在可供使用的网络库中,urllib
和urllib2
多是投入产出比最高的两个,是Python中操做url的官方标准库。它们让你可以经过网络访问文件,就像这些文件位于你的计算机中同样。只需一个简单的函数调用,就几乎可将统一资源定位符(URL)可指向的任何动做做为程序的输入。结合re模块使用将发挥强大威力!html
一个简单的例子:python
req = urllib2.Request( url=url, data=postdata, headers=headers ) result = urllib2.urlopen(req)
模块urllib
和urllib2
的功能差很少,简单来讲urllib2
是urllib
的加强——urllib2
更好一些,可是urllib中有urllib2中所没有的函数。对于简单的下载, urllib
绰绰有余。 若是须要实现HTTP身份验证
或Cookie
亦或编写扩展来处理本身的协议,urllib2
多是更好的选择。在Python2.x中主要为urllib
和urllib2
,这两个标准库是不可相互替代的。可是在Python3.x中将urllib2
合并到了urllib
,这一点值得注意。git
urllib
支持设置编码的函数urllib.urlencode
,在模拟登录的时候常常须要传递通过post
编码以后的参数,若是不想使用第三方库完成模拟登陆,就必须使用到标准库中的urllib
。urllib
提供一些比较原始基础的方法而urllib2
并无,好比urllib
中的urlencode
方法用来GET查询字符串的产生。github
urllib2
比较有优点的地方在于urllib2.openurl
中能够接受一个Request类的实例来设置Request参数
,来修改/设置Header头从而达到控制HTTP Request
的header部分的目的,也能够修改用户代理,设置cookie等,但urllib
仅能够接受URL。这就意味着,若是你访问一个网站想更改User Agent
(能够假装你的浏览器),你就须要使用urllib2
。urllib2
模块没有加入urllib.urlretrieve
函数以及urllib.quote
等一系列quote和unquote功能,这个时候就须要urllib
的辅助。web
所以Python2.x中,urllib
和urllib2
二者搭配使用。正则表达式
几乎能够像打开本地文件同样打开远程文件,差异是只能使用读取模式,以及使用模块urllib.request
中的函数urlopen
,而不是open(或file)。shell
from urllib.request import urlopen webpage = urlopen('http://www.python.org')
若是链接到了网络,变量webpage将包含一个相似于文件的对象,这个对象与网页http://www.python.org
相关联。json
注意:要在没有联网的状况下尝试使用模块urllib,可以使用以file:
打头的URL访问本地文件,如file:c:\text\somefile.txt
(别忘了对反斜杠进行转义)。浏览器
urlopen返回的相似于文件的对象支持方法:close、 read、readline和readlines,还支持迭代等。安全
假设要提取刚才所打开网页中连接About的相对URL, 可以使用正则表达式 。
>>> import re >>> text = webpage.read() # 注意:若是这个网页发生了变化,你可能须要修改使用的正则表达式。 >>> m = re.search(b'<a href="([^"]+)" .*?>about</a>', text, re.IGNORECASE) >>> m.group(1) 'about'
函数urlopen
返回一个相似于文件的对象,可从中读取数据。若是要让urllib
替你下载文件并将其副本存储在一个本地文件中,可以使用urlretrieve
。这个函数不返回一个相似于文件的对象,而返回一个格式为(filename, headers)
的元组,其中filename
是本地文件的名称(由urllib
自动建立),而headers
包含一些有关远程文件的信息(这里不会介绍headers, 若是你想更深刻地了解它,请在有关urllib的标准库文档中查找urlretrieve)。若是要给下载的副本指定文件名,可经过第二个参数来提供。
urlretrieve('http://www.python.org', 'C:\\python_webpage.html')
这将获取Python官网的主页,并将其存储到文件C:\python_webpage.html
中。若是你没有指定文件名,下载的副本将放在某个临时位置,可以使用函数open来打开。但使用完毕后,你可能想将其删除以避免占用磁盘空间。要清空这样的临时文件,可调用函数urlcleanup
且不提供任何参数,它将负责替你完成清空工做。
除了经过URL读取和下载文件外,urllib还提供了一些用于操做URL的函数,以下所示(这里假设你对URL和CGI略知一二)。
quote(string[, safe])
返回一个字符串,其中全部的特殊字符(在URL中有特殊意义的字符)都已替换为对URL友好的版本(如将~
替换为%7E
),若是要将包含特殊字符的字符串用做URL颇有用。参数safe是一个字符串(默认为'/'
),包含不该像这样对其进行编码的字符。
quote_plus(string[, safe])
相似于quote,但也将空格替换为加号。
unquote(string)
:与quote
相反。
unquote_plus(string)
:与quote_plus
相反。
urlencode(query[, doseq])
将映射(如字典)或由包含两个元素的元组(形如(key, value)
)组成的序列转换为“使用URL编码的”字符串。这样的字符串可用于CGI查询中(详细信息请参阅Python文档)。
urllib
urllib
做为Python的标准库,基本上涵盖了基础的网络请求功能。
urllib.request
urllib
中,request
这个模块主要负责构造和发起网络请求,并在其中加入Headers、Proxy等。
主要使用urlopen()
方法来发起请求:
from urllib import request resp = request.urlopen('http://www.baidu.com') print(resp.read().decode())
在urlopen()
方法中传入字符串格式的url地址,则此方法会访问目标网址,而后返回访问的结果。
返回的结果会是一个http.client.HTTPResponse
对象,使用此对象的read()
方法能够获取访问网页得到的数据。可是要注意的是,得到的数据会是bytes的二进制格式,因此须要decode()
一下,转换成字符串格式。
使用带参数的GET方法取回URL:
>>> import urllib >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params) >>> print f.read()
POST
请求urlopen()
默认的访问方式是GET
,当在urlopen()
方法中传入data参数时,则会发起POST
请求。注意:传递的data数据须要为bytes格式。timeout参数还能够设置超时时间,若是请求时间超出,那么就会抛出异常。
from urllib import request resp = request.urlopen('http://httpbin.org/post', data=b'word=hello', timeout=10) print(resp.read().decode())
使用带参数的POST方法:
>>> import urllib >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params) >>> print f.read()
经过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())
如上所示,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信息,咱们须要从新构造一个opener。
使用request.build_opener
方法来进行构造opener,将咱们想要传递的cookie配置到opener中,而后使用这个opener的open
方法来发起请求。
from http import cookiejar from urllib import request url = 'https://www.baidu.com' # 建立一个cookiejar对象 cookie = cookiejar.CookieJar() # 使用HTTPCookieProcessor建立cookie处理器 cookies = request.HTTPCookieProcessor(cookie) # 并以它为参数建立Opener对象 opener = request.build_opener(cookies) # 使用这个opener来发起请求 resp = opener.open(url) # 查看以前的cookie对象,则能够看到访问百度得到的cookie for i in cookie: print(i)
或者也能够把这个生成的opener使用install_opener
方法来设置为全局的,以后使用urlopen方法发起请求时,都会带上这个cookie:
# 将这个opener设置为全局的opener request.install_opener(opener) resp = request.urlopen(url)
使用爬虫来爬取数据的时候,经常须要使用代理来隐藏咱们的真实IP。
from urllib import request url = 'http://httpbin.org/ip' proxy = {'http':'218.18.232.26:80','https':'218.18.232.26:80'} # 建立代理处理器 proxies = request.ProxyHandler(proxy) # 建立opener对象 opener = request.build_opener(proxies) resp = opener.open(url) print(resp.read().decode())
urllib
官方文档的例子:
# 使用HTTP代理,自动跟踪重定向 >>> import urllib >>> proxies = {'http': 'http://proxy.example.com:8080/'} >>> opener = urllib.FancyURLopener(proxies) >>> f = opener.open("http://www.python.org") >>> f.read() # 不使用代理 >>> import urllib >>> opener = urllib.FancyURLopener({}) >>> f = opener.open("http://www.python.org/") >>> f.read()
在咱们进行网络请求时经常须要保存图片或音频等数据到本地,一种方法是使用python的文件操做,将read()获取的数据保存到文件中。
而urllib提供了一个urlretrieve()
方法,能够简单的直接将请求获取的数据保存成文件。
from urllib import request url = 'http://python.org/' # urlretrieve()方法传入的第二个参数为文件保存的位置,以及文件名。 request.urlretrieve(url, 'python.html')
注:urlretrieve()
方法是Python2.x直接移植过来的方法,之后有可能在某个版本中弃用。
urllib.response
在使用urlopen()
方法或者opener的open()
方法发起请求后,得到的结果是一个response
对象。这个对象有一些方法和属性,可让咱们对请求返回的结果进行一些处理。
read()
:获取响应返回的数据,只能使用一次。
getcode()
:获取服务器返回的状态码。
getheaders()
:获取返回响应的响应报头。
geturl()
:获取访问的url。
urllib.parse
urllib.parse
是urllib
中用来解析各类数据格式的模块。
在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': '1', 'height': '188'} >>> parse.urlencode(params) 'wd=%E5%8D%97%E5%8C%97&code=1&height=188'
urllib.error
在urllib中主要设置了两个异常,一个是URLError
,一个是HTTPError
,HTTPError
是URLError
的子类。
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
urllib2
import urllib2 # 设置浏览器请求头 ua_headers={ "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0" } #创建请求内容 request=urllib2.Request("http://baidu.com/",headers=ua_headers) #获取响应 response=urllib2.urlopen(request) #页面内容 html=response.read() print html print response.getcode() #返回响应码 print response.geturl() #返回实际url print response.info() #返回服务器响应的报头
urllib
)的一个例子:from urllib import request url = r'https://www.baidu.com/' headers = { 'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3', 'Referer': r'http://www.lagou.com/zhaopin/Python/?labelWords=label', 'Connection': 'keep-alive' } req = request.Request(url, headers=headers) html = request.urlopen(req).read() # 处理编码 html = html.decode('utf-8') print(html)
urllib2
官方文档的几个例子:>>> import urllib2 >>> f = urllib2.urlopen('http://www.python.org/') >>> print f.read()
import urllib2 auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler.add_password(realm='PDQ Application', uri='https://mahler:8092/site-updates.py', user='klem', passwd='kadidd!ehopper') opener = urllib2.build_opener(auth_handler) urllib2.install_opener(opener) urllib2.urlopen('http://www.example.com/login.html')
注:build_opener()
默认提供不少处理程序,包括代理处理程序,代理默认会被设置为环境变量所提供的。
proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'}) proxy_auth_handler = urllib2.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') opener = urllib2.build_opener(proxy_handler, proxy_auth_handler) opener.open('http://www.example.com/login.html')
import urllib2 req = urllib2.Request('http://www.example.com/') req.add_header('Referer', 'http://www.python.org/') r = urllib2.urlopen(req)
import urllib2 opener = urllib2.build_opener() opener.addheaders = [('User-agent', 'Mozilla/5.0')] opener.open('http://www.example.com/')
注:httplib
和httplib2
、httplib
是http客户端协议的实现,一般不直接使用,urllib
是以httplib
为基础,httplib2
是第三方库,比httplib
有更多特性。httplib
比较底层,通常使用的话用urllib
和urllib2
便可。
urllib
Python2.x 有这些库名可用: urllib
,urllib2
,urllib3
,httplib
,httplib2
,requests
Python3.x 有这些库名可用: urllib
,urllib3
,httplib2
,requests
若只使用Python3.x,记住有个urllib
的库就好了。Pyhton2.x和Python3.x都有urllib3
和requests
, 它们不是标准库。urllib3
提供线程安全链接池和文件post等支持,与urllib
及urllib2
的关系不大。requests
自称HTTP for Humans
,使用更简洁方便。
Python3.x中将urllib2
合并到了urllib
,以后此包分红了如下几个模块:
urllib.request
用于打开和读取URL
urllib.error
用于处理前面request引发的异常
urllib.parse
用于解析URL
urllib.robotparser
用于解析robots.txt文件
Python3.x中,随着urllib2
合入urllib
,一些经常使用的方法也发生了变化:2
在Python2.x中使用import urlparse
——在Python3.x中会使用import urllib.parse
在Python2.x中使用urllib2.urlopen
或urllib.urlopen
(已弃用)——在Python3.x中会使用urllib.request.urlopen
在Python2.x中使用urllib2.Request
——在Python3.x中会使用urllib.request.Request
在Python2.x中使用urllib.quote
——在Python3.x中会使用urllib.request.quote
在Python2.x中使用urllib.urlencode
——在Python3.x中会使用urllib.parse.urlencode
在Python2.x中使用cookielib.CookieJar
——在Python3.x中会使用http.CookieJar
异常处理:在Python2.x中使用urllib2.URLError,urllib2.HTTPError
——在Python3.x中会使用urllib.error.URLError,urllib.error.HTTPError
注:在Python3.3后urllib2
已经不能再用,全部urllib2
所有用urllib.request
来代替。
urllib
和urllib2
在Python2.x以及Python3.x的区别:import urllib import urllib2
一、共同点:均可以直接用urlopen(‘url’)
请求页面
二、不一样点:urllib
有urlencode(dict)
和unquote()
进行编码和解码
三、对于error:
try: response = urllib2.urlopen("http://pythonsite.com/111341.html") except urllib2.HTTPError as e: print(e.reason) print(e.code) print(e.headers) except urllib2.URLError as e: print(e.reason) else: print("reqeust successfully")
一、请求页面:urllib.request.urlopen(‘url’)
二、对于error:
from urllib import request,error try: response = request.urlopen("http://pythonsite.com/113211.html") except error.HTTPError as e: print(e.reason) print(e.code) print(e.headers) except error.URLError as e: print(e.reason) else: print("reqeust successfully")
>>> import urllib.request >>> with urllib.request.urlopen('http://www.python.org/') as f: ... print(f.read(300))
import urllib.request DATA=b'some data' req = urllib.request.Request(url='http://localhost:8080', data=DATA, method='PUT') with urllib.request.urlopen(req) as f: pass print(f.status) print(f.reason)
import urllib.request auth_handler = urllib.request.HTTPBasicAuthHandler() auth_handler.add_password(realm='PDQ Application', uri='https://mahler:8092/site-updates.py', user='klem', passwd='kadidd!ehopper') opener = urllib.request.build_opener(auth_handler) urllib.request.install_opener(opener) urllib.request.urlopen('http://www.example.com/login.html')
proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'}) proxy_auth_handler = urllib.request.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler) opener.open('http://www.example.com/login.html')
import urllib.request req = urllib.request.Request('http://www.example.com/') req.add_header('Referer', 'http://www.python.org/') r = urllib.request.urlopen(req)
import urllib.request opener = urllib.request.build_opener() opener.addheaders = [('User-agent', 'Mozilla/5.0')] opener.open('http://www.example.com/')
>>> import urllib.request >>> import urllib.parse >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> url = "http://www.musi-cal.com/cgi-bin/query?%s" % params >>> with urllib.request.urlopen(url) as f: ... print(f.read().decode('utf-8')) ...
>>> import urllib.request >>> import urllib.parse >>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> data = data.encode('ascii') >>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f: ... print(f.read().decode('utf-8')) ...
>>> import urllib.request >>> proxies = {'http': 'http://proxy.example.com:8080/'} >>> opener = urllib.request.FancyURLopener(proxies) >>> with opener.open("http://www.python.org") as f: ... f.read().decode('utf-8') ...
>>> import urllib.request >>> opener = urllib.request.FancyURLopener({}) >>> with opener.open("http://www.python.org/") as f: ... f.read().decode('utf-8') ...
注:Python2.X中的httplib
被重命名为http.client
。
使用2to3
工具转换源码时, 会自动处理这几个库的导入.
总的来讲, 使用Python3.x, 记住只有urllib
, 想要更简洁好用就用requests
, 但不够通用。
urllib3
3urllib3
功能强大且易于使用,用于HTTP客户端的Python库。许多Python的原生系统已经开始使用urllib3
。
urllib3
提供了不少python标准库urllib
里所没有的重要特性:
urllib3
是一个第三方库,pip安装:
$ pip install urllib3
或者,能够从GitHub获取最新的源代码:
$ git clone git://github.com/shazow/urllib3.git $ python setup.py install
urllib3
主要使用链接池进行网络请求的访问,因此访问以前须要先建立一个链接池对象:
# 导入urllib3模块: >>> import urllib3 # 须要一个PoolManager实例来生成请求,由该实例对象处理与线程池的链接以及线程安全的全部细节,不须要任何人为操做: >>> http = urllib3.PoolManager() # 经过request()方法建立一个请求,该方法返回一个HTTPResponse对象: >>> r = http.request('GET', 'http://httpbin.org/robots.txt') >>> r.status 200 >>> r.data 'User-agent: *\nDisallow: /deny\n'
经过request()
方法向请求(request)中添加一些其余信息:
>>> r = http.request( ... 'POST', ... 'http://httpbin.org/post', ... fields={'hello': 'world'})
或者:在request()
方法中,能够定义一个字典类型(dictionary),并做为headers参数传入:
headers={'X-Something': 'value'} resp = http.request('GET', 'http://httpbin.org/headers', headers=headers)
对于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中。
请求(request)中的数据项(request data)可包括:
在request()方法中,能够定义一个字典类型(dictionary)并做为headers参数传入:
>>> r = http.request( ... 'GET', ... 'http://httpbin.org/headers', ... headers={ ... 'X-Something': 'value' ... }) >>> json.loads(r.data.decode('utf-8'))['headers'] {'X-Something': 'value', ...}
对于GET、HEAD和DELETE请求,能够简单的经过定义一个字典类型做为fields参数传入便可:
>>> r = http.request( ... 'GET', ... 'http://httpbin.org/get', ... fields={'arg': 'value'}) >>> json.loads(r.data.decode('utf-8'))['args'] {'arg': 'value'}
对于POST和PUT请求(request),须要手动对传入数据进行编码,而后加在URL以后:
>>> from urllib.parse import urlencode >>> encoded_args = urlencode({'arg': 'value'}) >>> url = 'http://httpbin.org/post?' + encoded_args >>> r = http.request('POST', url) >>> json.loads(r.data.decode('utf-8'))['args'] {'arg': 'value'}
对于PUT和POST请求(request),urllib3
会自动将字典类型的field参数编码成表格类型.
>>> r = http.request( ... 'POST', ... 'http://httpbin.org/post', ... fields={'field': 'value'}) >>> json.loads(r.data.decode('utf-8'))['form'] {'field': 'value'}
在发起请求时,能够经过定义body参数并定义headers的Content-Type参数来发送一个已通过编译的JSON数据:
>>> import json >>> data = {'attribute': 'value'} >>> encoded_data = json.dumps(data).encode('utf-8') >>> r = http.request( ... 'POST', ... 'http://httpbin.org/post', ... body=encoded_data, ... headers={'Content-Type': 'application/json'}) >>> json.loads(r.data.decode('utf-8'))['json'] {'attribute': 'value'}
使用multipart/form-data编码方式上传文件,可使用和传入Form data数据同样的方法进行,并将文件定义为一个元组的形式(file_name,file_data)
:
>>> with open('example.txt') as fp: ... file_data = fp.read() >>> r = http.request( ... 'POST', ... 'http://httpbin.org/post', ... fields={ ... 'filefield': ('example.txt', file_data), ... }) >>> json.loads(r.data.decode('utf-8'))['files'] {'filefield': '...'}
文件名(filename)的定义不是严格要求的,可是推荐使用,以使得表现得更像浏览器。同时,还能够向元组中再增长一个数据来定义文件的MIME类型:
>>> r = http.request( ... 'POST', ... 'http://httpbin.org/post', ... fields={ ... 'filefield': ('example.txt', file_data, 'text/plain'), ... })
若是是发送原始二进制数据,只要将其定义为body参数便可。同时,建议对header
的Content-Type
参数进行设置:
>>> with open('example.jpg', 'rb') as fp: ... binary_data = fp.read() >>> r = http.request( ... 'POST', ... 'http://httpbin.org/post', ... body=binary_data, ... headers={'Content-Type': 'image/jpeg'}) >>> json.loads(r.data.decode('utf-8'))['data'] b'...'
The HTTPResponse object provides status, data, and header attributes:
>>> r = http.request('GET', 'http://httpbin.org/ip') >>> r.status 200 >>> r.data b'{\n "origin": "104.232.115.37"\n}\n' >>> r.headers HTTPHeaderDict({'Content-Length': '33', ...})
JSON content can be loaded by decoding and deserializing the data attribute of the request:
>>> import json >>> r = http.request('GET', 'http://httpbin.org/ip') >>> json.loads(r.data.decode('utf-8')) {'origin': '127.0.0.1'}
The data attribute of the response is always set to a byte string representing the response content:
>>> r = http.request('GET', 'http://httpbin.org/bytes/8') >>> r.data b'\xaa\xa5H?\x95\xe9\x9b\x11'
Note: For larger responses, it’s sometimes better to stream the response.
使用timeout,能够控制请求的运行时间。在一些简单的应用中,能够将timeout参数设置为一个浮点数:
>>> http.request( ... 'GET', 'http://httpbin.org/delay/3', timeout=4.0) <urllib3.response.HTTPResponse> >>> http.request( ... 'GET', 'http://httpbin.org/delay/3', timeout=2.5) MaxRetryError caused by ReadTimeoutError
要进行更精细的控制,可使用Timeout实例,将链接的timeout和读的timeout分开设置:
>>> http.request( ... 'GET', ... 'http://httpbin.org/delay/3', ... timeout=urllib3.Timeout(connect=1.0)) <urllib3.response.HTTPResponse> >>> http.request( ... 'GET', ... 'http://httpbin.org/delay/3', ... timeout=urllib3.Timeout(connect=1.0, read=2.0)) MaxRetryError caused by ReadTimeoutError
若是想让全部的request都遵循一个timeout,能够将timeout参数定义在PoolManager中:
>>> http = urllib3.PoolManager(timeout=3.0) # 或者这样 >>> http = urllib3.PoolManager( ... timeout=urllib3.Timeout(connect=1.0, read=2.0))
当在具体的request中再次定义timeout时,会覆盖PoolManager层面上的timeout。
urllib3能够自动重试幂等请求,原理和handles redirect同样。能够经过设置retries参数对重试进行控制。Urllib3默认进行3次请求重试,并进行3次方向改变。
给retries参数定义一个整型来改变请求重试的次数:
>>> http.requests('GET', 'http://httpbin.org/ip', retries=10)
关闭请求重试(retrying request)及重定向(redirect)只要将retries定义为False便可:
>>> http.request( ... 'GET', 'http://nxdomain.example.com', retries=False) NewConnectionError >>> r = http.request( ... 'GET', 'http://httpbin.org/redirect/1', retries=False) >>> r.status 302
关闭重定向(redirect)但保持重试(retrying request),将redirect参数定义为False便可:
>>> r = http.request( ... 'GET', 'http://httpbin.org/redirect/1', redirect=False) >>> r.status 302
要进行更精细的控制,可使用retry实例,经过该实例能够对请求的重试进行更精细的控制。
例如,进行3次请求重试,可是只进行2次重定向:
>>> http.request( ... 'GET', ... 'http://httpbin.org/redirect/3', ... retries=urllib3.Retry(3, redirect=2)) MaxRetryError
You can also disable exceptions for too many redirects and just return the 302 response:
>>> r = http.request( ... 'GET', ... 'http://httpbin.org/redirect/3', ... retries=urllib3.Retry( ... redirect=2, raise_on_redirect=False)) >>> r.status 302
若是想让全部请求都遵循一个retry策略,能够在PoolManager中定义retry参数:
>>> http = urllib3.PoolManager(retries=False) # 或者这样: >>> http = urllib3.PoolManager( ... retries=urllib3.Retry(5, redirect=2))
当在具体的request中再次定义retry时,会覆盖 PoolManager层面上的retry。
urllib3 wraps lower-level exceptions, for example:
>>> try: ... http.request('GET', 'nx.example.com', retries=False) >>> except urllib3.exceptions.NewConnectionError: ... print('Connection failed.')
See exceptions for the full list of all exceptions.
If you are using the standard library logging module urllib3 will emit several logs. In some cases this can be undesirable. You can use the standard logger interface to change the log level for urllib3’s logger:
>>> logging.getLogger("urllib3").setLevel(logging.WARNING)
requests
requests
使用的是urllib3
,它继承了urllib2
的全部特性。requests
有很大功能特性:
requests
是第三方类库,须要另外安装。
import requests r = requests.get(url='http://www.baidu.com') # 最基本的GET请求 print(r.status_code) # 获取返回状态 #带参数的GET请求,http://dict.baidu.com/s?wd=python r = requests.get(url='http://dict.baidu.com/s', params={'wd':'python'}) print(r.url) print(r.text) #打印解码后的返回数据
关于requests更详细的介绍,请参阅 https://mp.csdn.net/mdeditor/87564359
参考:
python中urllib, urllib2,urllib3, httplib,httplib2, request的区别 https://blog.csdn.net/permike/article/details/52437492
Python网络请求urllib和urllib3详解 https://www.jianshu.com/p/f05d33475c78
Python–urllib3库详解1 http://www.javashuo.com/article/p-tnwmtomr-cd.html
urllib2库.官方文档翻译 https://blog.csdn.net/u014343243/article/details/49308043
部份内容参考Python基础教程 ↩︎
进一步了解urllib2,参见中文版翻译文档:http://blog.csdn.net/u014343243/article/details/49308043 ↩︎
urllib3
官方文档: https://urllib3.readthedocs.io/en/latest/
urllib3
其余参考文档: https://pypi.org/project/urllib3/ ↩︎