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)