人生苦短,我用 Pythonhtml
前文傳送門:python
小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝github
小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門數據庫
小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門json
小白學 Python 爬蟲(5):前置準備(四)數據庫基礎瀏覽器
小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝服務器
小白學 Python 爬蟲(10):Session 和 Cookies
看到本篇實戰的同窗有沒有很激動,通過了前面十篇基礎內容的折磨,終於等到實戰章節了,有沒有一種激動之情。
想到一句歌詞:終於等到你~~~
首先,官方文檔地址敬上:
官方文檔地址:https://docs.python.org/3/library/urllib.html
在前面的前置準備中,咱們一塊兒安裝了不少第三方的請求類庫,在介紹這些第三方的類庫前,咱們先介紹一下 Python3 自己自帶的一個 HTTP 請求庫 urllib 。
urllib 是一個軟件包,它包含了幾個用於處理 URL 的模塊:
若是要說怎麼學習最快,固然是查看官方文檔,首先祭出官方文檔的地址。
urllib.request官方文檔: https://docs.python.org/3/library/urllib.request.html#module-urllib.request
這裏的解釋是最權威了,而且目前已經提供了中文版本,不過那個翻譯看起來像是機器翻譯的,質量並不高。
若是實在看不懂,就只能看小編 XBB 了。
urllib.request
模塊提供了最基本的構造 HTTP 請求的方法,使用它能夠模擬瀏覽器的一個請求發起過程,同時它還帶有處理受權驗證(authenticaton)、重定向(redirection)、瀏覽器Cookies以及其餘內容。
語法:
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)複製代碼
這麼厲害的模塊固然是要趕忙嘗試一下,首先咱們使用它爬取一下小編的博客站:
import urllib.request
response = urllib.request.urlopen('https://www.geekdigging.com/')
print(response.read().decode('utf-8'))複製代碼
運行結果小編這裏就不展現,比較長。
短短的三行代碼,咱們就完成了網站源代碼的抓取,是否是很簡單。
當咱們獲得源代碼以後,想要的連接、文本信息,均可以從中提取出來。
各位同窗看到打印的內容,能夠猜想一下這個內容是什麼數據類型,會是字符串類型麼?
使用 type()
看一下就知道了。
print(type(response))複製代碼
結果:
<class 'http.client.HTTPResponse'>複製代碼
urlopen 返回了一個 HTTPResponse 類型的對象。
官方文檔對 HTTPResponse 的解釋以下:
An HTTPResponse instance wraps the HTTP response from the server. It provides access to the request headers and the entity body. The response is an iterable object and can be used in a with statement.
大意是說 HTTPResponse 是對 HTTP 響應的包裝。它提供了對請求頭和請求體的訪問。這個響應是一個能夠迭代的對象。
HTTPResponse 主要包含 read() 、 readline() 、 getheader(name) 、 getheaders() 、 fileno() 等方法,以及 msg 、 version 、 status 、 reason 、 debuglevel 、 closed 等屬性。
import urllib.request
# 獲取HTTP協議版本號(10 for HTTP/1.0, 11 for HTTP/1.1)
print(response.version)
# 獲取響應碼
print(response.status)
print(response.getcode())
# 獲取響應描述字符串
print(response.reason)
# 獲取實際請求的頁面url(防止重定向用)
print(response.geturl())
# 獲取特定響應頭信息
print(response.getheader(name="Content-Type"))
# 獲取響應頭信息,返回二元元組列表
print(response.getheaders())
# 獲取響應頭信息,返回字符串
print(response.info())
# 讀取響應體
print(response.readline().decode('utf-8'))複製代碼
結果有點長,小編就不貼了,各位同窗能夠本身運行一下。
data
用來指明發往服務器請求中的額外的參數信息, data
默認是 None ,此時以 GET 方式發送請求;當用戶給出 data
參數的時候,改成 POST 方式發送請求。
來個示例吧,這裏咱們使用 httpbin 提供的測試接口,此項目爲 postmanlabs 提供在 Github開源的項目, Github 地址爲:https://github.com/postmanlabs/httpbin 。
import urllib.request
import urllib.parse
post_data = bytes(urllib.parse.urlencode({'name': 'geekdigging', 'hello':'world'}), encoding='utf8')
response = urllib.request.urlopen('https://httpbin.org/post', data = post_data)
print(response.read().decode('utf-8'))複製代碼
值得注意的是,這裏咱們傳遞了兩個參數,是以 dict 的方式傳遞的,它必定須要被轉碼成 bytes
字節流, 這裏使用了 bytes()
方法,第一個參數是咱們須要轉換的字符串,第二個參數是編碼方式。
這裏咱們請求的路徑是 https://httpbin.org/post
,這個連接能夠用來測試 POST 請求,它能夠返回一些咱們剛纔請求的信息。
響應結果以下:
{
"args": {},
"data": "",
"files": {},
"form": {
"hello": "world",
"name": "geekdigging"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "28",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/3.7"
},
"json": null,
"origin": "218.79.141.143, 218.79.141.143",
"url": "https://httpbin.org/post"
}複製代碼
從返回的響應信息中,咱們能夠看到請求頭的相關信息,如咱們請求的數據類型 Content-Type
爲 application/x-www-form-urlencoded
,這個表明了咱們提交數據的方式是表單提交,還能夠看到請求的來源 origin
是小編當前電腦的 ip 地址,能夠看到咱們提交的數據 form
等等的相關信息。
timeout 用於設置超時時間,單位爲秒。
若是請求超出了設置的時間,還未響應,就會拋出異常。
咱們看個小示例:
import urllib.request
import urllib.parse
response = urllib.request.urlopen('http://httpbin.org/get', timeout = 1)
print(response.read().decode('utf-8'))複製代碼
咱們先將超時時間設置成爲 1s ,看下響應結果:
{
"args": {},
"headers": {
"Accept-Encoding": "identity",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/3.7"
},
"origin": "218.79.141.143, 218.79.141.143",
"url": "https://httpbin.org/get"
}複製代碼
能夠看到是正常響應的,咱們將超時時間設置爲 0.1s ,再看下結果:
import urllib.request
import urllib.parse
response = urllib.request.urlopen('http://httpbin.org/get', timeout = 0.1)
print(response.read().decode('utf-8'))複製代碼
已經能夠看到拋異常出來了:
Traceback (most recent call last):
...
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
...
urllib.error.URLError: <urlopen error timed out>
Process finished with exit code 1複製代碼
內容有些多,小編省略了大量的內容。
咱們能夠看到,這裏確實拋出了超時的異常,還有同窗記得咱們前面講過的異常處理麼,這時咱們能夠添加一個異常處理,將這個超時的異常捕獲。
import urllib.request
import urllib.error
import socket
try:
response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
print(response.read().decode('utf-8'))
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
print('請求超時啦~~~')
else:
print(e)複製代碼
結果以下:
請求超時啦~~~複製代碼
證實咱們已經成功捕獲到了請求超時的異常。
還有其餘的幾個參數: cafile
、 capath
、 cadefault
用於實現可信任的 CA 證書的 HTTP 請求,通常不多使用, context
,用來實現 SSL 加密傳輸,通常也不多使用。
好了,本篇的內容就到這裏結束,但願各位同窗能夠本身動手敲一下上面的示例代碼。
本系列的全部代碼小編都會放在代碼管理倉庫 Github 和 Gitee 上,方便你們取用。