urllib 是一個用來處理網絡請求的python標準庫,它包含4個模塊。html
urllib.request---請求模塊,用於發起網絡請求python
urllib.parse---解析模塊,用於解析URLweb
urllib.error---異常處理模塊,用於處理request引發的異常json
urllib.robotparser robots.tx---用於解析robots.txt文件瀏覽器
urllib.request模塊websocket
request模塊主要負責構造和發起網絡請求,並在其中添加Headers,Proxy等。 利用它能夠模擬瀏覽器的請求發起過程。cookie
關於urllib.request.urlopen參數的介紹網絡
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)app
urlopen是一個簡單發送網絡請求的方法。它接收一個字符串格式的url,它會向傳入的url發送網絡請求,而後返回結果。socket
先寫一個簡單的例子:
from urllib import request
response = request.urlopen(url='http://www.httpbin.org/get') print(response.read().decode())
urlopen默認會發送get請求,當傳入data參數時,則會發起POST請求。data參數是字節類型、者類文件對象或可迭代對象。
from urllib import request
response = request.urlopen(url='http://www.httpbin.org/post', data=b'username=q123&password=123') print(response.read().decode())
還才能夠設置超時,若是請求超過設置時間,則拋出異常。timeout沒有指定則用系統默認設置,timeout只對,http,https以及ftp鏈接起做用。它以秒爲單位,好比能夠設置timeout=0.1 超時時間爲0.1秒。
from urllib import request
response = request.urlopen(url='https://www.baidu.com/',timeout=0.1)
Request對象
利用openurl能夠發起最基本的請求,但這幾個簡單的參數不足以構建一個完整的請求,能夠利用更強大的Request對象來構建更加完整的請求。
1 . 請求頭添加
經過urllib發送的請求會有一個默認的Headers: 「User-Agent」:「Python-urllib/3.6」,指明請求是由urllib發送的。因此遇到一些驗證User-Agent的網站時,須要咱們自定義Headers把本身假裝起來。
from urllib import request headers ={ 'Referer': 'https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&tn=baidu&wd=python%20urllib%E5%BA%93&oq=python%2520urllib%25E5%25BA%2593&rsv_pq=947af0af001c94d0&rsv_t=66135egC273yN5Uj589q%2FvA844PvH9087sbPe9ZJsjA8JA10Z2b3%2BtWMpwo&rqlang=cn&rsv_enter=0&prefixsug=python%2520urllib%25E5%25BA%2593&rsp=0', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36' } response = request.Request(url='https://www.baidu.com/',headers=headers) response = request.urlopen(response) print(response.read().decode())
2. 操做cookie
在開發爬蟲過程當中,對cookie的處理很是重要,urllib的cookie的處理以下案例
from urllib import request from http import cookiejar # 建立一個cookie對象 cookie = cookiejar.CookieJar() # 創一個cookie處理器 cookies = request.HTTPCookieProcessor(cookie) # 以它爲參數,建立opener對象 opener = request.build_opener(cookies) # 使用這個opener 來發請求 res =opener.open('https://www.baidu.com/') print(cookies.cookiejar)
3. 設置代理
運行爬蟲的時候,常常會出現被封IP的狀況,這時咱們就須要使用ip代理來處理,urllib的IP代理的設置以下:
from urllib import request url ='http://httpbin.org/ip' #代理地址 proxy ={'http':'172.0.0.1:3128'} # 代理處理器 proxies =request.ProxyBasicAuthHandler(proxy) # 建立opener對象 opener = request.build_opener(proxies) res =opener.open(url) print(res.read().decode())
urlib庫中的類或或者方法,在發送網絡請求後,都會返回一個urllib.response的對象。它包含了請求回來的數據結果。它包含了一些屬性和方法,供咱們處理返回的結果
read() 獲取響應返回的數據,只能用一次
readline() 讀取一行
info() 獲取響應頭信息
geturl() 獲取訪問的url
getcode() 返回狀態碼
urllib.parse模塊
parse.urlencode() 在發送請求的時候,每每會須要傳遞不少的參數,若是用字符串方法去拼接會比較麻煩,parse.urlencode()方法就是用來拼接url參數的。
from urllib import parse params = {'wd':'測試', 'code':1, 'height':188} res = parse.urlencode(params) print(res)
打印結果爲wd=%E6%B5%8B%E8%AF%95&code=1&height=188
也能夠經過parse.parse_qs()方法將它轉回字典
print(parse.parse_qs('wd=%E6%B5%8B%E8%AF%95&code=1&height=188'))
urllib.error模塊
error模塊主要負責處理異常,若是請求出現錯誤,咱們能夠用error模塊進行處理 主要包含URLError和HTTPError
URLError:是error異常模塊的基類,由request模塊產生的異常均可以用這個類來處理
HTTPError:是URLError的子類,主要包含三個屬性
from urllib import request,error try: response = request.urlopen("http://pythonsite.com/1111.html") except error.HTTPError as e: print(e.reason) print(e.code) print(e.headers) except error.URLError as e: print(e.reason) else: print("reqeust successfully")
urllib.robotparse模塊
robotparse模塊主要負責處理爬蟲協議文件,robots.txt.的解析。 https://www.taobao.com/robots.txt
Robots協議(也稱爲爬蟲協議、機器人協議等)的全稱是「網絡爬蟲排除標準」(Robots Exclusion Protocol),網站經過Robots協議告訴搜索引擎哪些頁面能夠抓取,哪些頁面不能抓取
urllib3 是一個基於python3的功能強大,友好的http客戶端。愈來愈多的python應用開始採用urllib3.它提供了不少python標準庫裏沒有的重要功能
安裝:
pip install urllib3
構造請求(request)
import urllib3 # 建立鏈接 http = urllib3.PoolManager() # 發送請求 res = http.request('GET','https://www.baidu.com/') # 狀態碼 print(res.status) # 返回的數據 print(res.data.decode())
發送post請求
import urllib3 # 建立鏈接 http = urllib3.PoolManager() # 發送請求 res = http.request('POST','https://www.baidu.com/',fields={'hello':'word'}) # 狀態碼 print(res.status) # 返回的數據 print(res.data.decode())
http響應對象提供status, data,和header等屬性
status--狀態碼
data--讀取返回的數據
header--請求頭
返回的json格式數據能夠經過json模塊,load爲字典數據類型。
import json data={'attribute':'value'} encode_data= json.dumps(data).encode() r = http.request('POST', 'http://httpbin.org/post', body=encode_data, headers={'Content-Type':'application/json'} ) print(r.data.decode('unicode_escape'))
響應返回的數據都是字節類型,對於大量的數據咱們經過stream來處理更好
import urllib3 http = urllib3.PoolManager() r =http.request('GET','http://httpbin.org/bytes/1024',preload_content=False) for chunk in r.stream(32): print(chunk)
也能夠當作一個文件對象來處理
import urllib3 http = urllib3.PoolManager() r =http.request('GET','http://httpbin.org/bytes/1024',preload_content=False) for chunk in r: print(chunk)
urllib3庫Proxies(代理IP)
import urllib3 proxy = urllib3.ProxyManager('http://172.0.0.1:3128') res =proxy.request('GET','https://www.baidu.com/') print(res.data)
urllib3庫headers(添加請求頭)
import urllib3 http = urllib3.PoolManager() headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36' } res = http.request('GET','https://www.baidu.com/',headers=headers) print(res.data)
JSON 當咱們須要發送json數據時,咱們須要在request中傳入編碼後的二進制數據類型的body參數,並制定Content-Type的請求頭
JSON:在發起請求時,能夠經過定義body 參數並定義headers的Content-Type參數來發送一個已通過編譯的JSON數據: import json data={'attribute':'value'} encode_data= json.dumps(data).encode() r = http.request('POST', 'http://httpbin.org/post', body=encode_data, headers={'Content-Type':'application/json'} ) print(r.data.decode('unicode_escape'))
對於二進制的數據上傳,咱們用指定body的方式,並設置Content-Type的請求頭
#使用multipart/form-data編碼方式上傳文件,可使用和傳入Form data數據同樣的方法進行,並將文件定義爲一個元組的形式 (file_name,file_data): with open('1.txt','r+',encoding='UTF-8') as f: file_read = f.read() r = http.request('POST', 'http://httpbin.org/post', fields={'filefield':('1.txt', file_read, 'text/plain') }) print(r.data.decode('unicode_escape')) #二進制文件 with open('websocket.jpg','rb') as f2: binary_read = f2.read() r = http.request('POST', 'http://httpbin.org/post', body=binary_read, headers={'Content-Type': 'image/jpeg'}) # # print(json.loads(r.data.decode('utf-8'))['data'] ) print(r.data.decode('utf-8'))