Python网络请求urllib和urllib3详解

urllib是Python中请求url连接的官方标准库,在Python2中主要为urllib和urllib2,在Python3中整合成了urllib。

而urllib3则是增加了连接池等功能,两者互相都有补充的部分。

urllib

urllib作为Python的标准库,基本上涵盖了基础的网络请求功能。

urllib.request

urllib中,request这个模块主要负责构造和发起网络请求,并在其中加入Headers、Proxy等。

发起GET请求

主要使用urlopen()方法来发起请求:

from urllib import request

resp = request.urlopen('http://www.baidu.com')
print(resp.read().decode())
 

urlopen()方法中传入字符串格式的url地址,则此方法会访问目标网址,然后返回访问的结果。

访问的结果会是一个http.client.HTTPResponse对象,使用此对象的read()方法,则可以获取访问网页获得的数据。但是要注意的是,获得的数据会是bytes的二进制格式,所以需要decode()一下,转换成字符串格式。

发起POST请求

urlopen()默认的访问方式是GET,当在urlopen()方法中传入data参数时,则会发起POST请求。

注意:传递的data数据需要为bytes格式。

设置timeout参数还可以设置超时时间,如果请求时间超出,那么就会抛出异常。

from urllib import request

resp = request.urlopen('http://httpbin.org', data=b'word=hello', timeout=10)
print(resp.read().decode())

添加Headers

通过urllib发起的请求会有默认的一个Headers:"User-Agent":"Python-urllib/3.6",指明请求是由urllib发送的。

所以遇到一些验证User-Agent的网站时,我们需要自定义Headers,而这需要借助于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'}

# 需要使用url和headers生成一个Request对象,然后将其传入urlopen方法中
req = request.Request(url, headers=headers)
resp = request.urlopen(req)
print(resp.read().decode())

Request对象

如上所示,urlopen()方法中不止可以传入字符串格式的url,也可以传入一个Request对象来扩展功能,Request对象如下所示。

class urllib.request.Request(url, data=None, headers={},
origin_req_host=None,
unverifiable=False, method=None)

构造Request对象必须传入url参数,data数据和headers都是可选的。

最后,Request方法可以使用method参数来自由选择请求的方法,如PUT,DELETE等等,默认为GET。

添加Cookie

为了在请求时能带上Cookie信息,我们需要重新构造一个opener。

使用request.build_opener方法来进行构造opener,将我们想要传递的cookie配置到opener中,然后使用这个opener的open方法来发起请求。

from http import cookiejar
from urllib import request

url = 'http://httpbin.org/cookies'
# 创建一个cookiejar对象
cookie = cookiejar.CookieJar()
# 使用HTTPCookieProcessor创建cookie处理器
cookies = request.HTTPCookieProcessor(cookie)
# 并以它为参数创建Opener对象
opener = request.build_opener(cookies)
# 使用这个opener来发起请求
resp = opener.open(url)
print(resp.read().decode())
 

或者也可以把这个生成的opener使用install_opener方法来设置为全局的。

则之后使用urlopen方法发起请求时,都会带上这个cookie。

# 将这个opener设置为全局的opener
request.install_opener(opener)
resp = request.urlopen(url)

设置Proxy代理

使用爬虫来爬取数据的时候,常常需要使用代理来隐藏我们的真实IP。


from urllib import request

url = 'http://httpbin.org/ip'
proxy = {'http':'50.233.137.33:80','https':'50.233.137.33:80'}
# 创建代理处理器
proxies = request.ProxyHandler(proxy)
# 创建opener对象
opener = request.build_opener(proxies)

resp = opener.open(url)
print(resp.read().decode())

下载数据到本地

在我们进行网络请求时常常需要保存图片或音频等数据到本地,一种方法是使用python的文件操作,将read()获取的数据保存到文件中。

urllib提供了一个urlretrieve()方法,可以简单的直接将请求获取的数据保存成文件。

from urllib import request

url = 'http://python.org/'
request.urlretrieve(url, 'python.html')

urlretrieve()方法传入的第二个参数为文件保存的位置,以及文件名。

注:urlretrieve()方法是python2直接移植过来的方法,以后有可能在某个版本中弃用。

urllib.response

在使用urlopen()方法或者opener的open()方法发起请求后,获得的结果是一个response对象。

