1. 程式人生 > 程式設計 >python3 中使用urllib問題以及urllib詳解

python3 中使用urllib問題以及urllib詳解

今天遇到一個蠻奇怪的問題:當我在控制檯中使用 urllib 沒問題,但是當我在 vscode 中 .py 檔案中匯入 urllib 使用時會報錯:

AttributeError: module 'urllib' has no attribute 'request'

查了一下資料是 python3 的 urllib 不會自動匯入其under層的包,需要手動匯入。

import urllib
import urllib.parse
import urllib.request

再次使用即可成功。

urllibe 是 python3 中將中文 urlencode 編碼使用的函式,urlencode 使用如下:

import urllib
import urllib.parse

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

urllib 將編碼後的字串轉為中文則使用:

import urllib
import urllib.parse

urllib.parse.unquote(string,encoding='utf-8',errors='replace')

聊到這裡就順帶講講 urllibe 的使用吧

urllib 是一個 python 內建包,不需要額外安裝即可使用,它包含一下幾個用來處理 url 的模版。

  • urllib.request,用來開啟和讀取 url,意思就是可以用它來模擬傳送請求,就像在瀏覽器裡輸入網址然後敲擊回車一樣,獲取網頁響應內容。
  • urllib.error,用來處理 urllib.request 引起的異常,保證程式的正常執行。
  • urllib.parse,用來解析 url,可以對 url 進行拆分、合併等。
  • urllib.robotparse,用來解析 robots.txt 檔案,判斷網站是否能夠進行爬取。

urllib.request 模組

urllib.request 模組定義了以下幾個函式。

urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None)

該函式主要用於模擬網站請求,返回一個 HTTPResponse 型別的物件。

urlopen 函式中引數定義

  • url,必選引數,是一個 str 字串或者 Request 物件(後面會介紹)。
  • data,bytes 型別的可選引數,如果傳遞的是字典型資料,可以用 urllib.parse.urlencode() 進行編碼,返回 str 字串,再將 str 轉換成 bytes 位元組流。如果傳遞 data 引數,urlopen 將使用 HTTP POST 方式請求,否則為 HTTP GET 請求。
  • timeout,可選引數,設定超時時間(未設定時使用全域性預設超時時間),以秒為單位計時,如果 urlopen 請求超出了設定時間還未得到響應則丟擲異常。
  • cafile 和 capath,可選引數,在 HTTPS 連線請求時指定已認證的 CA 證書以及證書路徑。
  • cadefault,一般可忽略該引數。
  • context,ssl.SSLContext 型別的可選引數,用來指定 SSL 設定。

urlopen 函式返回型別

urlopen 函式請求返回一個 HTTPResponse 響應上下文,或者請求異常丟擲 URLError 協議錯誤,一般有如下屬性:

  • geturl(),返回檢索的 url,通常用於判定是否進行了重定向。
  • info(),返回網頁的頭資訊。
  • getcode(),返回 HTTPResponse 響應的狀態碼。

urlopen 函式的應用例項

# 建立一個 HTTP GET 請求,輸出響應上下文
from urllib.request import urlopen
response = urlopen("http://www.python.org")
print(response.read())

# 建立一個 HTTP POST 請求,輸出響應上下文
from urllib.request import urlopen
from urllib.parse import urlencode
data = {'kw' : 'python'}
data = bytes(urlencode(data),encoding = 'utf-8')
response = urlopen("https://fanyi.baidu.com/sug",data)
print(response.read().decode('unicode_escape'))

urllib.request.Request(url,headers={},origin_req_host=None,unverifiable=False,method=None)

該函式主要用於構造一個 url,返回一個 urllib.request.Request 物件。

