解析庫的使用(XPath,BeautifulSoup, pyquery)
從崔慶才的《Python3網路開發實戰》上總結而來
使用XPath
from lxml import etree
html = etree.HTML(text) #呼叫HTML類進行初始化
html = etree.parse(text, etree,HTML.Parser())#直接對文字進行解析,但是會多出一個DOCTYPE宣告
result = etree.tostring(html) #輸出修正後的HTML文字,是bytes型別
result.decode(‘utf-8’) #將bytes型別轉換成str型別
result = html.xpath(匹配模式)
html.xpath(‘title’) 表示選取title元素的所有子節點
html.xpath(‘/title’) 表示選取根元素 title
html.xpath(‘title /book’) 選取屬於title的子元素的所有 book 元素。
html.xpath(‘//book’) 選取所有 book 子元素,而不管它們在文件中的位置。
html.xpath(‘title //book’) 選擇屬於title 元素的後代的所有 book 元素,而不管它們位於title之下的什麼位置。
html.xpath(‘//@lang’) 選取名為 lang 的所有屬性
多層[表示式]之間用|分隔
表示式 描述 |
nodename 選取此節點的所有子節點 |
/ 從根節點選取 |
// 從匹配選擇的當前節點選擇文件中的節點,而不考慮它們的位置 |
. 選取當前節點 |
.. 選取當前節點的父節點 |
@ 選取屬性 |
屬性匹配可以採用and or 等運算子
路徑表示式 結果 |
/bookstore/book[1] 選取屬於 bookstore 子元素的第一個 book 元素 |
/bookstore/book[last()] 選取屬於 bookstore 子元素的最後一個 book 元素。 |
/bookstore/book[last()-1] 選取屬於 bookstore 子元素的倒數第二個 book 元素。 |
/bookstore/book[position()<3] 選取最前面的兩個屬於 bookstore 元素的子元素的 book 元素。 |
//title[@lang] 選取所有擁有名為 lang 的屬性的 title 元素。 |
//title[@lang=’eng’] 選取所有 title 元素,且這些元素擁有值為 eng 的 lang 屬性。 |
/bookstore/book[price>35.00] 選取 bookstore 元素的所有 book 元素,且其中的 price 元素的值須大於 35.00。 |
/bookstore/book[price>35.00]/title 選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大於 35.00。 |
萬用字元 描述 |
* 匹配任何元素節點 |
@* 匹配任何屬性節點 |
node() 匹配任何型別的節點 |
軸可定義相對於當前節點的節點集。格式 軸名稱::
軸名稱 結果 |
ancestor 選取當前節點的所有先輩(父、祖父等)。 |
ancestor-or-self 選取當前節點的所有先輩(父、祖父等)以及當前節點本身。 |
attribute 選取當前節點的所有屬性。 |
child 選取當前節點的所有子元素。 |
descendant 選取當前節點的所有後代元素(子、孫等)。 |
descendant-or-self 選取當前節點的所有後代元素(子、孫等)以及當前節點本身。 |
following 選取文件中當前節點的結束標籤之後的所有節點。 |
namespace 選取當前節點的所有名稱空間節點。 |
parent 選取當前節點的父節點。 |
preceding 選取文件中當前節點的開始標籤之前的所有節點。 |
preceding-sibling 選取當前節點之前的所有同級節點。 |
self 選取當前節點。 |
方法:
text()獲取節點中的文字
contains(),第一個引數傳入屬性名稱,第二個引數傳入屬性的值,只要此屬性包含所傳入的屬性值,就可以完成匹配。
BeautifulSoup
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 解析器)#解析器常用lxml
soup.prettify()#以標準的縮排形式輸出
soup.節點 #輸出匹配到的第一個節點
soup.節點.string #獲取節點的文字
soup.節點.name #獲取節點的名稱
soup.節點.attrs #獲取節點的所有屬性,以字典形式返回{屬性名:屬性值}
soup.節點.contents #獲得直接子節點的列表
soup.節點.children #返回子節點的生成器
soup.節點.descendants #返回遞迴所有子節點的生成器
soup.節點.parent #父節點及其內部的全部內容
soup.節點.parents #所有祖先節點及其內容,以生成器形式返回
soup.節點.next_sibling #節點的下一個兄弟節點內容
soup.節點.previous_sibling #節點的上一個兄弟節點內容
soup.節點.next_siblings #節點的後面所有兄弟節點內容,以生成器形式返回
soup.節點.previous_siblings#節點的前面所有兄弟節點內容,以生成器形式返回
方法:返回列表形式
find_all(name, attrs, recursive, text, **kwargs)
name引數其值為節點名,attrs為字典引數(當屬性名為class時,可用class_作為屬性名),text引數用來匹配節點的文字,傳入的形式可以使字串或正則表示式物件。
find()返回的是第一個匹配的節點內容
find_parent()返回直接父節點
find_parents()返回所有祖先節點
find_next_sibling()返回後面第一個兄弟節點
find_next_siblings()返回後面的所有兄弟節點
find_previous_sibling()返回前面第一個兄弟節點
find_previous_siblings()返回前面的所有兄弟節點
find_next()返回節點後第一個符合條件的節點
find_all_next()返回節點後所有符合條件的節點
find_previous()返回節點前第一個符合條件的節點
find_all_previous()返回節點前所有符合條件的節點
pyquery
from pyquery import PyQuery as pq
需要初始化PyQuery物件,比如直接傳入字串、URL、檔名
doc = pq(html)
doc = pq(url=url)指定url引數
doc = pq(filename=filename)指定filename引數
result= =doc(#container.list li)#選取id為container的節點,再選取內部的class為list的節點內部的所有li節點
方法:返回型別為PyQuery型別
result.find(CSS選擇器)#返回所有子孫節點中符合CSS選擇器的節點
result.children(CSS選擇器)# 返回直接子節點中符合CSS選擇器的節點
result.parent(CSS選擇器)# 返回直接父節點中符合CSS選擇器的節點
result.parents(CSS選擇器)# 返回所有祖先節點中符合CSS選擇器的節點
result.siblings(CSS選擇器)#返回所有兄弟節點中符合CSS選擇器的節點
對PyQuery型別呼叫items()方法後,會得到一個生成器,
result.attr(),傳入屬性名稱就可以得到屬性值,如果傳入第二個引數則可以修改屬性值。
result.text(),如果不傳引數,則獲取節點內純文字,如果傳入引數則進行賦值。
result.html(),如果不傳引數,則獲取節點內HTML文字,如果傳入引數則進行賦值。
result.removeClass(屬性名),將節點內的屬性移除。
result.addClass(屬性名),新增屬性到節點。