• urllib库的使用(一)-----python3


    你 urlib库为python3的HTTP内置请求库
    urilib的四个模块:

    • urllib.request:它是最基本的HTTP请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。
    • urllib.error:异常处理模块,用于处理异常的模块
    • urllib.parse:用于解析url,一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等。
    • urllib.robotparse:用于解析robots.txt,主要用于看哪些网站不能进行爬取,不过少用
      urllib的用法
      urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
    urllib.request.urlopen(url, data=None, timeout=<object object at 0x000002407EBBC770>, *, cafile=None, capath=None, cadefault=False, context=None)
    • url:为请求网址
    • data:请求时需要发送的参数
    • timeout:超时设置,在该时间范围内返回请求内容就不会报错

    发送请求

    urlopen()它可以模拟浏览器的一个请求发起过程,同时它还带有处理授权验证(authenticaton)、重定向(redirection)、浏览器Cookies以及其他内容

    import urllib.request  # 导入urllib.request模块,提供了最基本的构造HTTP请求的方法
    response = urllib.request.urlopen('http://www.baidu.com')  # 以python官网为例,把这个页面爬取下来
    print(response.read().decode('utf-8'))    # read()方法得到返回的网页内容

    运行结果:输出的是网页的源代码。得到代码后,我们想要的链接、图片地址、文本信息就都可以提取出来。
    在这里插入图片描述在这里插入图片描述

    print(type(response)) # 输出响应类型
    print(',,,,,,,,,,,,')
    print(response.status) # 返回结果的状态码
    print(',,,,,,,,,,,,')
    print(response.getheaders())   # 响应的头信息
    print(',,,,,,,,,,,,')
    print(response.getheader('Server')) # 响应头中的Server值,nginx意思是服务器用nginx搭建的
    • HTTPResponse类型对象,主要包含:read()、readinto()、getheader(name)、getheaders()、fileno()等方法,以及msg、version、status、debuglevel、closed等属性,得到这个对象之后,我们把它赋值为response变量,然后就可以调用这些方法和属性,得到返回结果的一系列信息了。
    • 调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码,如:200代表请求成功,404代表网页未找到等。
    • 前两个输出分别输出了响应的状态码和响应的头信息,最后一个输出通过调用getheader()方法并传递一个参数Server获取了响应头中的Server值,结果是nginx,意思是服务器是用Nginx搭建的。利用最基本的urlopen()方法,可以完成最基本的简单网页的GET请求抓取。
      在这里插入图片描述
    • data参数

    请求时加载数据
    data参数是可选的,参数需是bytes类型,如果不是,则需要通过bytes()方法转化,另外传递了 这个参数,则它的请求方式就不再是GET方式,而是POST方式

    import urllib.parse
    import urllib.request
    data = bytes(urllib.parse.urlencode({'word':'hello'}), encoding = 'utf8')  # 传递一个参数word,值为hello,需要被转码为bytes类型
    response = urllib.request.urlopen('http://httpbin.org/post',data=data)
    print(response.read())
    • timeout参数

    timeout参数,如果不指定,就会使用全局默认时间,超时设置,在该时间范围内返回请求内容就不会报错,单位为秒,超过设置的时间,还没有得到响应,就会抛出异常,该异常属于urllib.error模块,错误原因是超时。
    判断超时请求,一个网页如果长时间未响应,就跳过它的抓取。

    import socket
    import urllib.error
    try:
        response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
    except urllib.error.URLError as e:
        if isinstance(e.reason, socket.timeout):
            print('TIME OUT')

    运行结果:TIME OUT

    按照常理来说,0.1秒内基本不可能得到服务器响应,通过设置timeout这个参数来实现超时处理,因此输出了TIMEOUT的提示

    context参数,它必须是ssl.SSLContext类型,用来指定SSL设置
    caflie和capath这两个参数分别指定CA证书和它的路径,这个在请求HTTPS链接时会有用
    cadefault已经弃用,默认为False

    如果希望返回与当前环境有关的信息,我们可以使用info()返回,比如可以执行

    >>>response.info()
    <http.client.HTTPMessage object at 0x0000000003623D68>
    • 可以看到,输出了对应的info,调用格式则为:“爬取的网页.info()”,我们之前爬取到的网页赋给了变量response,所以此时通过response调用。
    • 如果想要获取当前所爬取的URL地址,我们可以使用geturl()来实现
    >>>response.geturl()
    'http://www.baidu.com'

    quote() unquote()
    一般来说,URL标准中只会允许一部分ASCII字符比如数字、字母、部分符号等,而其他的一些字符,比如汉字等,是不符合URL标准的。此时,我们需要编码。
    如果要进行编码,我们可以使用urllib.request.quote()进行,对编码的网址进行解码

    urllib.request.unquote

    #对百度网址进行编码
    >>>urllib.request.quote('http://www.baidu.com') 
    'http%3A//www.baidu.com'
    #对编码的网址进行解码
    >>>urllib.request.unquote('http%3A//www.baidu.com')
    'http://www.baidu.com'
    from urllib.parse import quote
    keyword = '洪远的博客'
    url = 'www.baidu.com/s?wd=' + quote(keyword)
    print(url)

    运行结果:

    www.baidu.com/s?wd=%E6%B4%AA%E8%BF%9C%E7%9A%84%E5%8D%9A%E5%AE%A2
    from urllib.parse import unquote
    url = 'www.baidu.com/s?wd=%E6%B4%AA%E8%BF%9C%E7%9A%84%E5%8D%9A%E5%AE%A2'
    print(unquote(url))

    运行结果:

    www.baidu.com/s?wd=洪远的博客

    Request方法

    urlopen()方法可以实现最基本的发送,但如果想要构建一个完整的请求,在请求中需要加入Headers等信息,就可以利用更强大的Request类来构建
    使用Request来请求网页,将请求独立成一个对象

    import urllib.request
    request = urllib.request.Request('https://python.org')
    response = urllib.request.urlopen(request)#还用urlopen()方法来发送请求,只不过这次该方法的参数不再是URL,而是一个Request类型的对象
    print(response.read().decode('utf-8'))

    Request基本格式:

    urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
    • url:用于请求URL,必传参数
    • data:如果要传,必须传bytes类型,如果它是字典,可以先用urllib.parse模块里的urlencode()编码
    • headers:请求头,我们可以在构造请求时通过headers参数值构造,也可以通过调用请求实例的add_header()方法添加,常用于通过修改User-Agent来伪装浏览器
    • origin_req_host:指的是请求方的host名称或者IP地址
    • unverifiable:这个请求是否是无法验证,默认False,即用户没用足够权限来选取接受这个请求的结果
    • method:是一个字符串,用来只是请求的方法,比如:GET、POST、PUT等
      浏览器的模拟—Headers属性
      任意打开一个网页,比如打开http://httpbin.org/post。然后按F12(或者Fn+F12),会出现一个窗口。切换到Network(网络)标签页:
      然后让网页发生一个动作。
      我们可以观察到右边的窗口出现了一些数据。将界面右上方的标签切换到“Headers”(标头)中,即可以看到了对应的头信息,此时往下拖动,在请求标头中的最后一行,就可以找到User-Agent字样的一串信息。这一串信息即是我们下面模拟浏览器所需要用到的信息。我们将其复制出来。
      在这里插入图片描述
     User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763
    #通过Request请求参数来请求网页
    from urllib import request,parse
    url = 'http://httpbin.org/post'   # 请求URL
    headers = {   # headers指定User-Agent,Host
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
        'Host':'httpbin.org'
    }
    dict = {
        'name':'Germey'
    }
    data = bytes(parse.urlencode(dict), encoding='utf8')  # 参数转化为字节流
    req = request.Request(url=url, data=data, headers=headers, method='POST')  # 指定请求方式为POST
    response = request.urlopen(req)
    print(response.read().decode('utf-8'))
    
    #通过Request.add_header方法来请求网页
    from urllib import request,parse
    url = 'http://httpbin.org/post'   # 请求URL
    dict= {
        'name':'Germey'
    }
    data = bytes(parse.urlencode(dict), encoding='utf8')  # 参数转化为字节流
    req = request.Request(url = url, data = data, method='POST')
    req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36')
    response = request.urlopen(req)
    print(response.read().decode('utf-8'))
    

    运行结果:
    在这里插入图片描述
    首先,导入urllib中的request,parse,设置要爬取的网址,然后调用request.Request()函数创建一个req对象,该函数第一个参数传入url,第二个参数可以传入数据,默认是传入0数据,第三个参数是传入头部,该参数也是有默认值的,默认是不传任何头部。
    我们需要创建一个dict,将头部信息以键值对的形式存入到dict对象中,然后将该dict对象传入request.Request()函数第二个参数。
    此时,已经成功设置好报头,然后我们使用urlopen()打开该Request对象即可打开对应的网址。

  • 相关阅读:
    pgfplots画二维图真的很方便,多例比较
    LaTeX技巧206:使用gather输入多行公式的技巧
    LaTeX技巧205:使用split输入多行公式技巧
    LaTeX技巧207:使用align环境输入多行公式的技巧
    LaTeX技巧24:LaTeX常用命令集锦
    CTEX
    Latex常用指令学习
    LATEX数学公式基本语法
    LaTeX使用技巧
    C 命令行参数
  • 原文地址:https://www.cnblogs.com/llb123/p/13398733.html
Copyright © 2020-2023  润新知