lxml類庫的xpath的使用

爲什麼要學習lxml類庫和xpath呢?
-lxml類庫是一款高性能的Python HTML/XML解析器,我們可以利用XPath,
來快速地定位特定元素以及獲取節點信息。
-XPath是一門在HTML/XML文檔中查找信息的語言,可用來在HTML/XML文檔中對元素和屬性進行遍歷。

XML和HTML的區別?
-XML:可擴展標記語言,被設計爲傳輸和存儲數據,其焦點是數據的內容。
-HTML:超文本標記語言,顯示數據以及如何更好顯示數據。
我們可以使用chrome的XPath-Helper插件來幫助我們尋找想要的數據。
XPath-Helper的使用?
獲取文本:"a/text()"
-選擇文本爲下一頁三個字的a標籤按鈕:"//a[text()='下一頁']"
 
獲取屬性(使用@符號定位):"a/@href";"//ul[@id='detail-list']/li/p/text()"
③//的使用:在xpath開始的時候表示從當前html中任意位置開始選擇
-"a//text()":獲取a下的所有文本;"li//":表示li下任何一個標籤
注意:使用chrome插件選擇標籤時候,選中的標籤會添加屬性class="xh-highlight"
 
面對xpath列表每個元素的索引:"div[@div='page']/a[2]"(獲取第三個a標籤)
-豆瓣劇情片排行榜:"//div[@id='wrapper']//div[@class='movie-list-panel pictext']/div[last()]"
(獲取最後一個div標籤)
面對xpath列表一些元素的獲取"div[@div='page']/a[position()>4]"
(獲取從第5個開始後面的所有a標籤,數字是索引)
注意:使用XPath-Helper或者是chrome中的copy xpath都是從element中提取的數據,
但是爬蟲獲取的是url對應的響應,往往和elements不一樣。
 
所以,這時候lxml類庫的一個功能就應運而生:
導入lxml的etree庫:from lxml import etree
利用etree.HTML,將字符串轉化爲Element對象:html=etree.HTML(text)
lxml可以自動修正html代碼。
 
 
節點選擇語法:
/ :從根節點選取。
// :從匹配選擇的當前節點選擇文檔中的節點,而不考慮他們的位置。
. :選取當前節點。
.. :選取當前節點的父節點。
@ :選取屬性。
* :匹配任何元素節點。
@* :匹配任何屬性節點。
node():匹配任何類型的節點
 
節點選擇語法詳細例子說明:
/bookstore/* :選取bookstore元素的所有子元素。
//* :選取文檔中的所有元素。
html/node()/meta/@*:選擇html下面任意節點下的meta節點的所有屬性。
//title[@*] :選取所有帶屬性的title元素。

from lxml import etree

text='''<div><ul>
<li class="item-1"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">forth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul></div>'''
html=etree.HTML(text)
print(html)
輸出結果:
<Element html at 0x1ffec265d48>
#這個時候的html是一個響應狀態。
 
print(etree.tostring(html).decode())
輸出結果:
<html><body><div><ul>
        <li class="item-1"><a href="link1.html">first item</a></li>
        <li class="item-1"><a href="link2.html">second item</a></li>
        <li class="item-inactive"><a href="link3.html">third item</a></li>
        <li class="item-1"><a href="link4.html">forth item</a></li>
        <li class="item-0"><a href="link5.html">fifth item</a></li>
</ul></div></body></html>
#查看element對象中包含的字符串
#lxml能夠修正HTML代碼,但是可能會改錯了:
使用etree.tostring觀察修改之後的html的樣子,根據修改之後的html字符串寫xpath。
 
list_1=html.xpath('//li[@class="item-1"]/a/@href')
print(list_1)
list_2=html.xpath('//li[@class="item-1"]/a/text()')
print(list_2)
for href in list_1:
item={}
item["href"]=href
item["titile"]=list_2[list_1.index(href)]
print(item)
輸出結果是:
['link1.html', 'link2.html', 'link4.html']
['first item', 'second item', 'forth item']
{'href': 'link1.html', 'titile': 'first item'}
{'href': 'link2.html', 'titile': 'second item'}
{'href': 'link4.html', 'titile': 'forth item'}
#要注意的是:xpath輸出的數據類型是列表。
#分組,根據li標籤進行分組,對每一組繼續寫xpath
 
list_3=html.xpath('//li[@class="item-1"]')
print(list_3)
for i in list_3:
item={}
item["title"]=i.xpath("./a/@href")[0]
item["href"]=i.xpath("./a/text()")[0]
print(item)
輸出結果:
[<Element li at 0x1ffec265c88>, <Element li at 0x1ffec265cc8>, <Element li at 0x1ffec265e48>]
{'title': 'link1.html', 'href': 'first item'}
{'title': 'link2.html', 'href': 'second item'}
{'title': 'link4.html', 'href': 'forth item'
#list_3是對象響應的列表,對於這個列表進行進一步xpath獲取數據處理。
#今後xpath採取數據建議使用這段方法:
#先把對象響應分組,然後對每一組進行直接抓取數據處理,常用的方法使用.符號。
 
這段代碼提取頁面數據的思路:
-先分組,渠道一個包含分組標籤的列表
-遍歷,取其中每一組進行數據的提現,不會造成數據的對應錯亂,避免操作失誤的風險。

注意:lxml能夠接受bytes和str的字符串
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章