这个对象有一些方法和属性,可以让我们对请求返回的结果进行一些处理。

  • read()

    获取响应返回的数据,只能使用一次。

  • getcode()

    获取服务器返回的状态码。

  • getheaders()

    获取返回响应的响应报头。

  • geturl()

    获取访问的url。

urllib.parse

urllib.parse是urllib中用来解析各种数据格式的模块。

urllib.parse.quote

在url中,是只能使用ASCII中包含的字符的,也就是说,ASCII不包含的特殊字符,以及中文等字符都是不可以在url中使用的。而我们有时候又有将中文字符加入到url中的需求,例如百度的搜索地址:

https://www.baidu.com/s?wd=南北

?之后的wd参数,则是我们搜索的关键词。那么我们实现的方法就是将特殊字符进行url编码,转换成可以url可以传输的格式,urllib中可以使用quote()方法来实现这个功能。

>>> from urllib import parse
>>> keyword = '南北'
>>> parse.quote(keyword)
'%E5%8D%97%E5%8C%97'

如果需要将编码后的数据转换回来,可以使用unquote()方法。

>>> parse.unquote('%E5%8D%97%E5%8C%97')
'南北'

urllib.parse.urlencode

在访问url时,我们常常需要传递很多的url参数,而如果用字符串的方法去拼接url的话,会比较麻烦,所以urllib中提供了urlencode这个方法来拼接url参数。


>>> from urllib import parse
>>> params = {'wd': '南北', 'code': '', 'height': ''}
>>> parse.urlencode(params)
'wd=%E5%8D%97%E5%8C%97&code=1&height=188'

urllib.error

urllib中主要设置了两个异常,一个是URLError,一个是HTTPErrorHTTPErrorURLError的子类。

HTTPError还包含了三个属性:

  • code:请求的状态码

  • reason:错误的原因

  • headers:响应的报头

例子:

In [1]: from urllib.error import HTTPError

In [2]: try:
...: request.urlopen('https://www.jianshu.com')
...: except HTTPError as e:
...: print(e.code) 403

urllib3

Urllib3是一个功能强大,条理清晰,用于HTTP客户端的Python库。许多Python的原生系统已经开始使用urllib3。Urllib3提供了很多python标准库urllib里所没有的重要特性:

  1. 线程安全

  2. 连接池

  3. 客户端SSL/TLS验证

  4. 文件分部编码上传

  5. 协助处理重复请求和HTTP重定位

  6. 支持压缩编码

  7. 支持HTTP和SOCKS代理

安装

urllib3是一个第三方库,安装非常简单,pip安装即可:

pip install urllib3

使用

urllib3主要使用连接池进行网络请求的访问,所以访问之前我们需要创建一个连接池对象,如下所示:


>>> import urllib3
>>> http = urllib3.PoolManager()
>>> r = http.request('GET', 'http://httpbin.org/robots.txt')
>>> r.status
200
>>> r.data
'User-agent: *\nDisallow: /deny\n'

设置headers

headers={'X-Something': 'value'}
resp = http.request('GET', 'http://httpbin.org/headers', headers=headers)

设置url参数

对于GET等没有请求正文的请求方法,可以简单的通过设置fields参数来设置url参数。

fields = {'arg': 'value'}
resp = http.request('GET', 'http://httpbin.org/get', fields=fields)

如果使用的是POST等方法,则会将fields作为请求的请求正文发送。

所以,如果你的POST请求是需要url参数的话,那么需要自己对url进行拼接。

fields = {'arg': 'value'}
resp = http.request('POST', 'http://httpbin.org/get', fields=fields)

设置代理

>>> import urllib3
>>> proxy = urllib3.ProxyManager('http://50.233.137.33:80', headers={'connection': 'keep-alive'})
>>> resp = proxy.request('get', 'http://httpbin.org/ip')
>>> resp.status
200
>>> resp.data
b'{"origin":"50.233.136.254"}\n'
 

**注:urllib3中没有直接设置cookies的方法和参数,只能将cookies设置到headers中

