首頁 > 軟體

Python爬蟲庫urllib的使用教學詳解

2022-11-21 14:01:24

Python urllib庫

Python urllib庫用於操作網頁URL,並對網頁的內容進行抓取處理。

urllib包 包含以下幾個模組:

  • urllib.request - 開啟和讀取URL
  • urllib.error - 包含urllib.request丟擲的異常。
  • urllib.parse - 解析URL
  • urllib.robotparser - 解析robots.txt檔案。

需要用的就是每個模組的內建方法和函數。大概方法如下圖:

urllib.request模組

urllib.request定義了一些開啟URL的函數和類,包含授權驗證、重定向、瀏覽器cookies等。

urllib.request可以模擬瀏覽器的一個請求發起過程。

這裡主要介紹兩個常用方法,urlopenRequest

urlopen函數

語法格式如下:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
  • urlurl地址。
  • data:傳送到伺服器的其他資料物件,預設為None
  • timeout:設定存取超時時間。
  • cafile 和 capathcafileCA證書,capathCA證書的路徑,使用HTTPS需要用到。
  • cadefault:已經被棄用。
  • contextssl.SSLContext型別,用來指定SSL設定。

範例:

import urllib.request
#匯入urllib.request模組
url=urllib.request.urlopen("https://www.baidu.com")
#開啟讀取baidu資訊
print(url.read().decode('utf-8'))
#read獲取所有資訊,並decode()命令將網頁的資訊進行解碼

執行結果

<!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物件是http.client.HTTPResponse型別,主要包含readreadintogetheadergetheadersfileno等方法,以及msgversionstatusreasondebuglevelclosed等屬性。

常用方法:

  • read():是讀取整個網頁內容,也可以指定讀取的長度,如read(300)。獲取到的是二進位制的亂碼,所以需要用到decode()命令將網頁的資訊進行解碼。
  • readline(): 讀取檔案的一行內容。
  • readlines(): 讀取檔案的全部內容,它會把讀取的內容賦值給一個列表變數。
  • info():返回HTTPMessage物件,表示遠端伺服器返回的頭資訊。
  • getcode():返回Http狀態碼。如果是http請求,200請求成功完成;404網址未找到。
  • geturl():返回請求的連結。

Request 類

我們抓取網頁一般需要對headers(網頁頭資訊)進行模擬,否則網頁很容易判定程式為爬蟲,從而禁止存取。這時候需要使用到urllib.request.Request類:

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
  • urlurl地址。
  • data:傳送到伺服器的其他資料物件,預設為None
  • headersHTTP請求的頭部資訊,字典格式。
  • origin_req_host:請求的主機地址,IP或域名。
  • unverifiable:很少用整個引數,用於設定網頁是否需要驗證,預設是False
  • method:請求方法, 如 GETPOSTDELETEPUT等。

範例:

import urllib.request
#匯入模組
url = "https://www.baidu.com"
#網頁連線
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,模擬瀏覽器存取
req = urllib.request.Request(url=url,headers=headers)
#模擬瀏覽器傳送,存取網頁
response = urllib.request.urlopen(req)
#獲取頁面資訊
print(response.read().decode("utf-8"))

urllib.error模組

urllib.error模組為urllib.request所引發的異常定義了異常類,基礎異常類是URLError

urllib.error包含了兩個方法,URLErrorHTTPError

URLErrorOSError的一個子類,用於處理程式在遇到問題時會引發此異常(或其派生的異常),包含的屬性reason為引發異常的原因。

HTTPErrorURLError的一個子類,用於處理特殊HTTP錯誤例如作為認證請求的時候,包含的屬性codeHTTP的狀態碼,reason為引發異常的原因,headers為導致HTTPError的特定HTTP請求的HTTP響應頭。

區別:

  • URLError封裝的錯誤資訊一般是由網路引起的,包括url錯誤。
  • HTTPError封裝的錯誤資訊一般是伺服器返回了錯誤狀態碼。

關係:

URLErrorOSERROR的子類,HTTPErrorURLError的子類。

URLError 範例

from urllib import request
from urllib import error

if __name__ == "__main__":
    #一個不存在的連線
    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)

返回結果

[Errno -2] Name or service not known

此錯誤的原因。它可以是一個訊息字串或另一個異常範例。

HTTPError範例

from urllib import request
from urllib import error

if __name__ == "__main__":
    #網站伺服器上不存在資源
    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混合使用

注意:由於HTTPErrorURLError的子類,所以捕獲的時候HTTPError要放在URLError的上面。

範例:

from urllib import request
from urllib import error

if __name__ == "__main__":
    #網站伺服器上不存在資源
    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__":
    #網站伺服器上不存在資源
    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模組

模組定義的函數可分為兩個主要門類:URL解析和URL轉碼。

urlparse()

urllib.parse用於解析URL,格式如下:

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

urlstring為字串的url地址,scheme為協定型別。

allow_fragments引數為false,則無法識別片段識別符號。相反,它們被解析為路徑,引數或查詢元件的一部分,並fragment在返回值中設定為空字串。

標準連結格式為:

scheme://netloc/path;params?query#fragment

