學習Python的urllib模組

大雄45發表於2023-11-10
導讀   urllib 模組作為Python 3 處理 URL 的元件集合,如果你有 Python 2 的知識,那麼你就會注意到 Python 2 中有 urllib 和 urllib2 兩個版本的模組,這些現在都是 Python 3 的 urllib 包的一部分,具體如何來體現它們之間的關係

Python 3 的 urllib 模組是一堆可以處理 URL 的元件集合。如果你有 Python 2 的知識,那麼你就會注意到 Python 2 中有 urllib 和 urllib2 兩個版本的模組。這些現在都是 Python 3 的 urllib 包的一部分。當前版本的 urllib 包括下面幾部分:

  • urllib.request
  • urllib.error
  • urllib.parse
  • urllib.rebotparser

接下來我們會分開討論除了 urllib.error 以外的幾部分。官方文件實際推薦你嘗試第三方庫, requests,一個高 級的 HTTP 客戶端介面。然而我依然認為知道如何不依賴第三方庫開啟 URL 並與之進行互動是很有用的,而且這也可以幫助你理解為什麼 requests 包是如此的流行。

urllib.request

urllib.request 模組期初是用來開啟和獲取 URL 的。讓我們看看你可以用函式 urlopen 可以做的事:

>>> import urllib.request
>>> url = urllib.request.urlopen(')
>>> url.geturl()
'
>>> url.info()
<http.client.HTTPMessage object at 0x7fddc2de04e0>
>>> header = url.info()
>>> header.as_string()
('Date: Fri, 24 Jun 2016 18:21:19 GMT/n'
 'Expires: -1/n'
 'Cache-Control: private, max-age=0/n'
 'Content-Type: text/html; charset=ISO-8859-1/n'
 'P3P: CP="This is not a P3P policy! See '
 '
 'Server: gws/n'
 'X-XSS-Protection: 1; mode=block/n'
 'X-Frame-Options: SAMEORIGIN/n'
 'Set-Cookie: '
 'NID=80=tYjmy0JY6flsSVj7DPSSZNOuqdvqKfKHDcHsPIGu3xFv41LvH_Jg6LrUsDgkPrtM2hmZ3j9V76pS4K_cBg7pdwueMQfr0DFzw33SwpGex5qzLkXUvUVPfe9g699Qz4cx9ipcbU3HKwrRYA; '
 'expires=Sat, 24-Dec-2016 18:21:19 GMT; path=/; domain=.google.com; HttpOnly/n'
 'Alternate-Protocol: 443:quic/n'
 'Alt-Svc: quic=":443"; ma=2592000; v="34,33,32,31,30,29,28,27,26,25"/n'
 'Accept-Ranges: none/n'
 'Vary: Accept-Encoding/n'
 'Connection: close/n'
 '/n')
>>> url.getcode()
200

在這裡我們包含了需要的模組,然後告訴它開啟 Google 的 URL。現在我們就有了一個可以互動的 HTTPResponse 物件。我們要做的第一件事是呼叫方法 geturl ,它會返回根據 URL 獲取的資源。這可以讓我們發現 URL 是否進行了重定向。
接下來呼叫 info ,它會返回網頁的後設資料,比如請求頭資訊。因此,我們可以將結果賦給我們的 headers 變數,然後呼叫它的方法 as_string 。就可以列印出我們從 Google 收到的頭資訊。你也可以透過 getcode 得到網頁的 HTTP 響應碼,當前情況下就是 200,意思是正常工作。

如果你想看看網頁的 HTML 程式碼,你可以呼叫變數 url 的方法 read。我不準備再現這個過程,因為輸出結果太長了。

請注意 request 物件預設發起 GET 請求,除非你指定了它的 data 引數。如果你給它傳遞了 data 引數,這樣 request 物件將會變成 POST 請求。

下載檔案

urllib 一個典型的應用場景是下載檔案。讓我們看看幾種可以完成這個任務的方法:

>>> import urllib.request
>>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip'
>>> response = urllib.request.urlopen(url)
>>> data = response.read()
>>> with open('/home/mike/Desktop/test.zip', 'wb') as fobj:
...     fobj.write(data)
...

這個例子中我們開啟一個儲存在我的部落格上的 zip 壓縮檔案的 URL。然後我們讀出資料並將資料寫到磁碟。一個替代此操作的方案是使用 urlretrieve :

>>> import urllib.request
>>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip'
>>> tmp_file, header = urllib.request.urlretrieve(url)
>>> with open('/home/mike/Desktop/test.zip', 'wb') as fobj:
...     with open(tmp_file, 'rb') as tmp:
...         fobj.write(tmp.read())

方法 urlretrieve 會把網路物件複製到本地檔案。除非你在使用 urlretrieve 的第二個引數指定你要儲存檔案的路徑,否則這個檔案將被複製到臨時資料夾的隨機命名的一個檔案中。這個可以為你節省一步操作,並且使程式碼看起來更簡單:

>>> import urllib.request
>>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip'
>>> urllib.request.urlretrieve(url, '/home/mike/Desktop/blog.zip')
('/home/mike/Desktop/blog.zip',
 <http.client.HTTPMessage object at 0x7fddc21c2470>)

如你所見,它返回了檔案儲存的路徑,以及從請求得來的頭資訊。

設定你的使用者代理

當你使用瀏覽器訪問網頁時,瀏覽器會告訴網站它是誰。這就是所謂的 user-agent (使用者代理)欄位。Python 的 urllib 會表示它自己為 Python-urllib/x.y , 其中 x 和 y 是你使用的 Python 的主、次版本號。有一些網站不認識這個使用者代理欄位,然後網站可能會有奇怪的表現或者根本不能正常工作。辛運的是你可以很輕鬆的設定你自己的 user-agent 欄位。

>>> import urllib.request
>>> user_agent = ' Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0'
>>> url = '
>>> headers = {'User-Agent': user_agent}
>>> request = urllib.request.Request(url, headers=headers)
>>> with urllib.request.urlopen(request) as response:
...     with open('/home/mdriscoll/Desktop/user_agent.html', 'wb') as out:
...         out.write(response.read())

這裡設定我們的使用者代理為 Mozilla FireFox ,然後我們訪問 , 它會告訴我們它識別出的我們的 user-agent 欄位。之後我們將 url 和我們的頭資訊傳給 urlopen 建立一個 Request 例項。最後我們儲存這個結果。如果你開啟這個結果,你會看到我們成功的修改了自己的 user-agent 欄位。使用這段程式碼盡情的嘗試不同的值來看看它是如何改變的。

urllib.parse

urllib.parse 庫是用來拆分和組合 URL 字串的標準介面。比如,你可以使用它來轉換一個相對的 URL 為絕對的 URL。讓我們試試用它來轉換一個包含查詢的 URL :

>>> from urllib.parse import urlparse
>>> result = urlparse(')
>>> result
ParseResult(scheme='https', netloc='duckduckgo.com', path='/', params='', query='q=python+stubbing&t=canonical&ia=qa', fragment='')
>>> result.netloc
'duckduckgo.com'
>>> result.geturl()
'
>>> result.port
None

這裡我們匯入了函式 urlparse , 並且把一個包含搜尋查詢字串的 duckduckgo 的 URL 作為引數傳給它。我的查詢字串是搜尋關於 “python stubbing” 的文章。如你所見,它返回了一個 ParseResult 物件,你可以用這個物件瞭解更多關於 URL 的資訊。舉個例子,你可以獲取到埠資訊(本例中沒有埠資訊)、網路位置、路徑和很多其它東西。

提交一個 Web 表單

這個模組還有一個方法 urlencode 可以向 URL 傳輸資料。 urllib.parse 的一個典型使用場景是提交 Web 表單。讓我們透過搜尋引擎 duckduckgo 搜尋 Python 來看看這個功能是怎麼工作的。

>>> import urllib.request
>>> import urllib.parse
>>> data = urllib.parse.urlencode({'q': 'Python'})
>>> data
'q=Python'
>>> url = '
>>> full_url = url + '?' + data
>>> response = urllib.request.urlopen(full_url)
>>> with open('/home/mike/Desktop/results.html', 'wb') as f:
...     f.write(response.read())

這個例子很直接。基本上我們是使用 Python 而不是瀏覽器向 duckduckgo 提交了一個查詢。要完成這個我們需要使用 urlencode 構建我們的查詢字串。然後我們把這個字串和網址拼接成一個完整的正確 URL ,然後使用 urllib.request 提交這個表單。最後我們就獲取到了結果然後儲存到磁碟上。

urllib.robotparser

robotparser 模組是由一個單獨的類 RobotFileParser 構成的。這個類會回答諸如一個特定的使用者代理是否獲取已經設定了 robot.txt 的網站的 URL。 robot.txt 檔案會告訴網路爬蟲或者機器人當前網站的那些部分是不允許被訪問的。讓我們看一個簡單的例子:

>>> import urllib.robotparser
>>> robot = urllib.robotparser.RobotFileParser()
>>> robot.set_url(')
None
>>> robot.read()
None
>>> robot.can_fetch('*', ')
True
>>> robot.can_fetch('*', ')
False

這裡我們匯入了 robot 分析器類,然後建立一個例項。然後我們給它傳遞一個表明網站 robots.txt 位置的 URL 。接下來我們告訴分析器來讀取這個檔案。完成後,我們給它了一組不同的 URL 讓它找出那些我們可以爬取而那些不能爬取。我們很快就看到我們可以訪問主站但是不能訪問 cgi-bin 路徑。

總結一下

現在你就有能力使用 Python 的 urllib 包了。在這一節裡,我們學習瞭如何下載檔案、提交 Web 表單、修改自己的使用者代理以及訪問 robots.txt。 urllib 還有一大堆附加功能沒有在這裡提及,比如網站身份認證。你可能會考慮在使用 urllib 進行身份認證之前切換到 requests 庫,因為 requests 已經以更易用和易除錯的方式實現了這些功能。我同時也希望提醒你 Python 已經透過 http.cookies 模組支援 Cookies 了,雖然在 request 包裡也很好的封裝了這個功能。你應該可能考慮同時試試兩個來決定那個最適合你。

原文來自:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2987788/,如需轉載,請註明出處,否則將追究法律責任。

相關文章