Request 函式中引數定義

  • url,必選引數,請求的 url 地址。
  • data,bytes 型別的可選引數。
  • headers,字典型別,有些 HTTP 伺服器僅允許來自瀏覽器的請求,因此通過 headers 來模擬瀏覽器對 url 的訪問,比如模擬谷歌瀏覽器時使用的 headers:”Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/76.0.3809.132 Safari/537.36”。可以通過呼叫 add_header() 來新增 headers 資訊。
  • origin_req_host,請求方的 host 名稱或者 IP 地址。
  • unverifiable,表示這個請求是否無法驗證,預設為 False。比如請求一張圖片,如果沒有許可權獲取圖片那它的值就是 true。
  • method,是一個字串,用來指示請求使用的方法,如:GET,POST,PUT 等,預設是 GET 請求。

Request 函式返回型別

與 urlopen 函式請求返回一樣,一般返回一個 HTTPResponse 響應上下文。

Request 函式的應用例項

# 採用 HTTP GET 請求的方法模擬谷歌瀏覽器訪問網站,輸出響應上下文
from urllib import request,parse
url = 'http://www.python.org'
headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
req = request.Request(url,headers = headers,method = 'GET')
response = request.urlopen(req)
print(response.read())

2 urllib.error 模組

urllib.error 模組定義了由 urllib.request 模組引發的異常,異常主要包含 URLError 和 HTTPError。

urllib.error.URLError 異常

URLError 類繼承自 OSError 類,是 error 異常模組的基類,由request模組產生的異常都可以通過捕獲這個類來處理。URLError 只有一個屬性 reason,即返回錯誤的原因。

應用例項:

# 在請求連線時候捕獲網址錯誤引發的異常
from urllib import request,error
try: response = request.urlopen('https://www,baidu,com')
except error.URLError as e: print(e.reason)

urllib.error.HTTPError 異常

HTTPError 是 URLError 的子類,專門用來處理 HTTP 請求錯誤,比如認證請求失敗,包含以下三個屬性:

  • code:返回 HTTP 響應的狀態碼,如404頁面不存在等。
  • reason:返回錯誤的原因。
  • headers:返回 HTTP 響應頭資訊。

應用舉例:

# 返回401未授權錯誤
from urllib import request,error
try: response=request.urlopen('http://pythonscraping.com/pages/auth/login.php') print(response.getcode())
except error.HTTPError as e: print('1.錯誤原因:\n%s\n2.狀態碼:\n%s\n3.響應頭資訊:\n%s' %(e.reason,e.code,e.headers))
except error.URLError as e: print(e.reason)

urllib.parse 模組

urllib.parse 模組定義了一個處理 url 的標準介面,用來實現 url 字串的抽取、合併以及連結轉換。該模組主要用到的函式如下。

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

用於實現 url 字串的識別和分段,可以分為六個字串,分別是 scheme (協議),netloc (域名),path (路徑),params (引數),query (查詢條件)和 fragment (錨點),其結構如下所示:“scheme://netloc/path;parameters?query#fragment”。實際上具體 url 某些欄位可能會不存在,比如 “http://www.baidu.com” 只包含了協議和域名。

urlparse 函式中引數定義

  • urlstring,待解析的 url 字串。
  • scheme,是預設的協議,比如 http 或者 https,url 字串中如果不攜帶相關協議,可以通過 scheme 來指定,如果 url 中指定了相關協議則在 url 中生效。
  • allow_fragments,是否忽略錨點,設定為 False 即 fragment 部分會被忽略,反之不會忽略。

urlparse 的返回型別

函式返回的是一個 urllib.parse.ParseResult 物件,獲取解析出來的 url 六個欄位。

urlparse 應用舉例

# 解析並輸出 url 中每個欄位的字串
import urllib
url = 'http://www.baidu.com/urllib.parse.html;python?kw=urllib.parse#module-urllib'
result = urllib.parse.urlparse(url)
print(result)
print(result.scheme,result.netloc,result.path,result.params,result.query,result.fragment,sep = '\n')

urllib.parse.urlunparse(parts)

與 urlparse 相反,通過列表或者元祖的形式將分段的字串組合成一個完整的 url 字串。

urlunparse 函式中引數定義

parts,可以是列表或者元組。

urlunparse 的返回型別

urlunparse 函式返回一個構造好的 url 字串。

應用舉例