物件中包含了六個元素,分別為:協定(scheme)、域名(netloc)、路徑(path)、路徑引數(params)、查詢引數(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

以上還可以通過索引獲取,如通過

print(o[0])
...
print(o[5])

urlunparse()

urlunparse()可以實現URL的構造。(構造URL

urlunparse()接收一個是一個長度為6的可迭代物件,將URL的多個部分組合為一個URL。若可迭代物件長度不等於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()函數也能對 URL進行拆分,所不同的是,urlsplit()並不會把 路徑引數(params) 從 路徑(path) 中分離出來。

URL中路徑部分包含多個引數時,使用urlparse()解析是有問題的,這時可以使用urlsplit()來解析.

urlunsplit()urlunparse()類似,(構造URL),傳入物件必須是可迭代物件,且長度必須是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()

同樣可以構造URL

傳遞一個基礎連結,根據基礎連結可以將某一個不完整的連結拼接為一個完整連結.

注:連線兩個引數的url, 將第二個引數中缺的部分用第一個引數的補齊,如果第二個有完整的路徑,則以第二個為主。

URL 轉碼

python中提供urllib.parse模組用來編碼和解碼,分別是urlencode()unquote()

編碼quote(string)

URL轉碼函數的功能是接收程式資料並通過對特殊字元進行轉碼並正確編碼非ASCII文字來將其轉為可以安全地用作URL組成部分的形式。它們還支援逆轉此操作以便從作為URL組成部分的內容中重建原始資料,如果上述的URL解析函數還未覆蓋此功能的話

語法:

urllib.parse.quote(string, safe='/', encoding=None, errors=None)

使用%xx跳脫符替換string中的特殊字元。字母、數位和 '_.-~' 等字元一定不會被轉碼。在預設情況下,此函數只對URL的路徑部分進行轉碼。可選的safe形參額外指定不應被轉碼的ASCII字元 --- 其預設值為 '/'。

string可以是strbytes物件。

範例:

from urllib import parse

url = "http://www.baidu.com/s?wd={}"
words = "爬蟲"

#quote()只能對字串進行編碼
query_string = parse.quote(words)
url = url.format(query_string)
print(url)

執行結果:

http://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB

編碼urlencode()

quote()只能對字串編碼,而urlencode()可以對查詢字串進行編碼。

# 匯入parse模組
from urllib import parse

#呼叫parse模組的urlencode()進行編碼
query_string = {'wd':'爬蟲'}
result = parse.urlencode(query_string)

# format函數格式化字串,進行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)

解碼就是對編碼後的url進行還原。

範例:

from urllib import parse
string = '%E7%88%AC%E8%99%AB'
result = parse.unquote(string)
print(result)

執行結果:

爬蟲

urllib.robotparser模組

(在網路爬蟲中基本不會用到,使用較少,僅作了解)

urllib.robotparser用於解析robots.txt檔案。

robots.txt(統一小寫)是一種存放於網站根目錄下的robots協定,它通常用於告訴搜尋引擎對網站的抓取規則。

Robots協定也稱作爬蟲協定,機器人協定,網路爬蟲排除協定,用來告訴爬蟲哪些頁面是可以爬取的,哪些頁面是不可爬取的。它通常是一個robots.txt的文字檔案,一般放在網站的根目錄上。

當爬蟲存取一個站點的時候,會首先檢查這個站點目錄是否存在robots.txt檔案,如果存在,搜尋爬蟲會根據其中定義的爬取範圍進行爬取。如果沒有找到這個檔案,搜尋爬蟲會存取所有可直接存取的頁面。

urllib.robotparser提供了RobotFileParser類,語法如下:

class urllib.robotparser.RobotFileParser(url='')

這個類提供了一些可以讀取、解析robots.txt檔案的方法:

  • set_url(url) - 設定robots.txt檔案的URL
  • read() - 讀取robots.txt URL並將其輸入解析器。
  • parse(lines) - 解析行引數。
  • can_fetch(useragent, url) - 如果允許useragent按照被解析robots.txt檔案中的規則來獲取url則返回True
  • mtime() - 返回最近一次獲取robots.txt檔案的時間。這適用於需要定期檢查robots.txt檔案更新情況的長時間執行的網頁爬蟲。
  • modified() - 將最近一次獲取robots.txt檔案的時間設定為當前時間。
  • crawl_delay(useragent) - 為指定的useragentrobots.txt 返回Crawl-delay形參。如果此形參不存在或不適用於指定的useragent 或者此形參的robots.txt條目存在語法錯誤,則返回None
  • request_rate(useragent) -以 named tuple RequestRate(requests, seconds)的形式從robots.txt返回Request-rate形參的內容。如果此形參不存在或不適用於指定的useragent或者此形參的robots.txt條目存在語法錯誤,則返回None
  • site_maps() - 以list()的形式從robots.txt返回Sitemap形參的內容。如果此形參不存在或者此形參的robots.txt條目存在語法錯誤,則返回None

以上就是Python爬蟲庫urllib的使用教學詳解的詳細內容,更多關於Python爬蟲庫urllib的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com