python爬蟲之xpath的基本使用
一、簡介
XPath 是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。XPath 是 W3C XSLT 標準的主要元素,並且 XQuery 和 XPointer 都構建於 XPath 表達之上。
參照
二、安裝
命令行中:
1 |
pip3 install lxml
|
三、使用
1、導入
IDE中導入:
1 |
from lxml import etree
|
2、基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from lxml import etree
wb_data = """
<div>
<ul>
<li class="item-0"><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">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul> </div>
"""
html = etree.HTML(wb_data)
print (html)
result = etree.tostring(html)
print (result.decode( "utf-8" ))
|
從下面的結果來看,我們打印出的html其實就是一個python對象,etree.tostring(html)則是補全了html的基本寫法,對其中標簽查漏補缺,結構化更清晰。輸出結果如下:
1 2 3 4 5 6 7 8 9 10 11 |
<Element html at 0x39e58f0 >
<html><body><div>
<ul>
<li class = "item-0" ><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" >fourth item< / a>< / li>
<li class = "item-0" ><a href = "link5.html" >fifth item< / a>
< / li>< / ul>
< / div>
< / body>< / html>
|
3、獲取某個標簽的內容(基本使用),註意,獲取a標簽的所有內容,a後面就不用再加正斜杠,否則報錯。
寫法一
1 2 3 4 5 6 7 8 9 10 11 12 13 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘/html/body/div/ul/li/a‘ )
print (html)
for i in html_data:
print (i.text)
<Element html at 0x12fe4b8 >
first item
second item
third item
fourth item
fifth item
|
寫法二(直接在需要查找內容的標簽後面加一個/text()就行)
1 2 3 4 5 6 7 8 9 10 11 12 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘/html/body/div/ul/li/a/text()‘ )
print (html)
for i in html_data:
print (i)
<Element html at 0x138e4b8 >
first item
second item
third item
fourth item
fifth item
|
4、打開讀取html文件
1 2 3 4 5 6 |
#使用parse打開html的文件
html = etree.parse( ‘test.html‘ )
html_data = html.xpath( ‘//*‘ )<br> #輸出為一個列表,需要遍歷
print (html_data)
for i in html_data:
print (i.text)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
html = etree.parse( ‘test.html‘ )
html_data = etree.tostring(html,pretty_print = True )
res = html_data.decode( ‘utf-8‘ )
print (res)
打印:
<div>
<ul>
<li class = "item-0" ><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" >fourth item< / a>< / li>
<li class = "item-0" ><a href = "link5.html" >fifth item< / a>< / li>
< / ul>
< / div>
|
5、打印指定路徑下a標簽的屬性(可以通過遍歷拿到某個屬性的值,查找標簽的內容)
1 2 3 4 5 6 7 8 9 10 11 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘/html/body/div/ul/li/a/@href‘ )
for i in html_data:
print (i)
打印:
link1.html
link2.html
link3.html
link4.html
link5.html
|
6、我們知道我們使用xpath拿到得都是一個個的ElementTree對象,所以如果需要查找內容的話,還需要遍歷拿到數據的列表。
查到絕對路徑下a標簽屬性等於link2.html的內容。
1 2 3 4 5 6 7 8 9 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘/html/body/div/ul/li/a[@href="link2.html"]/text()‘ )
print (html_data)
for i in html_data:
print (i)
打印:
[ ‘second item‘ ]
second item
|
7、上面我們找到全部都是絕對路徑(每一個都是從根開始查找),下面我們查找相對路徑,例如,查找所有li標簽下的a標簽內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘//li/a/text()‘ )
print (html_data)
for i in html_data:
print (i)
打印:
[ ‘first item‘ , ‘second item‘ , ‘third item‘ , ‘fourth item‘ , ‘fifth item‘ ]
first item
second item
third item
fourth item
fifth item
|
8、上面我們使用絕對路徑,查找了所有a標簽的屬性等於href屬性值,利用的是/---絕對路徑,下面我們使用相對路徑,查找一下l相對路徑下li標簽下的a標簽下的href屬性的值,註意,a標簽後面需要雙//。實際測試後,發現a標簽後面單斜杠/也沒有報錯,並輸出相同。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘//li/a//@href‘ )
print (html_data)
for i in html_data:
print (i)
打印:
[ ‘link1.html‘ , ‘link2.html‘ , ‘link3.html‘ , ‘link4.html‘ , ‘link5.html‘ ]
link1.html
link2.html
link3.html
link4.html
link5.html
|
9、相對路徑下跟絕對路徑下查特定屬性的方法類似,也可以說相同。
1 2 3 4 5 6 7 8 9 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘//li/a[@href="link2.html"]‘ )
print (html_data)
for i in html_data:
print (i.text)
打印:
[<Element a at 0x216e468 >]
second item
|
10、查找最後一個li標簽裏的a標簽的href屬性
1 2 3 4 5 6 7 8 9 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘//li[last()]/a/text()‘ )
print (html_data)
for i in html_data:
print (i)
打印:
[ ‘fifth item‘ ]
fifth item
|
11、查找倒數第二個li標簽裏的a標簽的href屬性
1 2 3 4 5 6 7 8 9 |
html = etree.HTML(wb_data)
html_data = html.xpath( ‘//li[last()-1]/a/text()‘ )
print (html_data)
for i in html_data:
print (i)
打印:
[ ‘fourth item‘ ]
fourth item
|
12、如果在提取某個頁面的某個標簽的xpath路徑的話,可以如下圖:
//*[@id="kw"]
解釋:使用相對路徑查找所有的標簽,屬性id等於kw的標簽。
# for i in html_data:
# print(i.text) 或者遍歷時候.text 或者xpath的時候/text(),均可將對象輸出。
# html_data = html.xpath(‘//div/ul/li/a/@href‘) //兩個斜杠的意思是遍歷所有符合要求的全都搜出來。單斜杠的意思是必須連續從屬地一個個找。
# 綜上所述,單斜杠為絕對路徑,雙斜杠為相對路徑,全面查找。text為取出標簽文本值,或者在對象上輸出,或者for循環遍歷.text的形式取出。中括號等同於一種限制條件。@為取出某屬性,比如href的值。
python爬蟲之xpath的基本使用