# 通過 data 列表或元組構造一個 url 並輸出
import urllib
dataList = ['http','www.baidu.com','/urllib.parse.html','python','kw=urllib.parse','modul-urllib'] # 六個字串都必須填寫,否則會出現 ValueError 錯誤,如果某一字串不存在則填入空字元
dataTuple = ('http','','modul-urllib') # 六個字串都必須填寫,否則會出現 ValueError 錯誤,如果某一字串不存在則填入空字元
urlList = urllib.parse.urlunparse(dataList)
urlTuple = urllib.parse.urlunparse(dataTuple)
print('1.urlList:%s\n2.urlTuple:%s' % (urlList,urlTuple))

urllib.parse.urlsplit(urlstring,allow_fragments=True)

與 urlparse 函式類似,但它只返回 url 字串的5個欄位,把 params 合併到 path 中。

urlsplit 應用舉例

# 解析並輸出 url 中每個欄位的字串,params 會合併到 path 中。
import urllib
url = 'http://www.baidu.com/urllib.parse.html;python?kw=urllib.parse#modul-urllib'
result = urllib.parse.urlsplit(url)
print(result)
print(result.scheme,sep = '\n')

urllib.parse.urlunsplit(parts)

與 urlunparse 函式類似,它也是將 url 中各部分欄位組合完整的 url 字串的方法,唯一的區別是列表或元組的長度必須是5個,因為它把 params 省略了。

urlunsplit 應用舉例

# 通過 data 列表或元組構造一個 url 並輸出
import urllib
dataList = ['http','/urllib.parse.html;python','modul-urllib'] # 五個字串都必須填寫,否則會出現 ValueError 錯誤,如果某一字串不存在則填入空字元
dataTuple = ('http','modul-urllib') # 五個字串都必須填寫,否則會出現 ValueError 錯誤,如果某一字串不存在則填入空字元
urlList = urllib.parse.urlunsplit(dataList)
urlTuple = urllib.parse.urlunsplit(dataTuple)
print('1.urlList:%s\n2.urlTuple:%s' % (urlList,urlTuple))

urllib.parse.quote(string,errors=None)

使用 %xx 轉義字元替換字串中的特殊字元,比如漢字。字母、數字和‘_.-~'字元不會被替換。

quote 函式中引數定義

  • string,可以是 str 字串或 bytes 型別。
  • safe,可選引數,預設是'/',指明不應該被替換的附加 ASCII 字元。
  • encoding 和 errors,可選引數,用來定義如何處理 non-ASCII 字元。一般預設設定編碼方法為 encoding='utf-8',errors='strict',這意味著編碼錯誤將引發 UnicodeError。如果 string 是 bytes 型別,不能設定 encoding 和 errors,否則將引發 TypeError。

quote 函式的返回型別

quote 函式返回一個編碼後的字串。

應用舉例

# 採用 quote 對 url 中的漢字進行編碼,輸出編碼後的結果
import urllib
url = 'http://www.baidu.com/爬蟲'
result = urllib.parse.quote(url)
print(result)
url = 'http://www.baidu.com/+爬蟲'
result = urllib.parse.quote(url,'+') # 更改 safe 引數
print(result)

urllib.parse.unquote(string,errors='replace')

與 quote 函式相反,把 %xx 轉義字元替換成字元。

  • unquote 函式的引數定義
  • string,必須是 str 字串。
  • encoding 和 errors,可選引數,定義如何將 %xx 轉義字元解碼為 Unicode 字元。encoding 預設為 ‘utf-8',errors 預設為 ‘replace',表示無效的轉義字元將會用佔位符替換。

unquote 函式的返回型別

unquote 函式返回一個解碼後的字串。

應用舉例

# 解碼經過 quote 函式處理後的 url,輸出解碼後的結果。
import urllib
url = 'http://www.baidu.com/爬蟲'
result = urllib.parse.quote(url)
print(result)
result = urllib.parse.unquote(url)
print(result)

urllib.parse.urljoin(base,url,allow_fragments=True)

