• python的网络请求库urllib、urllib2、urllib3、request的联系


    1. 简介

    urllib、urllib2、urllib3、request均能通过网络访问互联网上的资源文件,它们通过使用统一资源定位符(URL)并结合re模块完成很多意想不到的操作。

    • urllib:Python2和Python3内置的网络请求库,Python3的urllib实际是Python2版本中urllib和urllib2的合并
    • urllib2:它只存在于Python2版本的内置库中,功能与urllib基本类似,主要是urllib的增强。urllib、urllib2都是python的内置标准库;
    • urllib3:Python2和Python3均可以使用,但这不是标准库,需要使用pip安装使用,urllib3提供了线程安全池和文件post等,该模块是服务于升级的http 1.1标准,且拥有高效http连接池管理及http代理服务的功能库,但其并非python内
    • requests:requests是基于urllib3封装的,继承了urllib2的所有特性,遵循Apache2 Licensed开源协议的HTTP库,支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。如他的口号HTTP for Humans所说,这才是给人用的HTTP库,实际使用过程中更方便,能够大大的提高使用效率,缩短写代码的时间。

    注意: 在Python2中urllib和urllib2一般搭配使用的(不然Python2整两个内置库干嘛),urllib具有urllib2没有的功能,而urllib2具有urllib没有的功能。如urllib2可以接受请求对象来设置URL请求的头,urllib只接受URL;urllib提供用于生成GET查询字符串的urlencode方法,urllib2没有这样的函数。这就是为什么urllib经常与urllib2一起使用的原因之一。

    2. urllib

    urllib这个Python标准库基本上包含了基础的网络请求功能,以下urllib的演示均为Python3中的用法,Python2中单独用urllib会比较难受,上面也提到了它最好配合urllib2一起使用。

    • urllib发起GET请求

    urlopen()方法发起请求,read()方法获取网页数据

    from urllib import request
    
    res = request.urlopen("http://httpbin.org/get")
    print(res.read().decode())  # red()方法读取的数据是bytes的二进制格式,需要解码
    
    • 1
    • 2
    • 3
    • 4
    • urllib发起POST请求

    urlopen()默认是GET方式请求,当传入data参数时会发起POST请求,此时传递的参数必须时bytes格式

    from urllib import request
    
    res = request.urlopen("http://httpbin.org/post", data=b'hello=world')
    print(res.read().decode())
    
    • 1
    • 2
    • 3
    • 4
    • urllib为请求添加Headers

    通过urllib发起的请求默认的头信息是"User-Agent": “Python-urllib/3.6”,一般网站会验证请求头的合法性,如果需要修改可以通过urllib.request中的Request对象

    from urllib import request
    
    url = "http://httpbin.org/get"
    headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}
    
    req = request.Request(url=url, headers=headers) # 传递的Request对象
    res = request.urlopen(req)
    print(res.read().decode())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    此时httpbin网站返回的内容如下:

    {
      "args": {},
      "headers": {
        "Accept-Encoding": "identity",
        "Host": "httpbin.org",
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
      },
      "origin": "210.33.11.241, 210.33.11.241",
      "url": "https://httpbin.org/get"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • urllib制定proxy代理

    在使用爬虫时经常会配置代理隐藏我们的IP地址

    from urllib import request
    
    url = 'http://httpbin.org/ip'
    proxy = {'http': '117.95.200.71:9999', 'https': '183.154.54.188:9999'} # 可以使用西刺代理配置
    
    # 创建代理处理器
    proxies = request.ProxyHandler(proxy)
    # 创建opener对象
    opener = request.build_opener(proxies)
    
    resp = opener.open(url)
    print(resp.read().decode())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • urllib下载数据至本地
    from urllib import request
    
    url = 'http://httpbin.org/image/jpeg'
    request.urlretrieve(url, '1.jpg')
    
    • 1
    • 2
    • 3
    • 4

    3. urllib2

    urllib2的用法其实基本和urllib相似,且它只存在于Python2版本,它的使用时需要配合urllib一起使用,要说它和urllib的区别还要看下面这个表,下表主要说明了在Python2中的urllib、urllib2中的方法整合到Python3后方法名的区别。
    urllib

    • urllib2发起GET请求

    这里展示了一个官方使用urllib2的GET请求

    import urllib2
    
    res = urllib2.urlopen("http://httpbin.org/get")
    print res.read().decode()
    
    • 1
    • 2
    • 3
    • 4

    4. urllib3

    urllib3说一个HTTP客户端Python库,Python2和Python3在未安装的情况下均可以使用pip install urllib3即可安装,它提供了很多urllib库中没有的重要特性: 线程安全 连接池 客户端SSL/TLS验证 文件分部编码上传 协助处理重复请求和HTTP重定位 支持gzip和deflate压缩编码 支持HTTP和SOCKS代理 100%测试覆盖率

    • urllib3发起GET请求

    urllib3主要的特点就是在请求之前需要创建一个连接池对象

    import urllib3
    
    http = urllib3.PoolManager()  # 线程池生成请求
    res = http.request('GET', 'http://httpbin.org/get')
    print(res.data.decode())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • urllib3发起POST请求

    post请求只需要将request()方法的第一个参数改为POST,并设置fields参数即可

    import urllib3
    
    http = urllib3.PoolManager()  # 线程池生成请求
    res = http.request('POST', 'http://httpbin.org/post', fields={'hello': 'world'})
    print(res.data.decode())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • urllib3设置headers

    设置headers的方法和设置参数一样方便,只需要加入headers参数即可

    headers = {'X-Something': 'value'}
    res = http.request('POST', 'http://httpbin.org/post', headers=headers, fields={'hello': 'world'})
    
    • 1
    • 2

    5. requests

    最后介绍一个杀手级神器——requests,你会发现它一样也很好用,requests使用了urllib3的库,并且继承了所有urllib2的特性,最关键的是它不需要urllib3一样在编码时收到开启线程池,简单粗暴,不过它同样也要使用pip install requests安装。另外,requests会自动实现持久连接keep-alive

    格外简单的演示:

    import requests
    
    res = requests.get('http://httpbin.org/get')
    print(res.text)
    
    • 1
    • 2
    • 3
    • 4

    在实际使用中推荐使用后两种,因为毕竟方便,而若时没有安装这些库的情况下,Python3的urllib也是一个不错的选择。

    和urllib比较示例:

    ###urllib
    
    from  urllib import request,parse
    import json
    if __name__ == '__main__':
        while True:
            baseurl = 'http://fanyi.baidu.com/sug'
            keyword = input('请输入你要查询的单词:')
            data = {
                'kw': keyword
            }
            data = parse.urlencode(data).encode()  # 需要给数据编码,现在data是bytes格式,
            #调试用的的话可以输入以下代码(已注释)
            #data = parse.urlencode(data)
            #print(data)
    
            rsp = request.urlopen(baseurl, data=data)
            json_data = rsp.read().decode()#解码后的数据是json格式,所以要import json
            #print(json_data)
            json_data = json.loads(json_data)
            for i in json_data['data']:
                print(i['k'], '---->', i['v'])
    
    ---------------------------------------------------------------------------------------
    
    #####requests
    
    import requests
    if __name__ == '__main__':
        while True:
            baseurl = 'http://fanyi.baidu.com/sug'
            keyword = input('请输入你要查询的单词:')
            data = {
                'kw': keyword
            }
            #这里不用给data进行编码
            #但是下面要指明post方法
            #rsp=requests.request('post',url=baseurl,data=data)
            #上下两代码等价
            rsp = requests.post(url=baseurl, data=data)
            #而这里也不用导入 json模块,直接使用对象的json()方法即可
            json_data = rsp.json()
            for i in json_data['data']:
                print(i['k'], '---->', i['v'])
    总的来说,requests将urlib进行了更高级的封装,不用人为的编码解码,将其自动化,
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    6. 相关文章

  • 相关阅读:
    网络之物理层
    递增/递减运算符和指针
    【Python】环境的搭建
    CF1559E Mocha and Stars(dp+莫比乌斯反演)
    数仓:金融级数仓架构转型的最佳实践(下篇)
    python基于PHP+MySQL的小区物业管理系统
    【LeetCode】【剑指offer】【二叉树中和为某一值的路径】
    Python---循环---while循环
    Body Glove 与 Yeti Out 推出复古街头时尚系列
    NumPy矩阵对象介绍及方法
  • 原文地址:https://blog.csdn.net/craftsman2020/article/details/127923391