小白學 Python 爬蟲(14):urllib 基礎使用(四)

人生苦短,我用 Pythonhtml

前文傳送門:python

小白學 Python 爬蟲(1):開篇git

小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝github

小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門數據庫

小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門瀏覽器

小白學 Python 爬蟲(5):前置準備(四)數據庫基礎數據結構

小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝框架

小白學 Python 爬蟲(7):HTTP 基礎ssh

小白學 Python 爬蟲(8):網頁基礎ide

小白學 Python 爬蟲(9):爬蟲基礎

小白學 Python 爬蟲(10):Session 和 Cookies

小白學 Python 爬蟲(11):urllib 基礎使用(一)

小白學 Python 爬蟲(12):urllib 基礎使用(二)

小白學 Python 爬蟲(13):urllib 基礎使用(三)

Parse 模塊

官方文檔:https://docs.python.org/zh-cn/3.7/library/urllib.parse.html

前面咱們介紹了 urllib 的 Request 模塊和 Error 模塊,本篇咱們接着介紹 Parse 模塊。

先看一下官方文檔的解釋吧:

This module defines a standard interface to break Uniform Resource Locator (URL) strings up in components (addressing scheme, network location, path etc.), to combine the components back into a URL string, and to convert a "relative URL" to an absolute URL given a "base URL."

The module has been designed to match the Internet RFC on Relative Uniform Resource Locators. It supports the following URL schemes: file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss.

The urllib.parse module defines functions that fall into two broad categories: URL parsing and URL quoting.

大意是該模塊定義了一個處理 URL 的標準接口,主要用於分解 URL 字符串爲組件和將組件組合回 URL 字符串,而且能夠將相對 URL 轉換爲絕對 URL 。

它支持的 URL 協議有:file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss。

urllib.parse 模塊定義的函數分爲兩大類:URL 解析和 URL 引用。

URL 解析

urlparse()

先看最經常使用的一個方法 urlparse() ,該方法主要用於識別 URL 和將其分段,再來看下 urlparse 對於一個 URL 的定義:

scheme://netloc/path;parameters?query#fragment複製代碼

能夠看到, urlparse() 將一個 URL 拆解成爲 6 個部分,分別是 schemenetlocpathparamsqueryfragment

大致上能夠看出來,解析時是會有特定的分隔符的。

  • scheme:位於 :// 前面,表明了當前的協議。
  • netloc:位於第一個 / 以前,表明了域名。
  • path:位於第一個 /; 之間,表明了訪問路徑。
  • parameters:位於 ;? 之間,表明了路徑元素的參數。
  • query:位於 ?# 之間,表明了查詢組件。
  • fragment:位於 # 以後,表明了片斷識別。

一個標準的 URL 應該是由以上部分組成,可是實際上,咱們如今看到的大部分的 URL 並不會在連接中包含 ;

看個小例子吧,隨便在官方文檔上找了個鏈接,咱們使用 urlparse() 將它解析一下看下結果:

from urllib.parse import urlparse

result = urlparse('https://docs.python.org/zh-cn/3.7/library/urllib.parse.html#module-urllib.parse')
print(type(result))
print(result)複製代碼

執行結果:

<class 'urllib.parse.ParseResult'>
ParseResult(scheme='https', netloc='docs.python.org', path='/zh-cn/3.7/library/urllib.parse.html', params='', query='', fragment='module-urllib.parse')複製代碼

能夠看到, urlparse() 返回的數據類型是 urllib.parse.ParseResult 對象,它其實是一個元組數據類型,而這個元組則包含了咱們上面介紹的那些組件元素。

若是咱們想要獲取這個連接中的某個值怎麼獲取呢?好比說咱們想獲取當前這個連接的域名信息:

print(result.netloc)複製代碼

結果以下:

docs.python.org複製代碼

咱們能夠直接經過這個 urllib.parse.ParseResult 對應的屬性將它取出來,而 urlparse() 甚至爲咱們提供了索引的方式來進行取值,對應關係以下表(如下內容來自官方文檔):

屬性 索引 描述 值(若是不存在)
scheme 0 URL 方案說明符 scheme parameter
netloc 1 域名 空字符串
path 2 分層路徑 空字符串
params 3 最後路徑元素的參數 空字符串
query 4 查詢組件 空字符串
fragment 5 片斷識別 空字符串

咱們再經過索引的方式獲取一下剛纔咱們想獲取的域名信息:

print(result[1])複製代碼

結果以下:

docs.python.org複製代碼

獲取成功。

