詳解:Python2中的urllib、urllib2與Python3中的urllib以及第三方模組requests
先說說Python2中的url與urllib2(參考此處):
在python2中,urllib和urllib2都是接受URL請求的相關模組,但是提供了不同的功能。兩個最顯著的不同如下:
1、urllib2可以接受一個Request類的例項來設定URL請求的headers,例如:
req = urllib2.Request(
url=url,
data=postdata,
headers=headers
)
result = urllib2.urlopen(req)
我們知道,HTTP是無連線的狀態協議,但是客戶端和伺服器端需要保持一些相互資訊,比如cookie,有了cookie,伺服器才能知道剛才是這個使用者登入了網站,才會給予客戶端訪問一些頁面的許可權。所以我們需要儲存cookie,之後附帶cookie再來訪問網站,才能夠達到效果。這裡就需要Python的cookielib和urllib2等的配合,將cookielib繫結到urllib2在一起,就能夠在請求網頁的時候附帶cookie。
cj = cookielib.LWPCookieJar() cookie_support = urllib2.HTTPCookieProcessor(cj) # 建立一個opener,將儲存了cookie的http處理器,還有設定一個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查詢字串的產生,而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中酷虎的和伺服器模組結構散亂,Python3中把這些打包成為了2個包,就是http與urllib,詳解如下:
http會處理所有客戶端--伺服器http請求的具體細節,其中:
(1)client會處理客戶端的部分
(2)server會協助你編寫Python web伺服器程式
(3)cookies和cookiejar會處理cookie,cookie可以在請求中儲存資料
使用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的高層庫,它有以下三個主要功能:
(1)request處理客戶端的請求
(2)response處理服務端的響應
(3)parse會解析url
下面是使用Python3中urllib來獲取資源的一些示例:
1、最簡單
import urllib.request
response = urllib.request.urlopen('http://python.org/')
html = response.read()
2、使用 Request
import urllib.request
req = urllib.request.Request('http://python.org/')
response = urllib.request.urlopen(req)
the_page = response.read()
3、傳送資料
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.python.org/')
response = urllib.request.urlopen(req)
the_page = response.read()
print(the_page.decode("utf8"))
4、傳送資料和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 錯誤
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 認證 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、超時
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)
上面例子大概把常用的一些情況都羅列出來了,其中對異常的處理要嚴格按照:
try...exceptA...exceptB...except...else...finally...
的語法格式來寫,詳情請參考我的另一篇相關博文
》》》》》》》》》》》》》》》》》》》》》》》》
2、除了使用官方標準庫的urllib,我們可以使用更好用的第三方模組,如requests
Requests 完全滿足如今網路的需求,其功能有以下:
- 國際化域名和 URLs
- Keep-Alive & 連線池
- 持久的 Cookie 會話
- 類瀏覽器式的 SSL 加密認證
- 基本/摘要式的身份認證
- 優雅的鍵/值 Cookies
- 自動解壓
- Unicode 編碼的響應體
- 多段檔案上傳
- 連線超時
- 支援
.netrc
- 適用於 Python 2.6—3.4
- 執行緒安全
請參考中文官方文件,寫的非常詳細:傳送門
其中快速上手頁面寫的非常棒,我就不贅述了,請看:傳送門
正如介紹所說:Requests 是使用 Apache2 Licensed 許可證的 HTTP 庫。用 Python 編寫,真正的為人類著想。