Python爬蟲之Urllib的基礎運用

1. 什麼是Urllib

Urllib是Python內置的HTTP請求庫,不需要額外安裝的庫,只要裝好Python就可以使用。其主要模塊如下:

模塊名 說明
urllib.request 發送請求模塊
urllib.error 異常處理模塊
urllib.parse url解析模塊

2. urlopen

urllib.request.urlopen(url, data=None, timeout=<object object at 0x0000025557C0B750>, *, cafile=None, capath=None, cadefault=False, context=None)

url :請求的網址
data(默認空):是伴隨 url 提交的數據(比如要post的數據),同時 HTTP 請求將從 "GET"方式 改爲 "POST"方式。
timeout = 1 :設置超時的時長,超過一秒則自動結束

情景1:僅有url參數,此時爲Get請求

from urllib import request
url = "http://www.baidu.com"
# 僅有url參數
response = request.urlopen(url)
# 使用read()來去讀urlopen請求url的結果
a = response.read() # 可以查看結果爲bytes數據類型,因此需要解碼爲“utf-8”
# 用decode(編碼,“ignore”) ignore”目的是忽略一些小錯誤
b = a.decode("utf-8","ignore")
# 實際上,以上步驟通常一部寫完
c = response.read().decode("utf-8","ignore")

情景2:有url、data,這種爲Post請求

from urllib import parse,request
# 設置一個data,注意是一個bytes數據類型
data = bytes(parse.urlencode({"word":"hello"}),encoding = "utf8")
response = request.urlopen("http://httpbin.org/post",data=data)
# print(response.read())
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "word": "hello"\n  }, \n  "headers": {\n    "Accept-Encoding": "identity", \n    "Content-Length": "10", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "Python-urllib/3.6", \n    "X-Amzn-Trace-Id": "Root=1-5ecd40e7-d4beebdce8d18eef9f517b8a"\n  }, \n  "json": null, \n  "origin": "183.229.25.96", \n  "url": "http://httpbin.org/post"\n}\n'

情景3:設置超時

from urllib import request
url = "http://www.baidu.com"
# 僅有url參數
response = request.urlopen(url,timeout=1)
# 實際上,以上步驟通常一部寫完
c = response.read().decode("utf-8","ignore")

情景4:錯誤捕獲

from urllib import request,error
url = "http://www.baidu.com"
# 僅有url參數
try:
    response = request.urlopen(url,timeout=0.01)
except error.URLError as e:
    print(e)
<urlopen error timed out>

3. Request(可模擬計算機訪問)

前面urlopen()的參數就是一個url地址;但是如果需要執行更復雜的操作,比如增加HTTP報頭,必須創建一個 Request 實例來作爲urlopen()的參數;而需要訪問的url地址則作爲 Request 實例的參數。

request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
url :請求的網址
data :是伴隨 url 提交的數據(比如要post的數據),同時 HTTP 請求將從 "GET"方式 改爲 "POST"方式。
headers(默認空):是一個字典,包含了需要發送的HTTP報頭的鍵值對。
method=“POST”調用post請求

User-Agent:接用urllib給一個網站發送請求的話,確實略有些唐突了,就好比,人家每家都有門,你以一個路人的身份直接闖進去顯然不是很禮貌。而且有一些站點不喜歡被程序(非人爲訪問)訪問,有可能會拒絕你的訪問請求。但是如果我們用一個合法的身份去請求別人網站,顯然人家就是歡迎的,所以我們就應該給我們的這個代碼加上一個身份,就是所謂的User-Agent頭。

在這裏插入圖片描述

headers其實就是User-Agent,不過在程序中將其改爲字典的形式而已。

情景1:只有Url

from urllib import request
res = request.Request("http://python.org")
response = request.urlopen(res)
result = response.read().decode("utf-8","ignore")

情景2 有url和headers,有headers則是通過模擬計算及訪問,是一種反爬措施

from urllib import request
header = {
    "User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36"
}
res = request.Request("http://python.org",headers=header)
response = request.urlopen(res)
result = response.read().decode("utf-8","ignore")

情景3 有url,headers,data,此時變爲post請求

from urllib import parse,request
# 設置一個data,注意是一個bytes數據類型
data = bytes(parse.urlencode({"word":"hello"}),encoding = "utf8")
header = {
    "User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36"
}
res = request.Request("http://httpbin.org/post",data = data ,headers=header)
response = request.urlopen(res)
result = response.read().decode("utf-8","ignore")

headers還可以用以下方法添加

from urllib import parse,request
# 設置一個data,注意是一個bytes數據類型
data = bytes(parse.urlencode({"word":"hello"}),encoding = "utf8")
res = request.Request("http://httpbin.org/post",data = data ,method="POST")
res.add_header("User-Agent","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36"
)
response = request.urlopen(res)
result = response.read().decode("utf-8","ignore")

此外還可以添加,timeout,在urlopen中添加

4. 查看響應是否成功

from urllib import request
res = request.Request("http://python.org")
response = request.urlopen(res)
print(response.info())# 響應頭
# 判斷是否訪問成功
print(response.getcode())# 狀態碼 2XX 3XX 4XX 5XX
# 返回所響應的地址
print(response.geturl()) # 返回響應地址
Connection: close
Content-Length: 48882
Server: nginx
Content-Type: text/html; charset=utf-8
X-Frame-Options: DENY
Via: 1.1 vegur
Via: 1.1 varnish
Accept-Ranges: bytes
Date: Tue, 26 May 2020 17:23:47 GMT
Via: 1.1 varnish
Age: 1215
X-Served-By: cache-bwi5127-BWI, cache-hkg17930-HKG
X-Cache: HIT, HIT
X-Cache-Hits: 3, 1151
X-Timer: S1590513827.165994,VS0,VE0
Vary: Cookie
Strict-Transport-Security: max-age=63072000; includeSubDomains


200
https://www.python.org/
# 獲取網頁內容方法
result = response.read().decode("utf-8","ignore")
# print(result)

更多用法參考,如設置代理,cookie等

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章