美文网首页
Python 3 基本库的使用 - urllib

Python 3 基本库的使用 - urllib

作者: 冰度猎魂 | 来源:发表于2018-12-03 00:01 被阅读0次

    在Python 2中,由urllib和urllib2两个库来实现请求的发送。而在Python 3中,已经不存在urllib2这个库了,统一为urllib。
    urllib是Python内置的HTTP请求库,也就是说不需要额外安装即可使用。它包含如下4个模块。

    • request:它是最基本的HTTP请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。
    • error:异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止。
    • parse:一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等。
    • robotparser:主要是用来识别网站的robots.txt文件,然后判断哪些网站可以爬,哪些网站不可以爬,它其实用得比较少。

    发送请求

    使用urllib的request模块,我们可以方便地实现请求的发送并得到响应。

    urlopen()

    urllib.request模块提供了最基本的构造HTTP请求的方法,利用它可以模拟浏览器的一个请求发起过程,同时它还带有处理授权验证(authenticaton)、重定向(redirection)、浏览器Cookies以及其他内容。

    import urllib.request
    
    response = urllib.request.urlopen("https://www.python.org")
    print(response.read().decode('utf-8'))
    

    可以发现,返回的response是一个HTTPResponse类型的对象,主要包含read()、readinto()、getheader(name)、getheaders()、fileno()等方法,以及msg、version、status、reason、debuglevel、closed等属性。

    import urllib.request
    
    response = urllib.request.urlopen('https://www.python.org')
    print(response.status)
    print(response.getheaders())
    print(response.getheader('Server'))
    
    图片.png

    可见,前两个输出分别输出了响应的状态码和响应头的信息,最后一个输出通过调用getheader()方法并传递一个参数Server获取了响应头中的Server值,结果是nginx,意思是服务器使用Nginx搭建的。
    利用最基本的ulropen()方法,可以完成最基本的简单网页的GET请求抓取。
    urlopen()函数的API:

    urllib.request.urlopen(url, data=None, [timeout,]*, cafile=None, capath=None, cadefault=False, context=None)
    

    可以发现,除了第一个参数可以传递URL之外,我们还可以传递其他内容,比如data(附加数据)、timeout(超时时间)等。

    • data参数
      data参数是可选的。如果要添加该参数,并且如果它是字节流编码格式的内容,即bytes类型,则需要通过bytes()方法转化。另外,如果传递了这个参数,则它的请求方式就不再是GET方式,而是POST方式。
    import urllib.parse
    import urllib.request
    
    data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
    response = urllib.request.urlopen('http://httpbin.org/post', data=data)
    print(response.read())
    
    运行结果
    • timeout参数
      timeout参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持HTTP、HTTPS、FTP请求。
      因此,可以通过设置这个超时时间来控制一个网页如果长时间未响应,就跳过它的抓取。这可以利用try except语句来实现,相关代码如下:
    import socket
    import urllib.request
    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')
    

    Request

    利用urlopen()方法可以实现最基本请求的发起,但这几个简单的参数并不足以构建一个完整的请求。如果请求中需要加入Headers等信息,就可以利用更强大的Request类来构建。

    import urllib.request
    
    request = urllib.request.Request('https://python.org')
    response = urllib.request.urlopen(request)
    print(response.read().decode('utf-8'))
    

    可以发现,我们依然用urlopen()方法来发送这个请求,只不过这次该方法的参数不再是URL,而是一个Request类型的对象。通过构造这个数据结构,一方面我们可以将请求独立成一个对象,另一方面可更加丰富和灵活地配置参数。
    Request的构造方法如下:

    class 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来伪装浏览器,默认的User-Agent是Python-urllib,我们可以通过修改它来伪装浏览器。比如要伪装火狐浏览器,你可以把它设置为:
      Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11
    • 第四个参数origin_req_host指的是请求方的host名称或者IP地址。
    • 第五个参数unverifiable表示这个请求是否是无法验证的,默认是False,意思就是说用户没有足够权限来选择接收这个请求的结果。例如,我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,这时unverifiable的值就是True。
    • 第六个参数method是一个字符串,用来指示请求使用的方法,比如GET、POST和PUT等。
    from urllib import request, parse
    
    url = 'http://httpbin.org/post'
    headers = {
       'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
       'Host': 'httpbin.org'
    }
    dict = {
       'name': 'Germey'
    }
    data = bytes(parse.urlencode(dict), encoding='utf8')
    req = request.Request(url=url, data=data, headers=headers, method='POST')
    response = request.urlopen(req)
    print(response.read().decode('utf-8'))
    
    运行结果
    高级用法

    在上面的过程中,我们虽然可以构造请求,但是对于一些更高级的操作(比如Cookies处理、代理设置等),我们就需要更强大的Handler。简而言之,我们可以把它理解为各种处理器,有专门处理登录验证的,有处理Cookies的,有处理代理设置的。利用他们,我们机会可以做到HTTP请求中的所有的事情。
    首先,介绍一下urllib.request模块里的BaseHandler类,它是所有其他Handler的父类,它提供了最基本的方法,例如default_open()、protocol_request()等。

    • HTTPDefaultErrorHandler:用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常。
    • HTTPRedirectHandler:用于处理重定向。
    • HTTPCookieProcessor:用于处理Cookies。
    • ProxyHandler:用于设置代理,默认代理为空。
    • HTTPPasswordMgr:用于管理秘密,它维护了用户名和密码的表。
    • HTTPBasicAuthHandler:用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。

    相关文章

      网友评论

          本文标题:Python 3 基本库的使用 - urllib

          本文链接:https://www.haomeiwen.com/subject/rxnscqtx.html