python3解析庫pyquery
pyquery是一個類似jquery的python庫,它實現能夠在xml文件中進行jQuery查詢,pyquery使用lxml解析器進行快速在xml和html文件上操作,它提供了和jQuery類似的語法來解析HTML文件,支援CSS選擇器,使用非常方便
pyquery安裝
pip方式安裝:
$pip install pyquery #它依賴cssselect和lxml包 pyquery==1.4.0 - cssselect [required: >0.7.9, installed: 1.0.3] #CSS選擇器並將它轉換為XPath表示式 - lxml [required: >=2.1, installed: 4.2.2] #處理xml和html解析庫
驗證安裝:
In [1]: import pyquery
In [2]: pyquery.text
Out[2]: <module 'pyquery.text' from '/root/pp1/.venv/lib/python3.6/site-packages/pyquery/text.py'>
pyquery物件初始化
pyquery首先需要傳入HTML文字來初始化一個pyquery物件,它的初始化方式有多種,如直接傳入字串,傳入URL或者傳入檔名
(1)字串初始化
from pyquery import PyQuery as pq html=''' <div id="wenzhangziti" class="article 389862"><p>人生是一條沒有盡頭的路,不要留戀逝去的夢,把命運掌握在自己手中,讓我們來掌握自己的命運,別讓別人的干擾與誘惑,別讓功名與利祿,來打翻我們這壇陳釀已久的命運之酒!</p> </div> ''' doc=pq(html) #初始化並建立pyquery物件 print(type(doc)) print(doc('p').text()) # <class 'pyquery.pyquery.PyQuery'> 人生是一條沒有盡頭的路,不要留戀逝去的夢,把命運掌握在自己手中,讓我們來掌握自己的命運,別讓別人的干擾與誘惑,別讓功名與利祿,來打翻我們這壇陳釀已久的命運之酒!
(2)URL初始化
from pyquery import PyQuery as pq
doc=pq(url='https://www.cnblogs.com/zhangxinqi/p/9218395.html')
print(type(doc))
print(doc('title'))
#
<class 'pyquery.pyquery.PyQuery'>
<title>python3解析庫BeautifulSoup4 - Py.qi - 部落格園</title>
PyQuery能夠從url載入一個html文件,之際上是預設情況下呼叫python的urllib庫去請求響應,如果requests已安裝的話它將使用requests來請求響應,那我們就可以使用request的請求引數來構造請求了,實際請求如下:
from pyquery import PyQuery as pq
import requests
doc=pq(requests.get(url='https://www.cnblogs.com/zhangxinqi/p/9218395.html').text)
print(type(doc))
print(doc('title'))
#輸出同上一樣
<class 'pyquery.pyquery.PyQuery'>
<title>python3解析庫BeautifulSoup4 - Py.qi - 部落格園</title>
(3)通過檔案初始化
通過本地的HTML檔案來構造PyQuery物件
from pyquery import PyQuery as pq
doc=pq(filename='demo.html',parser='html')
#doc=pq(open('demo.html','r',encoding='utf-8').read(),parser='html') #注意:在讀取有中文的HTML檔案時,請使用此方法,否則會報解碼錯誤
print(type(doc))
print(doc('p'))
CSS選擇器
在使用屬性選擇器中,使用屬性選擇特定的標籤,標籤和CSS標識必須引用為字串,它會過濾篩選符合條件的節點列印輸出,返回的是一個PyQuery型別物件
from pyquery import PyQuery as pq
import requests
html='''
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
doc=pq(html,parser='html')
print(doc('#container .list .item-0 a'))
print(doc('.list .item-1'))
#
<a href="link3.html"><span class="bold">third item</span></a><a href="link5.html">fifth item</a>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
查詢節點
PyQuery使用查詢函式來查詢節點,同jQuery中的函式用法完全相同
(1)查詢子節點和子孫節點
使用find()方法獲取子孫節點,children()獲取子節點,使用以上的HTML程式碼測試
from pyquery import PyQuery as pq
import requests
doc=pq(html,parser='html')
print('find:',doc.find('a'))
print('children:',doc('li').children('a'))
(2)獲取父節點和祖先節點
parent()方法獲取父節點,parents()獲取祖先節點
doc(.list).parent()
doc(.list).parents()
(3)獲取兄弟節點
siblings()方法用來獲取兄弟節點,可以巢狀使用,傳入CSS選擇器即可繼續匹配
doc('.list .item-0 .active').siblings('.active')
遍歷
對於pyquery的選擇結果可能是多個位元組,也可能是單個節點,型別都是PyQuery型別,它沒有返回列表等形式,對於當個節點我們可指直接列印輸出或者直接轉換成字串,而對於多個節點的結果,我們需要遍歷來獲取所有節點可以使用items()方法,它會返回一個生成器,迴圈得到的每個節點型別依然是PyQuery型別,所以我們可以繼續方法來選擇節點或屬性,內容等
lis=doc('li').items()
for i in lis:
print(i('a')) #繼續獲取節點下的子節點
獲取資訊
attr()方法用來獲取屬性,如返回的結果有多個時可以呼叫items()方法來遍歷獲取
doc('.item-0.active a').attr('href') #多屬性值中間不能有空格
text()方法用來獲取文字內容,它只返回內部的文字資訊不包括HTML文字內容,如果想返回包括HTML的文字內容可以使用html()方法,如果結果有多個,text()方法會方法所有節點的文字資訊內容並將它們拼接用空格分開返回字串內容,html()方法只會返回第一個節點的HTML文字,如果要獲取所有就需要使用items()方法來遍歷獲取了
from pyquery import PyQuery as pq
html='''
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
doc=pq(html,parser='html')
print('text:',doc('li').text()) #獲取li節點下的所有文字資訊
lis=doc('li').items()
for i in lis:
print('html:',i.html()) #獲取所有li節點下的HTML文字
#
text: first item second item third item fourth item fifth item
html: first item
html: <a href="link2.html">second item</a>
html: <a href="link3.html"><span class="bold">third item</span></a>
html: <a href="link4.html">fourth item</a>
html: <a href="link5.html">fifth item</a>
節點操作
pyquery提供了一系列方法來對節點進行動態修改,如新增一個class,移除某個節點,修改某個屬性的值
addClass()增加Class,removeClass()刪除Class
attr()增加屬性和值,text()增加文字內容,html()增加HTML文字,remove()移除
from pyquery import PyQuery as pq
import requests
html='''
<div id="container">
<ul class="list">
<li id="1">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-2 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-3 active"><a href="link4.html">fourth item</a></li>
<li class="item-4"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
doc=pq(html,parser='html')
print(doc('#1'))
print(doc('#1').add_class('myclass')) #增加Class
print(doc('.item-1').remove_class('item-1')) #刪除Class
print(doc('#1').attr('name','link')) #新增屬性name=link
print(doc('#1').text('hello world')) #新增文字
print(doc('#1').html('<span>changed item</span>')) #新增HTML文字
print(doc('.item-2.active a').remove('span')) #刪除節點
#
<li id="1">first item</li>
<li id="1" class="myclass">first item</li>
<li class=""><a href="link2.html">second item</a></li>
<li id="1" class="myclass" name="link">first item</li>
<li id="1" class="myclass" name="link">hello world</li>
<li id="1" class="myclass" name="link"><span>changed item</span></li>
<a href="link3.html"/>
[](javascript:void(0)