python爬蟲學習——解析庫pyquery的使用

這個解析庫對於學過前端的人非常友好,因爲其有強大的CSS選擇器,也可以增加或刪除class,方便的提取數據或者屬性。

初始化

  • 字符串初始化

這個就是傳入html代碼的字符串格式,簡單的requests庫可以獲得該參數。
以知乎-新聞頁爲例

import requests 
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0'
}
r = requests.get("https://daily.zhihu.com/",headers=headers)
print(r.text)

r.text返回的是一個經過解碼後的字符串,是unicode類型,而r.content返回的是一個原生字符串,是bytes類型

  • URL初始化

此時只需要指定參數爲 url 即可 :

from pyquery import PyQuery 
doc=PyQuery(url="https://www.baidu.com/")

這樣的話, PyQuery 對象會首先請求這個 URL, 然後用得到的 HTML 內容完成初始化,這其實就相當於用網頁的源代碼以字符串的形式傳遞給 PyQuery 類來初始化。

  • 文件初始化
from pyquery import PyQuery 
doc=PyQuery(filename="test.html")

此時將參數指定爲 filename 即可 。當然,這裏需要有一個本地 HTML 文件 test.html,其內容是待解析的 HTML 字符串。 這樣它會 首先讀取本地的文件內容,然後用文件內容以字符串的形式傳遞給 PyQuery 類來初始化。

基本CSS選擇器

這就是我認爲這個解析庫比較好用的地方,可以配合CSS選擇器來使用。直接看下例:

from pyquery import PyQuery 
html="待解析的html"
doc=PyQuery(html)
print(doc('#content .list li'))

這裏我們初始化 PyQuery 對象之後,傳入了一個 CSS 選擇器#container .list li,選擇後它的類型依然是 PyQuery 類型。配合CSS選擇器,事半功倍。

查找結點

  • 子節點

查找子節點時, 需要用到find()方法,此時傳人的參數是 css 選擇器。

from pyquery import PyQuery 
html="解析對象"
doc=PyQuery(html)
items=(doc('.list'))
lis=items.find('li')

find()方法會將符合條件的所有節點選擇出來,結果的類型是 PyQuery 類型。其實find()的查找範圍是節點的所有子孫節點(該節點下的所有結點)
而如果我們只想查找子節點,那麼可以用 children()方法:

lis=items.children('li')
#剩下的一致
  • 父節點

我們可以用 parent()方法來獲取某個節點的父節點,示例如下:

from pyquery import PyQuery 
html=""
doc=PyQuery(html)
items=(doc('.list'))
parents=items.parent()

這裏我們首先用 .list 選取 class 爲 list 的節點,然後調用 parent()方法得到其父節點,其類型依然是 PyQuery 類型。
這裏的父節點是該節點的直接父節點,也就是說,它不會再去查找父節點的父節點, 即祖先節點。

但是如果想獲取某個祖先節點,該怎麼辦呢?這時可以用 parents()方法:

parents=items.parents()

同樣的,如果想要篩選某個祖先節點的話,可以向 parents()方法傳入CSS選擇器。

  • 兄弟結點

如果要獲取兄弟節點, 可以使用 siblings()方法

from pyquery import PyQuery 
html=""
doc=PyQuery(html)
items=(doc('.list'))
lis=items.siblings()

將篩選後的結點的兄弟節點返回。

遍歷

pyquery 的選擇結果可能是多個節點,也可能是單個節點 , 類型都是 PyQuery 類型。

對於單個節點來說,可以直接打印輸出,也可以直接轉成字符串 。

對於多個節點的結果,我們就需要遍歷來獲取了。例如,這裏把每一個 li 節點進行遍歷,需要調用 items()方法:

doc=PyQuery(html)
a=doc('.li').items()
for i in a:
    print(i,type(i))

調用 items()方法後,會得到一個生成器,遍歷一下,就可以逐個得到 li 節點對象了 , 它的類型也是 PyQuery 類型。每個 li 節點還可以調用前面所說的方法進行選擇,比如繼續查詢子節點, 尋找某個祖先節點等,非常靈活。也可以用下文的屬性提取,十分靈活。

獲取信息

  • 獲取屬性

提取到某個 PyQuery 類型的節點後,就可以調用 attr()方法來獲取屬性:

from pyquery import PyQuery 
html=""
doc=PyQuery(html)
a=(doc('.list'))
print(a.attr('href'))

在這個方法中傳入屬性的名稱,就可以得到這個屬性值了。
此外,也可以通過調用 attr 屬性來獲取屬性,用法如下 :

print(a.attr.href)

注意:當返回結果包含多個節點時,調用 attr()方法,只會得 到第一個節點的屬性。那麼,遇到這種情況時,如果想獲取所有的 a 節點的屬性,就要用到前面所說的遍歷了 。

  • 獲取文本

可以調用 text()方法來實現:

from pyquery import PyQuery 
html=""
doc=PyQuery(html)
a=(doc('.list'))
print(a.text())

這裏首先選中class=list的節點,然後調用 text()方法,就可以獲取其內部的文本信息。 此時它會忽略 掉節點內部包含的所有 HTML,只返回純文字內容。

但如果想要獲取這個節點內部的 HTML 文本,就要用 html()方法了:

a=(doc('.list'))
print(a.html())

html()方法返回的是第一個 li 節點的內部 HTML 文本,而 text()則返 回了所有的 li 節點內部的純文本,中間用一個空格分割開,即返回結果是一個字符串。

若要輸出處理,應該遍歷依次輸出內容

節點操作

pyquery 提供了一系列方法來對節點進行動態修改,比如爲某個節點添加一個 class ,移除某個節點等,這些操作有時候會爲提取信息帶來極大的便利。

  • 移除添加class
doc=PyQuery(html)
a=(doc('.list'))
a.removeClass('active')
a.addClass('active')

首先選中了class爲list,然後調用 removeClass ()方法,將節點的 active 這個 class 移除, 後來又調用 addClass()方法,將 class 添加回來。

  • 改變屬性

當然,除了操作 class 這個屬性外,也可以用 attr()方法對屬性進行操作。 此外,還可以用 text() 和 html()方法來改變節點內部的內容。 示例如下:

a=(doc('.list'))
a.attr('name','link')
a.text('change')
a.html('<span>changed item</span>')

所以說,如果 attr()方法只傳入第一個參數的屬性名,則是獲取這個屬性值。如果傳入第二個參數,可以用來修改屬性值。 text()和 html()方法如果不傳參數,則是獲取節點內純文本和 HTML 文本。如果傳人蔘數,則進行賦值。

  • 移除節點
wrap.find ('p').remove() 

首先選中 p 節點,然後調用了 remove()方法將其移除,可以方便進一步提取節點內容。

另外,其實還有很多節點操作的方法,比如 append()、 empty()和 prepend()等方法,它們和 jQuery 的用法完全一致,詳細的用法可以參考官方文檔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章