該函式用來將基本 url 與另一個 url 組合,更新基本 url 字串。它會使用 url 對基本 url 中缺失的部分進行補充,比如 scheme (協議)、netloc (域名)和 path (路徑)。即根據 url 字串中帶有的欄位,對基本 url 中沒有的欄位進行補充,已存在的欄位進行替換。

  • urljoin 函式中引數定義
  • base,是一個基本 url。
  • url,將 scheme (協議)、netloc (域名)或 path (路徑)欄位組合進基本 url 的 url。
  • allow_fragments,是否忽略錨點,設定為 False 即 fragment 部分會被忽略,反之不會忽略。

urljoin 函式返回型別

返回組合成功的 url 字串。

應用舉例

# 基於 url 對 base_url 進行重新組合,並輸出組合結果。
import urllib
base_url = 'http://www.baidu.com'
url = 'https://www.google.com/urllib.parse.html;python?kw=urllib.parse#module-urllib'
result = urllib.parse.urljoin(base_url,False)
print(result)

urllib.parse.urlencode(query,doseq=False,safe='',errors=None,quote_via=quote_plus)

urlencode 函式可以將字典轉化為 GET 請求中的 query (查詢條件),或者將字典轉化為 POST 請求中需要上傳的資料。

  • urlencode 函式中引數定義
  • query,字典型別。
  • doseq,允許字典中一個鍵對應多個值,編碼成 query (查詢條件)。
  • safe、encoding 和 errors,這三個引數由 quote_via 指定。

urlencode 函式返回型別

urlencode 函式返回 str 字串。

應用舉例

# 建立 GET 請求
import urllib
params = {'username':'xxx','password':'123'}
base_url='http://www.baidu.com'
url=base_url + '?' + urllib.parse.urlencode(params)
print(url)
params = {'username':['xxx','yyy'],'password':'123'} # username 鍵對應多個值
base_url='http://www.baidu.com'
url=base_url + '?' + urllib.parse.urlencode(params) # doseq 設定為 False,會解析成亂碼
print(url)
url=base_url + '?' + urllib.parse.urlencode(params,True) # doseq 設定為 True
print(url)

urllib.robotparse 模組

rebotparser 模組提供了一個 RobotFileParser 類,主要用來解析網站上釋出的 robots.txt,然後根據解析內容判斷爬蟲是否有許可權來爬取這個網頁。

robots.txt 檔案

robots.txt,存放於網站根目錄下,採用 ASCII 編碼的文字檔案,記錄此網站中的哪些內容是不應被爬蟲獲取的,哪些是可以被爬蟲獲取的。

robots.txt 檔案內容舉例

User-agent: * Disallow: / Allow: /public/

  • User-agent,爬蟲的名稱,將其設定為 * 代表協議對任何爬蟲有效,如果設定為 Baiduspider 則代表協議僅對百度爬蟲有效,要是有多條則對多個爬蟲有效,至少需要指定一條。
  • Disallow,網頁中不允許抓取的目錄,上述例子中設定的 / 代表不允許抓取所有的頁面。
  • Allow,一般和 Disallow 一起使用,用來排除單獨的某些限制,上述例子中設定為 /public/ 表示所有頁面不允許抓取,但可以抓取 public 目錄。

urllib.robotparser.RobotFileParser(url='') 類及其常用方法

  • set_url(url),設定引用 robots.txt 檔案的 url,如果在建立 RobotFileParser 物件時傳入了 url,那麼就不需要使用這個方法設定 url。
  • read(),讀取 robots.txt 檔案並將其提供給解析器,不返回任何內容。
  • parse(lines),用來解析 robots.txt 某些行的內容,並安裝語法規則來分析內容。
  • can_fetch(useragent,url),傳入兩個引數,使用者代理以及要爬取的網站,返回的內容是該使用者代理否可以抓取這個網站,結果為 True 或 False。

到此這篇關於python3 中使用urllib問題以及urllib詳解的文章就介紹到這了,更多相關python3使用urllib內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!