咱們再來看一下 urlparse() 的語法:

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)複製代碼

  • urlstring:這是必填項,即待解析的URL。
  • scheme:它是默認的協議(好比 http 或 https 等)。假如這個連接沒有帶協議信息,會將這個做爲默認的協議。
  • allow_fragments:便是否忽略 fragment 。若是它被設置爲 False , fragment 部分就會被忽略,它會被解析爲 path 、 parameters 或者 query 的一部分,而 fragment 部分爲空。

咱們再來寫一個示例,鏈接仍是使用剛纔上面的連接,咱們在這個示例中去掉連接中的 scheme 信息,在參數中指定 scheme 信息,而且將 allow_fragments 設置爲 False ,看下片斷識別將會被解析成哪一部分:

from urllib.parse import urlparse

result1 = urlparse('docs.python.org/zh-cn/3.7/library/urllib.parse.html#module-urllib.parse', scheme = "https", allow_fragments = False)
print(result1)複製代碼

運行結果以下:

ParseResult(scheme='https', netloc='', path='docs.python.org/zh-cn/3.7/library/urllib.parse.html#module-urllib.parse', params='', query='', fragment='')複製代碼

能夠從結果中看出, scheme 信息是能夠正常識別出來的,而片斷識別信息則被解析成爲了 path 的一部分。

urlunparse()

有了解析連接的 urlparse() ,那麼必定會存在構建連接的 urlunparse()

這個方法它接受的參數是一個可迭代對象,可是它的長度必須是 6 ,不然會拋出參數數量不足或者過多的問題。

咱們仍是經過一個示例瞭解一下:

from urllib.parse import urlparse, urlunparse

params = ('https', 'www.geekdigging.com', 'index.html', 'people', 'a=1', 'geekdigging')
print(urlunparse(params))複製代碼

這裏的參數使用的數據類型是元組,固然也能夠選擇其餘的可迭代的數據類型,例如列表或者特定的數據結構等等。

運行結果以下:

https://www.geekdigging.com/index.html;people?a=1#geekdigging複製代碼

這樣咱們就簡單的實現了 URL 的構造,若是其中某些參數在構建的時候不存在,切記不可直接不寫,留空字符串便可,以下:

params = ('https', 'www.geekdigging.com', 'index.html', '', '', 'geekdigging')複製代碼

urlsplit()

urlsplit() 這個方法和 urlparse() 很是像,惟一的區別就是 urlsplit() 再也不單獨解析 params 這個組件,只會返回 5 個組件的結果,它將 params 合併到了 path 中。仍是看一個示例:

from urllib.parse import urlsplit

result_urlsplit = urlsplit("https://www.geekdigging.com/index.html;people?a=1#geekdigging")
print(type(result_urlsplit))
print(result_urlsplit)複製代碼

結果以下:

<class 'urllib.parse.SplitResult'>
SplitResult(scheme='https', netloc='www.geekdigging.com', path='/index.html;people', query='a=1', fragment='geekdigging')複製代碼

能夠發現,返回結果是 urllib.parse.SplitResult ,它其實也是一個元組類型,既能夠用屬性獲取值,也能夠用索引來獲取。示例以下:

print(result_urlsplit.netloc)
print(result_urlsplit[1])複製代碼

結果以下:

www.geekdigging.com
www.geekdigging.com複製代碼

urlunsplit()

看到這個命名各位同窗應該大體上已經能夠猜出來 urlunsplit() 它的做用以及用法了。

對的,木有錯,它和上面介紹的 urlunparse() 是很是類似的,惟一的區別就是它的參數長度必須爲 5 。示例以下:

from urllib.parse import urlunsplit

params_urlunsplit = ('https', 'www.geekdigging.com', 'index.html;people', 'a=1', 'geekdigging')
print(urlunsplit(params_urlunsplit))複製代碼

結果以下:

https://www.geekdigging.com/index.html;people?a=1#geekdigging複製代碼

其他的很少作介紹,徹底參考上面的 urlunparse()

urljoin()

上面咱們介紹了 urlunparse()urlunsplit() 兩個方法能夠合成連接,前提是咱們須要有定長的參數可迭代對象,連接的每個組件都要對應的分開。

而 urllib.parase 中提供的 urljoin() 這個方法就比較有意思了。咱們先看下官方的解釋:

Construct a full ("absolute") URL by combining a "base URL" (base) with another URL (url). Informally, this uses components of the base URL, in particular the addressing scheme, the network location and (part of) the path, to provide missing components in the relative URL.

其中的大意是:經過基礎的 URL 和另外一個 URL 來完成組合完成最終的 URL ,它會分析基礎的 URL 的 schemenetlocpath 這三個內容,並對新鏈接缺失的部分進行補充,完成最終的組合。

