我要爬爬蟲(7)-xpath解析庫
常用符號
/ 直接子節點
// 所有子孫節點
. 當前節點
.. 當前節點的父節點
@ 屬性值
contains 屬性包括
lxml庫的使用
對於下面這段html文字source.html
<div>
<ul>
<li class ="item-0"><a href="link1.html">first time</a> </li>
<li class ="item-1"><a href="link2.html">second time</a> </li>
<li class ="item-inactive"><a href="link3.html">third time</a> </li>
<li class ="item-1"><a href="link4.html">fouth time</a> </li>
<li class ="item-0"><a href="link5.html">fifth time</a>
</ul>
</div >
直接解析html文字
from lxml import etree
#HTML方法傳入html文字構造xpath解析物件,並可自動修復預設格式
html=etree.HTML('XXXXXXXXXX')
#tostring轉換成bytes
result=etree.tostring(html)
#decode轉換成string
print(result.decode('gbk'))
#解碼之後可以實現換行輸出,utf-8或gbk都行
結果如下
<html><body><div>
<ul>
<li class="item-0"><a href="link1.html">first time</a> </li>
<li class="item-1"><a href="link2.html">second time</a> </li>
<li class="item-inactive"><a href="link3.html">third time</a> </li>
<li class="item-1"><a href="link4.html">fouth time</a> </li>
<li class="item-0"><a href="link5.html">fifth time</a>
</li></ul>
</div>
</body></html>
其實就是個補全格式的操作。
也可對html檔案進行解析。
html=etree.parse('source.html',parser=etree.HTMLParser())
result=etree.tostring(html)
print(result.decode('gbk'))
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div>
<ul>
<li class="item-0"><a href="link1.html">first time</a> </li>
<li class="item-1"><a href="link2.html">second time</a> </li>
<li class="item-inactive"><a href="link3.html">third time</a> </li>
<li class="item-1"><a href="link4.html">fouth time</a> </li>
<li class="item-0"><a href="link5.html">fifth time</a> </li>
</ul>
</div></body></html>
多了個DOCTYPE的宣告,其他一樣。
取節點
html.xpath('//*')
取得所有子孫節點
列表形式返回所有節點
[<Element html at 0x1626ad130c8>,
<Element body at 0x1626ac5d648>,
<Element div at 0x1626ad1c108>,
<Element ul at 0x1626ad1cfc8>,
<Element li at 0x1626ad1c788>,
<Element a at 0x1626ad1c8c8>,
<Element li at 0x1626ad1c648>,
<Element a at 0x1626ad1c848>,
<Element li at 0x1626ad1c388>,
<Element a at 0x1626ad1c3c8>,
<Element li at 0x1626ad1c208>,
<Element a at 0x1626ad1c188>,
<Element li at 0x1626ad1c6c8>,
<Element a at 0x1626ad1c688>]
//li
取得所有li節點
//li/a
取得所有li節點下的直接a節點
//a[@href="link4.html"]/../@class
取得所有滿足href=“link4.html”的a節點的父節點的class屬性
li[@class="item-0"]/text()
這裡取不到任何值
結果[' ', '\n ']
因為li節點的直接子節點沒有文字,只有a節點和空格,以及構造xpath物件時新增的換行符。
對於<li class="li li-first"><a href="link.html"><a/><li/>
這裡li節點的class屬性有兩個值li li-first,所以用[@class='li']
是取不到該節點的,應該使用[contains(@class,'li')]
,這樣屬性值裡包含即可匹配到。
//li[contains(@class,"li") and @name="item"]/a/text()
這裡使用and並列查詢條件。
//li[1]
下標1即取第一個節點,並非第二個。
//li[last()]
最後一個節點
//li[position()<3]
下標小於3,即第一,第二個節點。
//li[last()-2]
倒數第三個節點
節點軸
ancestor 祖先節點
attribute 屬性值
child 子節點
decedent 子孫節點
following 後面的節點
following-sibling 後面的同級節點
//li[1]/following::*2
第一個li節點的後面第二個節點