您好,登錄后才能下訂單哦!
小編給大家分享一下Python中urllib爬蟲、request模塊和parse模塊的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
urllib
urllib
是Python中用來處理URL的工具包,源碼位于/Lib/下。它包含了幾個模塊:用于打開及讀寫的urls的request
模塊、由request
模塊引起異常的error
模塊、用于解析urls的parse
模塊、用于響應處理的response
模塊、分析robots.txt文件的robotparser
模塊。
注意版本差異。urllib
有3個版本:Python2.X包含urllib
、urllib2
模塊,Python3.X把urllib
、urllib2
以及urlparse
合成到urllib
包中,而urllib3
是新增的第三方工具包。若遇到"No module named urllib2"等問題幾乎都是Python版本不同導致的。
urllib3
是一個功能強大、條例清晰、用于HTTP客戶端的Python庫。它提供了許多Python標準庫里所沒有的特性:壓縮編碼、連接池、線程安全、SSL/TLS驗證、HTTP和SCOCKS代理等。可以通過pip進行安裝:pip install urllib3
也可以通過GitHub下載最新代碼:
git clone git://github.com/shazow/urllib3.git python setup.py install
urllib3
參考文檔:https://urllib3.readthedocs.io/en/latest/
request模塊
urllib.request
模塊定義了身份認證、重定向、cookies等應用中打開url的函數和類。
再簡單介紹下request
包,該包用于高級的非底層的HTTP客戶端接口,容錯能力比request
模塊強大。request
使用的是urllib3,它繼承了urllib2的特性,支持HTTP連接保持和連接池,支持使用cookie保持會話、文件上傳、自動解壓縮、Unicode響應、HTTP(S)代理等。更多具體可參考文檔http://requests.readthedocs.io。
下面將介紹urllib.request
模塊常用函數和類。
訪問URL
一、urlopen()
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=false,context=None)
該函數用于抓取URL數據,十分重要。帶有如上所示的參數,除了URL參數外(字符串或Request
對象)其余參數都有默認值。
①URL參數
from urllib import requestwith request.urlopen("http://www.baidu.com") as f: print(f.status) print(f.getheaders())#運行結果如下200[('Bdpagetype', '1'), ('Bdqid', '0x8583c98f0000787e'), ('Cache-Control', 'private'), ('Content-Type', 'text/html;charset=utf-8'), ('Date', 'Fri, 19 Mar 2021 08:26:03 GMT'), ('Expires', 'Fri, 19 Mar 2021 08:25:27 GMT'), ('P3p', 'CP=" OTI DSP COR IVA OUR IND COM "'), ('P3p', 'CP=" OTI DSP COR IVA OUR IND COM "'), ('Server', 'BWS/1.1'), ('Set-Cookie', 'BAIDUID=B050D0981EE3A706D726852655C9FA21:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Set-Cookie', 'BIDUPSID=B050D0981EE3A706D726852655C9FA21; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Set-Cookie', 'PSTM=1616142363; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Set-Cookie', 'BAIDUID=B050D0981EE3A706FA20DF440C89F27F:FG=1; max-age=31536000; expires=Sat, 19-Mar-22 08:26:03 GMT; domain=.baidu.com; path=/; version=1; comment=bd'), ('Set-Cookie', 'BDSVRTM=0; path=/'), ('Set-Cookie', 'BD_HOME=1; path=/'), ('Set-Cookie', 'H_PS_PSSID=33272_33710_33690_33594_33600_33624_33714_33265; path=/; domain=.baidu.com'), ('Traceid', '161614236308368819309620754845011048574'), ('Vary', 'Accept-Encoding'), ('Vary', 'Accept-Encoding'), ('X-Ua-Compatible', 'IE=Edge,chrome=1'), ('Connection', 'close'), ('Transfer-Encoding', 'chunked')]
②data參數
如果向服務器發送數據,那么data參數必須是一個有數據的byes
對象,否則為None。在Python3.2之后可以是一個iterable對象。若是,則headers
中必須帶有Content-Length參數。HTTP請求使用POST
方法時,data必須有數據;使用GET
方法時,data寫None即可。
from urllib import parsefrom urllib import request data = bytes(parse.urlencode({"pro":"value"}),encoding="utf8")response = request.urlopen("http://httpbin.org/post",data=data)print(response.read())#運行結果如下b'{\n "args": {}, \n "data": "", \n "files": {}, \n "form": {\n "pro": "value"\n }, \n "headers": {\n "Accept-Encoding": "identity", \n "Content-Length": "9", \n "Content-Type": "application/x-www-form-urlencoded", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.9", \n "X-Amzn-Trace-Id": "Root=1-60545f5e-7428b29435ce744004d98afa"\n }, \n "json": null, \n "origin": "112.48.80.243", \n "url": "http://httpbin.org/post"\n}\n'
對數據進行POST
請求,需要轉碼bytes
類型或者iterable
類型。這里通過bytes()
進行字節轉換,考慮到第一個參數為字符串,所以需要利用parse模塊(下面會講)的urlencode()
方法對上傳的數據進行字符串轉換,同時指定編碼格式為utf8。測試網址httpbin.org可以提供HTTP測試,從返回的內容可以看出提交以表單form作為屬性、以字典作為屬性值。
③timeout參數
該參數是可選的,以秒為單位指定一個超時時間,若超過該時間則任何操作都會被阻止,如果沒有指定,那么默認會取sock.GLOBAL_DEFAULT_TIMEOUT
對應的值。該參數僅對http、https、ftp連接有效。
超時后會拋出urllib.error.URLError:<urlopen error time out>異常,可以用try…except來處理異常。
from urllib import request response = request.urlopen("http://httpbin.org/get",timeout=1)print(response.read())#運行結果如下b'{\n "args": {}, \n "headers": {\n "Accept-Encoding": "identity", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.9", \n "X-Amzn-Trace-Id": "Root=1-605469dd-76a6d963171127c213d9a9ab"\n }, \n "origin": "112.48.80.243", \n "url": "http://httpbin.org/get"\n}\n'
④返回對象的常用方法和屬性
除了前三個urlopen()
常用參數外,該函數返回用作context manager(上下文管理器)的類文件對象,并包含如下方法:
geturl():返回請求的URL,通常重定向后的URL照樣能獲取到
info():返回httplib.HTTPMessage對象,表示遠程服務器返回的頭信息
getcode():返回響應后的HTTP狀態碼
status屬性:返回響應后的HTTP狀態碼
msg屬性:請求結果
from urllib import request response = request.urlopen("http://httpbin.org/get")print(response.geturl())print("===========")print(response.info())print("===========")print(response.getcode())print("===========")print(response.status)print("===========")print(response.msg)
運行結果:
附:狀態碼對應狀態
1xx(informational):請求已經收到,正在進行中。
2xx(successful):請求成功接收,解析,完成。
3xx(Redirection):需要重定向。
4xx(Client Error):客戶端問題,請求存在語法錯誤,網址未找到。
5xx(Server Error):服務器問題。
二、build_opener()
urllib.request.build_opener([handler1 [handler2, ...]])
該函數不支持驗證、cookie及其他HTTP高級功能。要支持這些功能必須使用build_opener()
函數自定義OpenerDirector對象,稱之為Opener。
build_opener()
函數返回的是OpenerDirector實例,而且是按給定的順序鏈接處理程序的。作為OpenerDirector實例,可以從OpenerDirector類的定義看出他具有addheaders、handlers、handle_open、add_handler()、open()、close()等屬性或方法。open()方法與urlopen()函數的功能相同。
上述代碼通過修改http報頭進行HTTP高級功能操作,然后利用返回對象open()進行請求,返回結果與urlopen()一樣,只是內存位置不同而已。
實際上urllib.request.urlopen()方法只是一個Opener,如果安裝啟動器沒有使用urlopen啟動,調用的就是OpenerDirector.open()方法。那么如何設置默認全局啟動器呢?就涉及下面的install_opener
函數。
三、install_opener()
urllib.request.install_opener(opener)
安裝OpenerDirector實例作為默認全局啟動器。
首先導入request
模塊,實例化一個HTTPBasicAuthHandler對象,然后通過利用add_password()
添加用戶名和密碼來創建一個認證處理器,利用urllib.request.build_opener()方法來調用該處理器以構建Opener,并使其作為默認全局啟動器,這樣Opener在發生請求時具備了認證功能。通過Opener的open()
方法打開鏈接完成認證。
當然了,CSDN不需要賬號密碼也可以訪問,讀者還可以在其他網站上用自己的賬號進行測試。
除了上述方法外,還有將路徑轉換為URL的pathname2url(path)
、將URL轉換為路徑的url2pathname(path)
,以及返回方案至代理服務器URL映射字典的getproxies()
等方法。
Request類
前面介紹的urlopen()
方法可以滿足一般基本URL請求,如果需要添加headers信息,就要考慮更為強大的Request
類了。Request
類是URL請求的抽象,包含了許多參數,并定義了一系列屬性和方法。
一、定義
class urllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)
參數url是有效網址的字符串,同urlopen()
方法中一樣,data參數也是。
headers是一個字典,可以通過add_header()
以鍵值進行調用。通常用于爬蟲爬取數據時或者Web請求時更改User-Agent標頭值參數來進行請求。
origin_req_host是原始請求主機,比如請求的是針對HTML文檔中的圖像的,則該請求主機是包含圖像頁面所在的主機。
Unverifiable指示請求是否是無法驗證的。
method指示使用的是HTTP請求方法。常用的有GET、POST、PUT、DELETE等,
代碼示例:
from urllib import requestfrom urllib import parse data = parse.urlencode({"name":"baidu"}).encode('utf-8')headers = {'User-Agent':'wzlodq'}req = request.Request(url="http://httpbin.org/post",data=data,headers=headers,method="POST")response = request.urlopen(req)print(response.read())#運行結果如下b'{\n "args": {}, \n "data": "", \n "files": {}, \n "form": {\n "name": "baidu"\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": "wzlodq", \n "X-Amzn-Trace-Id": "Root=1-605491a4-1fcf3df01a8b3c3e22b5edce"\n }, \n "json": null, \n "origin": "112.48.80.34", \n "url": "http://httpbin.org/post"\n}\n'
注意data參數和前面一樣需是字節流類型的,不同的是調用Request
類進行請求。
二、屬性方法
①Request.full_url
full_url屬性包含setter、getter和deleter。如果原始請求URL片段存在,那么得到的full_url將返回原始請求的URL片段,通過添加修飾器@property
將原始URL傳遞給構造函數。
②Request.type:獲取請求對象的協議類型。
③Request.host:獲取URL主機,可能含有端口的主機。
④Request.origin_req_host:發出請求的原始主機,沒有端口。
⑤Request.get_method():返回顯示HTTP請求方法的字符串。
(插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/
⑥Request.add_header(key,val):向請求中添加標頭。
from urllib import requestfrom urllib import parse data = bytes(parse.urlencode({'name':'baidu'}),encoding='utf-8')req = request.Request('http://httpbin.org/post',data,method='POST')req.add_header('User-agent','test')response = request.urlopen(req)print(response.read().decode('utf-8'))
上述代碼中,通過add_header()
傳入了User-Agent,在爬蟲過程中,常常通過循環調用該方法來添加不同的User-Agent進行請求,避免服務器針對某一User-Agent的禁用。
其他類
BaseHandler
為所有注冊處理程序的基類,并且只處理注冊的簡單機制,從定義上看,BaseHandler
提供了一個添加基類的add_parent()
方法,后面介紹的類都是繼承該類操作的。
HTTPErrorProcessor:用于HTTP錯誤響應過程。
HTTPDefaultErrorHandler:用于處理HTTP響應錯誤。
ProxyHandler:用于設置代理。
HTTPRedirectHandler:用于設置重定向。
HTTPCookieProcessor:用于處理cookie。
HEEPBasicAuthHandler:用于管理認證。
parse模塊
parse
模塊用于分解URL字符串為各個組成部分,包括尋址方案、網絡位置、路徑等,也可將這些部分組成URL字符串,同時可以對“相對URL"進行轉換等。
解析URL
一、urllib.parse.urlparse
(urlstring,scheme=’’,allow_fragments=True)
解析URL為6個部分,即返回一個6元組(tuple子類的實例),tuple類具有下標所示的屬性:
屬性 | 說明 | 對應下標指數 | 不存在時的取值 |
---|---|---|---|
scheme | URL方案說明符 0 | scheme參數 | |
netloc | 網絡位置部分 | 1 | 空字符串 |
path | 分層路徑 | 2 | 空字符串 |
params | 最后路徑元素的參數 | 3 | 空字符串 |
query | 查詢組件 | 4 | 空字符串 |
fragment | 片段標識符 | 5 | 空字符串 |
username | 用戶名 | None | |
password | 密碼 | None | |
hostname | 主機名 | None | |
port | 端口號 | None |
最后組成的URL結構為scheme://netloc/path;parameters?query#fragment
舉個栗子:
from urllib.parse import *res = urlparse('https://wzlodq.blog.csdn.net/article/details/113597816')print(res)print(res.scheme)print(res.netloc)print(res.path)print(res.params)print(res.query)print(res.username)print(res.password)print(res.hostname)print(res.port)print(res.geturl())print(tuple(res))print(res[0])print(res[1])print(res[2])
需要注意的是urlparse
有時并不能很好地識別netloc,它會假定相對URL以路徑分量開始,將其取值放在path中。
二、urllib.parse.urlunparse
(parts)
是urlparse()
的逆操作,即將urlparse()
返回的原則構建一個URL。
三、urllib.parse.urlsplit
(urlstring,scheme=’’.allow_fragments=True)
類似urlparse()
,但不會分離參數,即返回的元組對象沒有params元素,是一個五元組,對應下標指數也發生了改變。
from urllib.parse import *sp = urlsplit('https://wzlodq.blog.csdn.net/article/details/113597816')print(sp)#運行結果如下SplitResult(scheme='https', netloc='wzlodq.blog.csdn.net', path='/article/details/113597816', query='', fragment='')
四、urllib.parse.urlunsplit
(parts)
類似urlunparse()
,是urlsplit()
的逆操作,不再贅述。
五、urllib.parse.urljoin
(base,url,allow_fragments=True)
該函數主要組合基本網址(base)與另一個網址(url)以構建新的完整網址。
相對路徑和絕對路徑的url組合是不同的,而且相對路徑是以最后部分路徑進行替換處理的:
六、urllib.parse.urldefrag
(url)
根據url進行分割,如果url包含片段標識符,就返回url對應片段標識符前的網址,fragment取片段標識符后的值。如果url沒有片段標識符,那么fragment為空字符串。
轉義URL
URL轉義可以避免某些字符引起歧義,通過引用特殊字符并適當編排非ASCII文本使其作為URL組件安全使用。同時也支持反轉這些操作,以便從URL組件內容重新創建原始數據。
一、urllib.parse.quote
(string,safe=’/’,encoding=None,errors=None)
使用%xx轉義替換string中的特殊字符,其中字母、數字和字符’_.-‘不會進行轉義。默認情況下,此函數用于轉義URL的路徑部分,可選的safe參數指定不應轉義的其他ASCII字符——其默認值為’/’。
特別注意的是若string是bytes,encoding和errors就無法指定,否則報錯TypeError。
二、urllib.parse.unquote
(string,encoding=‘utf-8’,errors=‘replace’)
該函數時quote()
的逆操作,即將%xx轉義為等效的單字符。參數encoding和errors用來指定%xx編碼序列解碼為Unicode字符,同bytes.decode()
方法。
三、urllib.parse.quote_plus
(string,safe=’’,encoding=None,errors=None)
該函數時quote()
的增強版,與之不同的是用+替換空格,而且如果原始URL有字符,那么+將被轉義。
四、urllib.parse.unquote_plus
(string,encoding=‘utf-8’,errors=‘replace’)
類似unquote()
,不再贅述。
五、urllib.parse.urlencode
(query,doseq=False,safe=’’,encoding=None,errors=None,quote_via=quote_plus)
該函數前面提到過,通常在使用HTTP進行POST請求傳遞的數據進行編碼時使用。
robots.txt文件
robotparser
模塊很簡單,僅定義了3個類(RobotFileParser
、RuleLine
、Entry
)。從__all__
屬性來看也就RobotFileParser
一個類(用于處理有關特定用戶代理是否可以發布robots.txt文件的網站上提前網址內容)。
robots文件類似一個協議文件,搜索引擎訪問網站時查看的第一個文件,會告訴爬蟲或者蜘蛛程序在服務器上可以查看什么文件。
RobotFileParser
類有一個url參數,常用以下方法:
set_url():用來設置指向robots.txt文件的網址。
read():讀取robots.txt網址,并將其提供給解析器。
parse():用來解析robots.txt文件。
can_fetch():用來判斷是否可提前url。
mtime():返回上次抓取robots.txt文件的時間。
modified():將上次抓取robots.txt文件的時間設置為當前時間。
以上是“Python中urllib爬蟲、request模塊和parse模塊的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。