python爬蟲之解析連結

偷吃了老鼠的土豆發表於2020-12-01

解析連結

1. urlparse() & urlunparse()

urlparse() 是對url連結識別和分段的,API用法如下:

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

他的三個引數:

  • urlstring: 這是一個必須項,即待解析的url。
  • scheme: 它是預設協議。假如這個連結沒有帶協議資訊,會將這個作為預設協議。
from urllib.parse import urlparse

result = urlparse('www.baidu.com/index.html;user?id=5#comment', scheme='https')
print(result)

結果為:

ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')
  • allow_fragments: 即是否忽略fragment。如果他被設定為Falsefragment部分就會被忽略,他會解析為pathparameters或者query的一部分,而fragment部分為空
from urllib.parse import urlparse

result = urlparse('http://www.baidu.com/index.html;user?id=5#comment', allow_fragments=False)
print(result)

結果如下:

ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5#comment', fragment='')

假設URL中不包含paramsquery,如下:

from urllib.parse import urlparse

result = urlparse('http://www.baidu.com/index.html#comment', allow_fragments=False)
print(result)

執行結果如下:

ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html#comment', params='', query='', fragment='')

可以發現,當URL中不包含paramsquery時,fragment便會被解析為path的一部分。返回結果ParseResult實際上是一個元組,我們可以用索引順去來獲取,也可以用屬性名獲取。如下:

from urllib.parse import urlparse

result = urlparse('http://www.baidu.com/index.html#comment', allow_fragments=False)
print(result.scheme, result[0], result.netloc, result[1], sep='\n')

結果如下:

http
http
www.baidu.com
www.baidu.com

可以發現二者結果一致

urlunparse()是其對立方法,他可接收一個可迭代物件。但是長度必須是6,否則會丟擲引數數量不足或者過多的問題。如下:

from urllib.parse import urlunparse

data = ['http', 'www.baidu.com', 'index.html', 'user', 'a=6', 'comment']
print(urlunparse(data))

結果如下:

http://www.baidu.com/index.html;user?a=6#comment

2. urlsplite() & urlunsplite()

unsplite()urlparse()方法相似。但是不能單獨解析params這一部分,只返回5個結果。

from urllib.parse import urlsplit

result = urlsplit('http://www.baidu.com/index.html;user?id=5#comment')
print(result)

結果:

SplitResult(scheme='http', netloc='www.baidu.com', path='/index.html;user', query='id=5', fragment='comment')

返回結果SplitResult是一個元組型別,既可以用屬性獲取值,也可以用索引來獲取。如下:

from urllib.parse import urlsplit

result = urlsplit('http://www.baidu.com/index.html;user?id=5#comment')
print(result.scheme, result[0])

結果:

http http

urlunsplit()urlunparse()方法類似,他也是將連結各個部分組合成完整連結的方法。傳入的引數也是一個可迭代物件。長度必須為5,如下:

from urllib.parse import urlunsplit

data = ['http', 'www.baidu.com', 'index.html', 'a=6', 'comment']
print(urlunsplit(data))

結果:

http://www.baidu.com/index.html?a=6#comment

3. urljoin()

生成連結的另外一個方法,可以提供一個base_url作為第一個引數,將新的連結作為第二個引數,該方法會分析base_urlschemenetlocpath 這3個內容並對連結缺失部分進行補充。如下:

from urllib.parse import urljoin

print(urljoin('http://www.baidu.com', 'FAQ.html'))
print(urljoin('http://www.baidu.com', 'https://cuiqingcai.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html', 'https://cuiqingcai.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html', 'https://cuiqingcai.com/FAQ.html?question=2'))
print(urljoin('http://www.baidu.com?wd=abc', 'https://cuiqingcai.com/index.php'))
print(urljoin('http://www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com#comment', '?category=2'))

結果如下:

http://www.baidu.com/FAQ.html
https://cuiqingcai.com/FAQ.html
https://cuiqingcai.com/FAQ.html
https://cuiqingcai.com/FAQ.html?question=2
https://cuiqingcai.com/index.php
http://www.baidu.com?category=2#comment
www.baidu.com?category=2#comment
www.baidu.com?category=2

base_url提供了三項內容schemenetlocpath。 如果這3項在新的連結裡不存在就會補充。如果新的連結存在,就使用新的連結的部分。而base_url中的paramsqueryfragment是不起作用的。

4. urlencode()

urlencode()方法在構造GET請求引數的時候非常有用,如下:

from urllib.parse import urlencode

params = {
    'name': 'germey',
    'age': 22
}
base_url = 'http://www.baidu.com?'
url = base_url + urlencode(params)
print(url)

首先宣告一個字典來作為參數列示,然後呼叫urlencode()方法將其序列化為GET請求引數。

http://www.baidu.com?name=germey&age=22

5. parse_qs()

這是一個反序列化方法,我們可以利用parse_qs()方法,就可以轉回字典,如下:

from urllib.parse import parse_qs

query = 'name=germey&age=22'
print(parse_qs(query))

結果

{'name': ['germey'], 'age': ['22']}

6. parse_qsl()

將引數轉化成元組列表

from urllib.parse import parse_qsl

query = 'name=germey&age=22'
print(parse_qsl(query))

結果:

[('name', 'germey'), ('age', '22')]

7. quote() & unquote()

quote()是將中文轉換成URL編碼,unquote()是對URL進行解碼。

from urllib.parse import quote

keyword = '桌布'
url = 'https://www.baidu.com/s?wd=' + quote(keyword)
print(url)
https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8
from urllib.parse import unquote

url = 'https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8'
print(unquote(url))
https://www.baidu.com/s?wd=桌布

參考崔慶才部落格

相關文章