Python爬蟲中urllib3與urllib的區別是什麼
urllib庫
urllib 是一個用來處理網絡請求的python標準庫,它包含4個模塊。
- urllib.request—請求模塊,用於發起網絡請求
- urllib.parse—解析模塊,用於解析URL
- urllib.error—異常處理模塊,用於處理request引起的異常
- urllib.robotparser robots.tx—用於解析robots.txt文件
urllib.request模塊
request模塊主要負責構造和發起網絡請求,並在其中添加Headers,Proxy等。 利用它可以模擬瀏覽器的請求發起過程。
- 發起網絡請求
- 操作cookie
- 添加Headers
- 使用代理
關於urllib.request.urlopen參數的介紹
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
urlopen是一個簡單發送網絡請求的方法。它接收一個字符串格式的url,它會向傳入的url發送網絡請求,然後返回結果。
先寫一個簡單的例子:
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的子類,主要包含三個屬性
- Code:請求的狀態碼
- reason:錯誤的原因
- headers:響應的報頭
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.的解析。
Robots協議(也稱為爬蟲協議、機器人協議等)的全稱是“網絡爬蟲排除標準”(Robots Exclusion Protocol),網站通過Robots協議告訴搜索引擎哪些頁面可以抓取,哪些頁面不能抓取
網絡庫urllib3
urllib3是比urllib庫更強大的存在,目前已經有許多的原生系統已經開始使用urllib3。
urllib3具有如下優點:
- 支持HTTP和SOCKS代理
- 支持壓縮編碼
- 100%測試覆蓋率
- 具有鏈接池
- 線程安全
- 客戶端SLL/TLS驗證
- 協助處理重復請求和HTTP重定位
- 使用multipart編碼上傳文件
因為urllib3並不是Python的標準庫,所以我們使用之前,需要進行下載安裝,具體命令如下所示:
pip install urllib3 #或 conda install urllib3
下面,我們來講解urllib3庫的使用方式。
網絡請求
GET請求
首先,在我們使用urllib3庫進行網絡請求時,需創建PoolManager類的實例,該類用於管理線程池。
下面,我們來通過urllib訪問百度,並返回查詢的結果,示例如下:
import urllib3 http = urllib3.PoolManager() url = 'http://www.baidu.com/s' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = http.request('GET', url, fields={'wd': '機器學習'}, headers=headers) result = response.data.decode('UTF-8') print(result)
運行之後,效果如下:
這裡,我們通過fields參數指定GET的請求字段。不過,這裡先一步講解瞭請求頭,其實是百度有安全機制,讀者可以去掉headers參數試試。會返回百度的安全驗證頁面。
POST請求
如果需要向服務器提交表單或者比較復雜的數據,就需要使用到POST請求。POST請求比較簡單,僅僅隻是將請求的第一個參數改為“POST”即可。
示例如下:
import urllib3 http = urllib3.PoolManager() url = 'http://httpbin.org/post' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = http.request('POST', url, fields={'username': 'name', 'age': '123456'}, headers=headers) result = response.data.decode('UTF-8') print(result)
運行之後,返回如下數據:
HTTP響應頭
使用urllib3庫進行網絡訪問時,其返回的HTTPResponse。默認有一些攜帶的參數,其中就包括info方法。它能返回響應頭數據,示例如下:
import urllib3 http = urllib3.PoolManager() url = 'http://www.baidu.com/s' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = http.request('POST', url, fields={'wd': '機器學習'}, headers=headers) for key in response.info().keys(): print('key:',response.info()[key])
運行之後,返回的響應數據如下:
上傳文件
首先,我們需要簡單的實現一個文件上傳的服務器代碼,這裡我們使用Flask搭建一個簡單的服務器Python程序,代碼如下:
import flask import os UPLOAD_FILE = 'uploads' app = flask.Flask(__name__) @app.route('/', methods=['POST']) def upload_file(): file = flask.request.files['file'] if file: file.save(os.path.join(UPLOAD_FILE, os.path.basename(file.filename))) return '文件上傳成功' else: return '文件上傳失敗' if __name__ == '__main__': app.run()
運行之後,它會一直等待客戶端上傳文件。
這個時候,我們再來實現urllib3是如何上傳文件的,示例如下:
import urllib3 http = urllib3.PoolManager() with open('1.jpg', 'rb') as f: fileData = f.read() url = 'http://127.0.0.1:5000' response = http.request('POST', url, fields={'file': ('1.jpg', fileData, 'image/jpeg')}) print(response.data.decode('UTF-8'))
默認flask搭建的服務器,其接口為5000,也就是通過127.0.0.1:5000進行訪問。運行之後,就會在uploads文件夾下創建一個1.jpg的圖片。
同時,控制臺會輸出文件上傳成功,而服務器會返回狀態碼200。
這裡,上傳文件就1一個鍵值對,其中file代表服務器上傳文件的字段。值的元組裡,fileData為文件的二進制形式,’image/jpeg’代表上傳文件的格式(可以省略)。
超時處理
urllib3庫其HTTP的底層都是基於Socket實現的,而Socket超時又分為連接超時與讀超時。
其中,連接超時表示在連接的過程中,由於服務器的問題或域名弄錯瞭,而導致的無法連接的情況拋出的異常。
讀超時表示從服務器讀取數據時由於服務器的問題,導致長時間無法正常讀取數據而導致的異常。
通常,我們超時的設置有2種,一種是通過http.request(timeout)進行設置,一種是通過PoolManager()連接池進行設置。示例如下:
from urllib3 import * http = PoolManager(timeout=Timeout(connect=2.0, read=2.0)) with open('1.jpg', 'rb') as f: fileData = f.read() url = 'http://127.0.0.1:5000' try: response = http.request('POST', url, timeout=Timeout(connect=2.0, read=4.0)) print(response.data.decode('UTF-8')) except Exception as e: print(e)
需要註意的是,通過連接池PoolManager進行設置的超時,是全局超時時間,哪怕你後邊的請求不設置,也是默認使用的這個超時。如果同時設置瞭request的超時,那麼以request為準。
到此這篇關於Python爬蟲中urllib3與urllib的區別是什麼的文章就介紹到這瞭,更多相關Python urllib3 urllib內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Python爬蟲之urllib庫詳解
- python 如何用urllib與服務端交互(發送和接收數據)
- python爬蟲基礎之urllib的使用
- 關於python爬蟲應用urllib庫作用分析
- python urllib.request模塊的使用詳解