Python网络请求urllib和urllib3详解的更多相关文章

  1. Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)

    最近做项目要求使用到网络,想来想去选择了AsyncHttpClient框架开进行APP开发.在这里把我工作期间遇到的问题以及对AsyncHttpClient的使用经验做出相应总结,希望能对您的学习有所 ...

  2. android网络请求库volley方法详解

    使用volley进行网络请求:需先将volley包导入androidstudio中 File下的Project Structrue,点加号导包 volley网络请求步骤: 1. 创建请求队列     ...

  3. python中requests库使用方法详解

    目录 python中requests库使用方法详解 官方文档 什么是Requests 安装Requests库 基本的GET请求 带参数的GET请求 解析json 添加headers 基本POST请求 ...

  4. (转)python标准库中socket模块详解

    python标准库中socket模块详解 socket模块简介 原文:http://www.lybbn.cn/data/datas.php?yw=71 网络上的两个程序通过一个双向的通信连接实现数据的 ...

  5. kafka实战教程(python操作kafka),kafka配置文件详解

    kafka实战教程(python操作kafka),kafka配置文件详解 应用往Kafka写数据的原因有很多:用户行为分析.日志存储.异步通信等.多样化的使用场景带来了多样化的需求:消息是否能丢失?是 ...

  6. 网络编程socket基本API详解(转)

    网络编程socket基本API详解   socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...

  7. [转]网络性能评估工具Iperf详解(可测丢包率)

    原文链接:安全运维之:网络性能评估工具Iperf详解:http://os.51cto.com/art/201410/454889.htm 参考博文:http://linoxide.com/monito ...

  8. [转帖]技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

    技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解    http://www.52im.net/thread-1309-1-1.html   本文来自腾讯资深研发工程师罗成的技术分享, ...

  9. 入木三分学网络第一篇--VRRP协议详解第一篇(转)

    因为keepalived使用了VRRP协议,所有有必要熟悉一下. 虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP)是解决局域网中配置静态网关时,静 ...

随机推荐

  1. WebView播放H5课件时,锁屏解锁后,页面重新绘制的问题

    难题描述:H5页面播放 ,锁屏,解锁后,重新加载了页面,三星不会出现(onpause onstop ,onresume),但在小米.魅族会调用 onpause onstop ondestroy,onr ...

  2. bzoj 4537 最小公倍数

    给定一张N个顶点M条边的无向图 每条边上带有权值 所有权值都可以分解成2^a*3^b的形式 q个询问,每次询问给定四个参数u.v.a和b,请你求出是否存在一条顶点u到v之间的路径,使得路径依次经过的边 ...

  3. 苹果树(线段树+Dfs序)

    1228 苹果树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总 ...

  4. Akka源码分析-Remote-网络链接生命周期

    remote模式下,网络链接的生命周期往往影响着对应Actor的生命周期,那么网络链接的生命周期是怎么样的呢? 每一个与远程系统的链路都是四个状态之一:空闲.活跃.被守护.被隔离.远程系统的某个地址没 ...

  5. 【转】关于Java基础你不得不会的34个问题

    1. 面向对象和面向过程的区别 面向过程 优点: 性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机.嵌入式开发.Linux/Unix等一般采用面向过程开发,性能是最重要的 ...

  6. Vue.js中学习使用Vuex详解

    在SPA单页面组件的开发中 Vue的vuex和React的Redux 都统称为同一状态管理,个人的理解是全局状态管理更合适:简单的理解就是你在state中定义了一个数据之后,你可以在所在项目中的任何一 ...

  7. 【BZOJ2149】拆迁队(斜率优化DP+CDQ分治)

    题目: 一个斜率优化+CDQ好题 BZOJ2149 分析: 先吐槽一下题意:保留房子反而要给赔偿金是什么鬼哦-- 第一问是一个经典问题.直接求原序列的最长上升子序列是错误的.比如\(\{1,2,2,3 ...

  8. Codeforces 766E

    题意:给一棵树(1e5),每个节点上有对应权值(0<=ai<=1e6)定义树上两个节点间的距离为路径中节点的异或,求所有节点对间的距离和(包括节点自身也作为节点对,距离为节点权值). 解题 ...

  9. V3的普通窗体控件的使用

    1.文本: 属性: 标签对齐方式: Left  Right  Center 值对齐方式: Left  Right  Center 事件: 值改变事件 值加载事件 单击标题事件 键盘按下事件 获得焦点事 ...

  10. 【转】Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...