Python爬蟲(chóng)庫(kù)urllib的使用教程詳解
Python urllib庫(kù)
Python urllib
庫(kù)用于操作網(wǎng)頁(yè)URL
,并對(duì)網(wǎng)頁(yè)的內(nèi)容進(jìn)行抓取處理。
urllib
包 包含以下幾個(gè)模塊:
urllib.request
- 打開(kāi)和讀取URL
。urllib.error
- 包含urllib.request
拋出的異常。urllib.parse
- 解析URL
。urllib.robotparser
- 解析robots.txt
文件。
需要用的就是每個(gè)模塊的內(nèi)置方法和函數(shù)。大概方法如下圖:
urllib.request模塊
urllib.request
定義了一些打開(kāi)URL
的函數(shù)和類,包含授權(quán)驗(yàn)證、重定向、瀏覽器cookies
等。
urllib.request
可以模擬瀏覽器的一個(gè)請(qǐng)求發(fā)起過(guò)程。
這里主要介紹兩個(gè)常用方法,urlopen
和Request
。
urlopen函數(shù)
語(yǔ)法格式如下:
urllib.request.urlopen(url,?data=None,?[timeout,?]*,?cafile=None,?capath=None,?cadefault=False,?context=None)
url
:url
地址。data
:發(fā)送到服務(wù)器的其他數(shù)據(jù)對(duì)象,默認(rèn)為None
。timeout
:設(shè)置訪問(wèn)超時(shí)時(shí)間。cafile
和capath
:cafile
為CA
證書,capath
為CA
證書的路徑,使用HTTPS
需要用到。cadefault
:已經(jīng)被棄用。context
:ssl.SSLContext
類型,用來(lái)指定SSL
設(shè)置。
示例:
import?urllib.request #導(dǎo)入urllib.request模塊 url=urllib.request.urlopen("https://www.baidu.com") #打開(kāi)讀取baidu信息 print(url.read().decode('utf-8')) #read獲取所有信息,并decode()命令將網(wǎng)頁(yè)的信息進(jìn)行解碼
運(yùn)行結(jié)果
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta content="always" name="
html{color:#000;overflow-y:scroll;overflow:-moz-scrollbars}
body,button,input,select,textarea{font-size:12px;font-family:Arial,sans-serif}
h1,h2,h3,h4,h5,h6{font-size:100%}
em{font-style:normal}
small{font-size:12px}
ol,ul{list-style:none}
a{text-decoration:none}
a:hover{text-decoration:underline}
legend{color:#000}
fieldset,img{border:0}
button,input,select,textarea{font-size:100%}
...
response
對(duì)象是http.client.HTTPResponse
類型,主要包含read
、readinto
、getheader
、getheaders
、fileno
等方法,以及msg
、version
、status
、reason
、debuglevel
、closed
等屬性。
常用方法:
read()
:是讀取整個(gè)網(wǎng)頁(yè)內(nèi)容,也可以指定讀取的長(zhǎng)度,如read(300)
。獲取到的是二進(jìn)制的亂碼,所以需要用到decode()
命令將網(wǎng)頁(yè)的信息進(jìn)行解碼。readline()
: 讀取文件的一行內(nèi)容。readlines()
: 讀取文件的全部?jī)?nèi)容,它會(huì)把讀取的內(nèi)容賦值給一個(gè)列表變量。info()
:返回HTTPMessage
對(duì)象,表示遠(yuǎn)程服務(wù)器返回的頭信息。getcode()
:返回Http
狀態(tài)碼。如果是http
請(qǐng)求,200請(qǐng)求成功完成;404網(wǎng)址未找到。geturl()
:返回請(qǐng)求的鏈接。
Request 類
我們抓取網(wǎng)頁(yè)一般需要對(duì)headers
(網(wǎng)頁(yè)頭信息)進(jìn)行模擬,否則網(wǎng)頁(yè)很容易判定程序?yàn)榕老x(chóng),從而禁止訪問(wèn)。這時(shí)候需要使用到urllib.request.Request
類:
class?urllib.request.Request(url,?data=None,?headers={},?origin_req_host=None,?unverifiable=False,?method=None)
url
:url
地址。data
:發(fā)送到服務(wù)器的其他數(shù)據(jù)對(duì)象,默認(rèn)為None
。headers
:HTTP
請(qǐng)求的頭部信息,字典格式。origin_req_host
:請(qǐng)求的主機(jī)地址,IP
或域名。unverifiable
:很少用整個(gè)參數(shù),用于設(shè)置網(wǎng)頁(yè)是否需要驗(yàn)證,默認(rèn)是False
。method
:請(qǐng)求方法, 如GET
、POST
、DELETE
、PUT
等。
示例:
import?urllib.request #導(dǎo)入模塊 url?=?"https://www.baidu.com" #網(wǎng)頁(yè)連接 headers?=?{ "User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/80.0.3987.122?Safari/537.36" } #定義headers,模擬瀏覽器訪問(wèn) req?=?urllib.request.Request(url=url,headers=headers) #模擬瀏覽器發(fā)送,訪問(wèn)網(wǎng)頁(yè) response?=?urllib.request.urlopen(req) #獲取頁(yè)面信息 print(response.read().decode("utf-8"))
urllib.error模塊
urllib.error
模塊為urllib.request
所引發(fā)的異常定義了異常類,基礎(chǔ)異常類是URLError
。
urllib.error
包含了兩個(gè)方法,URLError
和HTTPError
。
URLError
是OSError
的一個(gè)子類,用于處理程序在遇到問(wèn)題時(shí)會(huì)引發(fā)此異常(或其派生的異常),包含的屬性reason
為引發(fā)異常的原因。
HTTPError
是URLError
的一個(gè)子類,用于處理特殊HTTP
錯(cuò)誤例如作為認(rèn)證請(qǐng)求的時(shí)候,包含的屬性code
為HTTP
的狀態(tài)碼,reason
為引發(fā)異常的原因,headers
為導(dǎo)致HTTPError
的特定HTTP
請(qǐng)求的HTTP
響應(yīng)頭。
區(qū)別:
URLError
封裝的錯(cuò)誤信息一般是由網(wǎng)絡(luò)引起的,包括url
錯(cuò)誤。HTTPError
封裝的錯(cuò)誤信息一般是服務(wù)器返回了錯(cuò)誤狀態(tài)碼。
關(guān)系:
URLError
是OSERROR
的子類,HTTPError
是URLError
的子類。
URLError 示例
from?urllib?import?request from?urllib?import?error if?__name__?==?"__main__": ????#一個(gè)不存在的連接 ????url?=?"http://www.baiiiduuuu.com/" ????req?=?request.Request(url) ????try: ????????response?=?request.urlopen(req) ????????html?=?response.read().decode('utf-8') ????????print(html) ????except?error.URLError?as?e: ????????print(e.reason)
返回結(jié)果
[Errno -2] Name or service not known
此錯(cuò)誤的原因。它可以是一個(gè)消息字符串或另一個(gè)異常實(shí)例。
HTTPError示例
from?urllib?import?request from?urllib?import?error if?__name__?==?"__main__": ????#網(wǎng)站服務(wù)器上不存在資源 ????url?=?"http://www.baidu.com/no.html" ????req?=?request.Request(url) ????try: ????????response?=?request.urlopen(req) ????????html?=?response.read().decode('utf-8') ????????print(html) ????except?error.HTTPError?as?e: ????????print(e.code)
output
404
URLError和HTTPError混合使用
注意:由于HTTPError
是URLError
的子類,所以捕獲的時(shí)候HTTPError
要放在URLError
的上面。
示例:
from?urllib?import?request from?urllib?import?error if?__name__?==?"__main__": ????#網(wǎng)站服務(wù)器上不存在資源 ????url?=?"http://www.baidu.com/no.html" ????req?=?request.Request(url) ????try: ????????response?=?request.urlopen(req) ?#???????html?=?response.read().decode('utf-8') ????except?error.HTTPError?as?e: ????????print(e.code) ????except?error.URLError?as?e: ????????print(e.code)
如果不用上面的方法,可以直接用判斷的形式
from?urllib?import?request from?urllib?import?error if?__name__?==?"__main__": ????#網(wǎng)站服務(wù)器上不存在資源 ????url?=?"http://www.baidu.com/no.html" ????req?=?request.Request(url) ????try: ????????response?=?request.urlopen(req) ?#???????html?=?response.read().decode('utf-8') ????except?error.URLError?as?e: ????????if?hasattr(e,?'code'): ????????????print("HTTPError") ????????????print(e.code) ????????elif?hasattr(e,?'reason'): ????????????print("URLError") ????????????print(e.reason)
output
HTTPError
404
urllib.parse模塊
模塊定義的函數(shù)可分為兩個(gè)主要門類:URL
解析和URL
轉(zhuǎn)碼。
urlparse()
urllib.parse
用于解析URL
,格式如下:
urllib.parse.urlparse(urlstring,?scheme='',?allow_fragments=True)
urlstring
為字符串的url
地址,scheme
為協(xié)議類型。
allow_fragments
參數(shù)為false
,則無(wú)法識(shí)別片段標(biāo)識(shí)符。相反,它們被解析為路徑,參數(shù)或查詢組件的一部分,并fragment
在返回值中設(shè)置為空字符串。
標(biāo)準(zhǔn)鏈接格式為:
scheme://netloc/path;params?query#fragment
對(duì)象中包含了六個(gè)元素,分別為:協(xié)議(scheme)、域名(netloc)、路徑(path)、路徑參數(shù)(params)、查詢參數(shù)(query)、片段(fragment)。
示例:
from?urllib.parse?import?urlparse o?=?urlparse("https://docs.python.org/zh-cn/3/library/urllib.parse.html#module-urllib.parse") print('scheme??:',?o.scheme) print('netloc??:',?o.netloc) print('path????:',?o.path) print('params??:',?o.params) print('query???:',?o.query) print('fragment:',?o.fragment) print('hostname:',?o.hostname)
output
scheme : https
netloc : docs.python.org
path : /zh-cn/3/library/urllib.parse.html
params :
query :
fragment: module-urllib.parse
hostname: docs.python.org
以上還可以通過(guò)索引獲取,如通過(guò)
print(o[0]) ... print(o[5])
urlunparse()
urlunparse()
可以實(shí)現(xiàn)URL
的構(gòu)造。(構(gòu)造URL
)
urlunparse()
接收一個(gè)是一個(gè)長(zhǎng)度為6的可迭代對(duì)象,將URL
的多個(gè)部分組合為一個(gè)URL
。若可迭代對(duì)象長(zhǎng)度不等于6,則拋出異常。
示例:
from?urllib.parse?import?urlunparse url_compos?=?['http','www.baidu.com','index.html','user=?test','a=6','comment'] print(urlunparse(url_compos))
output
http://www.baidu.com/index.html;user= test?a=6#comment
urlsplit()
urlsplit()
函數(shù)也能對(duì) URL
進(jìn)行拆分,所不同的是,urlsplit()
并不會(huì)把 路徑參數(shù)(params) 從 路徑(path) 中分離出來(lái)。
當(dāng)URL
中路徑部分包含多個(gè)參數(shù)時(shí),使用urlparse()
解析是有問(wèn)題的,這時(shí)可以使用urlsplit()
來(lái)解析.
urlunsplit()
與urlunparse()
類似,(構(gòu)造URL
),傳入對(duì)象必須是可迭代對(duì)象,且長(zhǎng)度必須是5。
示例:
from?urllib.parse?import?urlunsplit url_compos?=?['http','www.baidu.com','index.html','user=?test','a?=?2'] print(urlunsplit(url_compos))urlunsplit()
output
http://www.baidu.com/index.html?user= test#a = 2
urljoin()
同樣可以構(gòu)造URL
。
傳遞一個(gè)基礎(chǔ)鏈接,根據(jù)基礎(chǔ)鏈接可以將某一個(gè)不完整的鏈接拼接為一個(gè)完整鏈接.
注:連接兩個(gè)參數(shù)的url
, 將第二個(gè)參數(shù)中缺的部分用第一個(gè)參數(shù)的補(bǔ)齊,如果第二個(gè)有完整的路徑,則以第二個(gè)為主。
URL 轉(zhuǎn)碼
python
中提供urllib.parse
模塊用來(lái)編碼和解碼,分別是urlencode()
與unquote()
。
編碼quote(string)
URL
轉(zhuǎn)碼函數(shù)的功能是接收程序數(shù)據(jù)并通過(guò)對(duì)特殊字符進(jìn)行轉(zhuǎn)碼并正確編碼非ASCII
文本來(lái)將其轉(zhuǎn)為可以安全地用作URL
組成部分的形式。它們還支持逆轉(zhuǎn)此操作以便從作為URL
組成部分的內(nèi)容中重建原始數(shù)據(jù),如果上述的URL
解析函數(shù)還未覆蓋此功能的話
語(yǔ)法:
urllib.parse.quote(string,?safe='/',?encoding=None,?errors=None)
使用%xx
轉(zhuǎn)義符替換string
中的特殊字符。字母、數(shù)字和 '_.-~' 等字符一定不會(huì)被轉(zhuǎn)碼。在默認(rèn)情況下,此函數(shù)只對(duì)URL
的路徑部分進(jìn)行轉(zhuǎn)碼??蛇x的safe
形參額外指定不應(yīng)被轉(zhuǎn)碼的ASCII
字符 --- 其默認(rèn)值為 '/'。
string
可以是str
或bytes
對(duì)象。
示例:
from?urllib?import?parse url?=?"http://www.baidu.com/s?wd={}" words?=?"爬蟲(chóng)" #quote()只能對(duì)字符串進(jìn)行編碼 query_string?=?parse.quote(words) url?=?url.format(query_string) print(url)
執(zhí)行結(jié)果:
http://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB
編碼urlencode()
quote()
只能對(duì)字符串編碼,而urlencode()
可以對(duì)查詢字符串進(jìn)行編碼。
#?導(dǎo)入parse模塊 from?urllib?import?parse #調(diào)用parse模塊的urlencode()進(jìn)行編碼 query_string?=?{'wd':'爬蟲(chóng)'} result?=?parse.urlencode(query_string) #?format函數(shù)格式化字符串,進(jìn)行url拼接 url?=?'http://www.baidu.com/s?{}'.format(result) print(url)
output
http://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB
解碼 unquote(string)
解碼就是對(duì)編碼后的url
進(jìn)行還原。
示例:
from?urllib?import?parse string?=?'%E7%88%AC%E8%99%AB' result?=?parse.unquote(string) print(result)
執(zhí)行結(jié)果:
爬蟲(chóng)
urllib.robotparser模塊
(在網(wǎng)絡(luò)爬蟲(chóng)中基本不會(huì)用到,使用較少,僅作了解)
urllib.robotparser
用于解析robots.txt
文件。
robots.txt
(統(tǒng)一小寫)是一種存放于網(wǎng)站根目錄下的robots
協(xié)議,它通常用于告訴搜索引擎對(duì)網(wǎng)站的抓取規(guī)則。
Robots
協(xié)議也稱作爬蟲(chóng)協(xié)議,機(jī)器人協(xié)議,網(wǎng)絡(luò)爬蟲(chóng)排除協(xié)議,用來(lái)告訴爬蟲(chóng)哪些頁(yè)面是可以爬取的,哪些頁(yè)面是不可爬取的。它通常是一個(gè)robots.txt
的文本文件,一般放在網(wǎng)站的根目錄上。
當(dāng)爬蟲(chóng)訪問(wèn)一個(gè)站點(diǎn)的時(shí)候,會(huì)首先檢查這個(gè)站點(diǎn)目錄是否存在robots.txt
文件,如果存在,搜索爬蟲(chóng)會(huì)根據(jù)其中定義的爬取范圍進(jìn)行爬取。如果沒(méi)有找到這個(gè)文件,搜索爬蟲(chóng)會(huì)訪問(wèn)所有可直接訪問(wèn)的頁(yè)面。
urllib.robotparser
提供了RobotFileParser
類,語(yǔ)法如下:
class?urllib.robotparser.RobotFileParser(url='')
這個(gè)類提供了一些可以讀取、解析robots.txt
文件的方法:
set_url(url)
- 設(shè)置robots.txt
文件的URL
。read()
- 讀取robots.txt URL
并將其輸入解析器。parse(lines)
- 解析行參數(shù)。can_fetch(useragent, url)
- 如果允許useragent
按照被解析robots.txt
文件中的規(guī)則來(lái)獲取url
則返回True
。mtime()
- 返回最近一次獲取robots.txt
文件的時(shí)間。這適用于需要定期檢查robots.txt
文件更新情況的長(zhǎng)時(shí)間運(yùn)行的網(wǎng)頁(yè)爬蟲(chóng)。modified()
- 將最近一次獲取robots.txt
文件的時(shí)間設(shè)置為當(dāng)前時(shí)間。crawl_delay(useragent)
- 為指定的useragent
從robots.txt
返回Crawl-delay
形參。如果此形參不存在或不適用于指定的useragent
或者此形參的robots.txt
條目存在語(yǔ)法錯(cuò)誤,則返回None
。request_rate(useragent)
-以named tuple RequestRate(requests, seconds)
的形式從robots.txt
返回Request-rate
形參的內(nèi)容。如果此形參不存在或不適用于指定的useragent
或者此形參的robots.txt
條目存在語(yǔ)法錯(cuò)誤,則返回None
。site_maps()
- 以list()
的形式從robots.txt
返回Sitemap
形參的內(nèi)容。如果此形參不存在或者此形參的robots.txt
條目存在語(yǔ)法錯(cuò)誤,則返回None
。
以上就是Python爬蟲(chóng)庫(kù)urllib的使用教程詳解的詳細(xì)內(nèi)容,更多關(guān)于Python爬蟲(chóng)庫(kù)urllib的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python中的List sort()與torch.sort()
這篇文章主要介紹了python中的List sort()與torch.sort()使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09Python2.5/2.6實(shí)用教程 入門基礎(chǔ)篇
本文方便有經(jīng)驗(yàn)的程序員進(jìn)入Python世界.本文適用于python2.5/2.6版本.2009-11-11Python matplotlib學(xué)習(xí)筆記之坐標(biāo)軸范圍
這篇文章主要介紹了Python matplotlib學(xué)習(xí)筆記之坐標(biāo)軸范圍,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06解決pycharm py文件運(yùn)行后停止按鈕變成了灰色的問(wèn)題
今天小編就為大家分享一篇解決pycharm py文件運(yùn)行后停止按鈕變成了灰色的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11使用Pandas解決對(duì)比兩列數(shù)據(jù)取最大值
Pandas庫(kù)作為Python中數(shù)據(jù)處理和分析的強(qiáng)大工具,提供了多種靈活的方法來(lái)實(shí)現(xiàn)這一需求,本文將詳細(xì)介紹五種使用Pandas對(duì)比兩列數(shù)據(jù)并取最大值的方法,需要的可以參考下2024-04-04Python判斷兩個(gè)list是否是父子集關(guān)系的實(shí)例
今天小編就為大家分享一篇Python判斷兩個(gè)list是否是父子集關(guān)系的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05Python?Pandas實(shí)現(xiàn)將嵌套JSON數(shù)據(jù)轉(zhuǎn)換DataFrame
對(duì)于復(fù)雜的JSON數(shù)據(jù)進(jìn)行分析時(shí),通常的做法是將JSON數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為Pandas?DataFrame,所以本文就來(lái)看看將嵌套JSON數(shù)據(jù)轉(zhuǎn)換為Pandas?DataFrame的具體方法吧2024-01-01