先說說Python2中的url與urllib2(參考此處):
在python2中,urllib和urllib2都是接受URL請求的相關(guān)模塊,但是提供了不同的功能。兩個(gè)最顯著的不同如下:
1、urllib2可以接受一個(gè)Request類的實(shí)例來設(shè)置URL請求的headers,例如:
- url=url,
- data=postdata,
- headers=headers
- )
- result = urllib2.urlopen(req)
我們知道,HTTP是無連接的狀態(tài)協(xié)議,但是客戶端和服務(wù)器端需要保持一些相互信息,比如cookie,有了cookie,服務(wù)器才能知道剛才是這個(gè)用戶登錄了網(wǎng)站,才會(huì)給予客戶端訪問一些頁面的權(quán)限。所以我們需要保存cookie,之后附帶cookie再來訪問網(wǎng)站,才能夠達(dá)到效果。這里就需要Python的cookielib和urllib2等的配合,將cookielib綁定到urllib2在一起,就能夠在請求網(wǎng)頁的時(shí)候附帶cookie。在構(gòu)造req請求之前可以獲取一個(gè)保存cookies的對象,并把該對象和http處理器、http的handler資源以及urllib2的對象綁定在一起:
- cj = cookielib.LWPCookieJar()
- cookie_support = urllib2.HTTPCookieProcessor(cj)
- # 創(chuàng)建一個(gè)opener,將保存了cookie的http處理器,還有設(shè)置一個(gè)handler用于處理http的URL的打開
- opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
- # 將包含了cookie、http處理器、http的handler的資源和urllib2對象板頂在一起
- urllib2.install_opener(opener)
2、urllib僅可以接受URL。這意味著,你不可以偽裝你的User Agent字符串等。
但是urllib提供urlencode方法用來GET查詢字符串的產(chǎn)生,而urllib2沒有。這是就是為何urllib常和urllib2一起使用的原因,如下:
- postdata = urllib.urlencode(postdata)
(把字典形式的postdata編碼一下)
Tip: if you
are planning to do HTTP stuff only, check out httplib2,
it is much better than httplib or urllib or urllib2.
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
下面說說Python3x中的urllib包、http包以及其他比較好使的第三方包
1、Python3
urllib、http
Python3不像2x中酷虎的和服務(wù)器模塊結(jié)構(gòu)散亂,Python3中把這些打包成為了2個(gè)包,就是http與urllib,詳解如下:
http會(huì)處理所有客戶端--服務(wù)器http請求的具體細(xì)節(jié),其中:
(1)client會(huì)處理客戶端的部分
(2)server會(huì)協(xié)助你編寫Python
web服務(wù)器程序
(3)cookies和cookiejar會(huì)處理cookie,cookie可以在請求中存儲(chǔ)數(shù)據(jù)
使用cookiejar示例可以在前幾篇博客中基于Python3的爬蟲中找到示例,如下:
- import http.cookiejar
- import urllib.request
- import urllib.parse</span></span>
- def getOpener(head):
- # deal with the Cookies
- cj = http.cookiejar.CookieJar()
- pro = urllib.request.HTTPCookieProcessor(cj)
- opener = urllib.request.build_opener(pro)
- header = []
- for key, value in head.items():
- elem = (key, value)
- header.append(elem)
- opener.addheaders = header
- return opener
urllib是基于http的高層庫,它有以下三個(gè)主要功能:
(1)request處理客戶端的請求
(2)response處理服務(wù)端的響應(yīng)
(3)parse會(huì)解析url
下面是使用Python3中urllib來獲取資源的一些示例:
- 1、最簡單
- import urllib.request
- response = urllib.request.urlopen('http:///')
- html = response.read()
- 2、使用 Request
- import urllib.request
- req = urllib.request.Request('http:///')
- response = urllib.request.urlopen(req)
- the_page = response.read()
- 3、發(fā)送數(shù)據(jù)
- import urllib.parse
- import urllib.request
- url = '"
- values = {
- 'act' : 'login',
- 'login[email]' : '',
- 'login[password]' : ''
- }
- data = urllib.parse.urlencode(values)
- req = urllib.request.Request(url, data)
- req.add_header('Referer', 'http://www./')
- response = urllib.request.urlopen(req)
- the_page = response.read()
- print(the_page.decode("utf8"))
- 4、發(fā)送數(shù)據(jù)和header
- import urllib.parse
- import urllib.request
- url = ''
- user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- values = {
- 'act' : 'login',
- 'login[email]' : '',
- 'login[password]' : ''
- }
- headers = { 'User-Agent' : user_agent }
- data = urllib.parse.urlencode(values)
- req = urllib.request.Request(url, data, headers)
- response = urllib.request.urlopen(req)
- the_page = response.read()
- print(the_page.decode("utf8"))
- 5、http 錯(cuò)誤
- import urllib.request
- req = urllib.request.Request(' ')
- try:
- urllib.request.urlopen(req)
- except urllib.error.HTTPError as e:
- print(e.code)
- print(e.read().decode("utf8"))
- 6、異常處理1
- from urllib.request import Request, urlopen
- from urllib.error import URLError, HTTPError
- req = Request("http://www..net /")
- try:
- response = urlopen(req)
- except HTTPError as e:
- print('The server couldn't fulfill the request.')
- print('Error code: ', e.code)
- except URLError as e:
- print('We failed to reach a server.')
- print('Reason: ', e.reason)
- else:
- print("good!")
- print(response.read().decode("utf8"))
- 7、異常處理2
- from urllib.request import Request, urlopen
- from urllib.error import URLError
- req = Request("http://www.Python.org/")
- try:
- response = urlopen(req)
- except URLError as e:
- if hasattr(e, 'reason'):
- print('We failed to reach a server.')
- print('Reason: ', e.reason)
- elif hasattr(e, 'code'):
- print('The server couldn't fulfill the request.')
- print('Error code: ', e.code)
- else:
- print("good!")
- print(response.read().decode("utf8"))
- 8、HTTP 認(rèn)證
- import urllib.request
- # create a password manager
- password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
- # Add the username and password.
- # If we knew the realm, we could use it instead of None.
- top_level_url = ""
- password_mgr.add_password(None, top_level_url, 'rekfan', 'xxxxxx')
- handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
- # create "opener" (OpenerDirector instance)
- opener = urllib.request.build_opener(handler)
- # use the opener to fetch a URL
- a_url = ""
- x = opener.open(a_url)
- print(x.read())
- # Install the opener.
- # Now all calls to urllib.request.urlopen use our opener.
- urllib.request.install_opener(opener)
- a = urllib.request.urlopen(a_url).read().decode('utf8')
- print(a)
- 9、使用代理
- import urllib.request
- proxy_support = urllib.request.ProxyHandler({'sock5': 'localhost:1080'})
- opener = urllib.request.build_opener(proxy_support)
- urllib.request.install_opener(opener)
- a = urllib.request.urlopen("").read().decode("utf8")
- print(a)
- 10、超時(shí)
- import socket
- import urllib.request
- # timeout in seconds
- timeout = 2
- socket.setdefaulttimeout(timeout)
- # this call to urllib.request.urlopen now uses the default timeout
- # we have set in the socket module
- req = urllib.request.Request('')
- a = urllib.request.urlopen(req).read()
- print(a)
上面例子大概把常用的一些情況都羅列出來了,其中對異常的處理要嚴(yán)格按照:
try...exceptA...exceptB...except...else...finally...
的語法格式來寫,詳情請參考我的另一篇相關(guān)博文
》》》》》》》》》》》》》》》》》》》》》》》》
2、除了使用官方標(biāo)準(zhǔn)庫的urllib,我們可以使用更好用的第三方模塊,如requests
Requests
完全滿足如今網(wǎng)絡(luò)的需求,其功能有以下:
- 國際化域名和 URLs
- Keep-Alive & 連接池
- 持久的 Cookie 會(huì)話
- 類瀏覽器式的 SSL 加密認(rèn)證
- 基本/摘要式的身份認(rèn)證
- 優(yōu)雅的鍵/值 Cookies
- 自動(dòng)解壓
- Unicode 編碼的響應(yīng)體
- 多段文件上傳
- 連接超時(shí)
- 支持
.netrc - 適用于 Python 2.6—3.4
- 線程安全
請參考中文官方文檔,寫的非常詳細(xì):傳送門
其中快速上手頁面寫的非常棒,我就不贅述了,請看:傳送門
正如介紹所說:Requests
是使用 Apache2
Licensed 許可證的 HTTP 庫。用 Python 編寫,真正的為人類著想。
|