在可供使用的網絡庫中,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/ ↩︎