1. 程式人生 > >詳解:Python2中的urllib、urllib2與Python3中的urllib以及第三方模組requests

詳解:Python2中的urllib、urllib2與Python3中的urllib以及第三方模組requests

先說說Python2中的url與urllib2(參考此處):

在python2中,urlliburllib2都是接受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。
在構造req請求之前可以獲取一個儲存cookies的物件,並把該物件和http處理器、http的handler資源以及urllib2的物件繫結在一起:
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 編寫,真正的為人類著想。