有點沒看懂?不要緊,咱們寫幾個簡單的示例就清楚了:

print(urljoin("https://www.geekdigging.com/", "index.html"))
print(urljoin("https://www.geekdigging.com/", "https://www.geekdigging.com/index.html"))
print(urljoin("https://www.geekdigging.com/", "?a=aa"))
print(urljoin("https://www.geekdigging.com/#geekdigging", "https://docs.python.org/zh-cn/3.7/library/urllib.parse.html"))複製代碼

結果以下:

https://www.geekdigging.com/index.html
https://www.geekdigging.com/index.html
https://www.geekdigging.com/?a=aa
https://docs.python.org/zh-cn/3.7/library/urllib.parse.html複製代碼

不知各位同窗看懂了沒?

只有在第二個參數連接缺失 schemenetlocpath 這三個內容的時候,纔會從第一個參數中獲取對應的內容進行組合。

parse_qs()

這個方法可讓咱們將一串 GET 請求中的參數轉換成爲字典。

咱們在百度搜索的時候,像百度發送的請求實際上是 GET 請求,例如我在百度搜索 Python ,這時瀏覽器上的連接顯示爲:https://www.baidu.com/s?ie=UTF-8&wd=python 。這裏的 GET請求參數其實是 ? 後面這部分 ie=UTF-8&wd=python 。咱們仍是用 parse_qs() 來寫個示例看一下:

from urllib.parse import parse_qs

print(parse_qs("ie=UTF-8&wd=python"))複製代碼

執行結果以下:

{'ie': ['UTF-8'], 'wd': ['python']}複製代碼

能夠看到,參數成功的轉換成了字典。

parse_qsl()

還有一個parse_qsl()方法,它用於將參數轉化爲元組組成的列表,示例以下:

from urllib.parse import parse_qsl

# parse_qsl 示例
print(parse_qsl("ie=UTF-8&wd=python"))複製代碼

執行結果以下:

[('ie', 'UTF-8'), ('wd', 'python')]複製代碼

能夠看到,參數成功的轉換成了元組組成的列表。

URL 引用

urlencode()

咱們接着介紹一個比較經常使用的方法: urlencode()

這個方法是用來構造 GET 請求參數的,例如咱們上面示例中所使用到的百度搜索的參數,它能夠將一個字典轉換成爲 GET 請求參數。示例以下:

from urllib.parse import urlencode

# urlencode 示例
dict = {
    "name": "極客挖掘機",
    "age": 18
}
print("https://www.geekdigging.com/" + urlencode(dict))複製代碼

結果以下:

https://www.geekdigging.com/name=%E6%9E%81%E5%AE%A2%E6%8C%96%E6%8E%98%E6%9C%BA&age=18複製代碼

執行結果中有一串看不懂是什麼的字符串,這個是 URL 編碼,由於參數中含有中文參數時,可能會致使亂碼,能夠看到 urlencode() 這個方法,自動的幫咱們對中文進行了 URL 編碼。

quote()

這個方法是 urllib.parse 中專門爲咱們提供的 URL 轉碼的方法,咱們仍是拿上面一個示例的中文進行轉碼,各位同窗能夠看下結果是否相同:

from urllib.parse import quote

# quote 示例
print(quote("極客挖掘機"))複製代碼

結果以下:

%E6%9E%81%E5%AE%A2%E6%8C%96%E6%8E%98%E6%9C%BA複製代碼

好像是同樣的對吧,說明咱們測試成功。

unquote()

有了 quote() 的方法,固然會搞一個專門逆向的方法咯~~~

咱們把剛纔通過 URL 編碼後的字符串拿出來作測試,看看能不能轉回去:

from urllib.parse import unquote

# unquote 示例
print(unquote("%E6%9E%81%E5%AE%A2%E6%8C%96%E6%8E%98%E6%9C%BA"))複製代碼

結果以下:

極客挖掘機複製代碼

能夠看到,通過咱們 URL 編碼後的字符串逆向成功。

本篇的內容就到這裏了,內容有些又臭又長,不過仍是但願各位同窗能夠親自動手練習一下。

畢竟,本身不敲代碼是永遠學不會代碼的。

示例代碼

本系列的全部代碼小編都會放在代碼管理倉庫 Github 和 Gitee 上,方便你們取用。

示例代碼-Github

示例代碼-Gitee

參考

https://www.cnblogs.com/zhangxinqi/p/9170312.html

若是個人文章對您有幫助,請掃碼關注下做者的公衆號:獲取最新干貨推送:)
相關文章
相關標籤/搜索