Python網路解析庫Xpath,媽媽再也不會擔心我不會解析了

〆 小源。發表於2019-03-07

本文同步發表於我的微信公眾號,掃一掃文章底部的二維碼或在微信搜尋 極客導航 即可關注,每個工作日都有文章更新。

一、概況

前兩篇我們把網路庫Requests大概的用法學了一遍,把網站上的每頁資料請求下來是爬蟲的第一步,接下來我們就需要把每頁上對我們有用資料進行提取。提取資料的方式有很多,比如說正則、xpath、bs4等,我們今天就來學一下xpath的語法。

二、Xpath

  • 什麼是xpath? XPath (XML Path Language) 是一門在 XML 文件中查詢資訊的語言,可用來在 XML 文件中對元素和屬性進行遍歷。
  • 什麼是xml?W3School
    • XML 指可擴充套件標記語言(EXtensible Markup Language)
    • XML 是一種標記語言,很類似 HTML
    • XML 的設計宗旨是傳輸資料,而非顯示資料
    • XML 標籤沒有被預定義。您需要自行定義標籤。
    • XML 被設計為具有自我描述性。
    • XML 是 W3C 的推薦標準
  • XML和 HTML 的區別
資料格式 描述 作用
XML 可擴充套件標記語言 用來傳輸和儲存資料
HTML 超文字標記語言 用來顯示資料

3、準備

pip3 install lxml
複製程式碼

4、用法

XPath 使用路徑表示式來選取 XML 文件中的節點或者節點集。這些路徑表示式和我們在常規的電腦檔案系統中看到的表示式非常相似。

表示式 含義
/ 從根節點開始
// 從任意節點
. 從當前節點
.. 從當前節點的父節點
@ 選取屬性
text() 選取文字

案例

from lxml import etree
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" id="1" ><a href="link4.html">fourth item</a></li>
                 <li class="item-0" data="2"><a href="link5.html">fifth item</a>
             </ul>
         </div>
        """

html = etree.HTML(data)#構造了一個XPath解析物件。etree.HTML模組可以自動修正HTML文字。

li_list = html.xpath('//ul/li')#選取ul下面的所有li節點
#li_list = html.xpath('//div/ul/li')#選取ul下面的所有li節點

a_list = html.xpath('//ul/li/a')#選取ul下面的所有a節點
herf_list = html.xpath('//ul/li/a/@href')#選取ul下面的所有a節點的屬性herf的值
text_list = html.xpath('//ul/li/a/text()')#選取ul下面的所有a節點的值
print(li_list)
print(a_list)
print(herf_list)
print(text_list)

#列印
[<Element li at 0x1015f4c48>, <Element li at 0x1015f4c08>, <Element li at 0x1015f4d08>, <Element li at 0x1015f4d48>, <Element li at 0x1015f4d88>]
[<Element a at 0x1015f4dc8>, <Element a at 0x1015f4e08>, <Element a at 0x1015f4e48>, <Element a at 0x1015f4e88>, <Element a at 0x1015f4ec8>]
['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
['first item', 'second item', 'third item', 'fourth item', 'fifth item']
複製程式碼

我們發現最後列印的值都是一個列表物件,如果想取值就可以遍歷列表了。

選取未知節點 XPath 萬用字元可用來選取未知的 XML 元素。

萬用字元 含義
* 選取任何元素節點
@* 選取任何屬性的節點

案例

from lxml import etree
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" id="1" ><a href="link4.html">fourth item</a></li>
                 <li class="item-0" data="2"><a href="link5.html">fifth item</a>
             </ul>
         </div>
        """

html = etree.HTML(data)

li_list = html.xpath('//li[@class="item-0"]')#選取class為item-0的li標籤
text_list = html.xpath('//li[@class="item-0"]/a/text()')#選取class為item-0的li標籤 下面a標籤的值
li1_list  = html.xpath('//li[@id="1"]')#選取id屬性為1的li標籤
li2_list  = html.xpath('//li[@data="2"]')#選取data屬性為2的li標籤
print(li_list)
print(text_list)
print(li1_list)
print(li2_list)

#列印
[<Element li at 0x101dd4cc8>, <Element li at 0x101dd4c88>]
['first item', 'fifth item']
[<Element li at 0x101dd4d88>]
[<Element li at 0x101dd4c88>]

複製程式碼

謂語的一些路徑表示式

表示式 含義
[?] 選取第幾個節點
last() 選取最後一個節點
last()-1 選取倒數第二個節點
position()-1 選取前兩個

案例

from lxml import etree

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" id="1" ><a href="link4.html">fourth item</a></li>
                 <li class="item-0" data="2"><a href="link5.html">fifth item</a>
             </ul>
         </div>
        """

html = etree.HTML(data)

li_list = html.xpath('//ul/li[1]')  # 選取ul下面的第一個li節點
li1_list = html.xpath('//ul/li[last()]')  # 選取ul下面的最後一個li節點
li2_list = html.xpath('//ul/li[last()-1]')  # 選取ul下面的最後一個li節點
li3_list = html.xpath('//ul/li[position()<= 3]')  # 選取ul下面前3個標籤
text_list = html.xpath('//ul/li[position()<= 3]/a/@href')  # 選取ul下面前3個標籤的裡面的a標籤裡面的href的值
print(li_list)
print(li1_list)
print(li2_list)
print(li3_list)
print(text_list)

#列印
[<Element li at 0x1015d3cc8>]
[<Element li at 0x1015d3c88>]
[<Element li at 0x1015d3d88>]
[<Element li at 0x1015d3cc8>, <Element li at 0x1015d3dc8>, <Element li at 0x1015d3e08>]
['link1.html', 'link2.html', 'link3.html']

複製程式碼

五、函式

表示式 含義
starts-with 選取以什麼開頭的元素
contains 選取包含一些資訊的元素
and 並且的關係
or 或者的關係

案例

from lxml import etree

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" id="1" ><a href="link4.html">fourth item</a></li>
                 <li class="item-0" data="2"><a href="link5.html">fifth item</a>
             </ul>
         </div>
        """

html = etree.HTML(data)

li_list = html.xpath('//li[starts-with(@class,"item-1")]')#獲取class包含以item-1開頭的li標籤
li1_list = html.xpath('//li[contains(@class,"item-1")]')#獲取class包含item的li標籤
li2_list = html.xpath('//li[contains(@class,"item-0") and contains(@data,"2")]')#獲取class為item-0並且data為2的li標籤
li3_list = html.xpath('//li[contains(@class,"item-1") or contains(@data,"2")]')#獲取class為item-1或者data為2的li標籤
print(li_list)
print(li1_list)
print(li2_list)
print(li3_list)

#列印
[<Element li at 0x101dcac08>, <Element li at 0x101dcabc8>]
[<Element li at 0x101dcac08>, <Element li at 0x101dcabc8>]
[<Element li at 0x101dcacc8>]
[<Element li at 0x101dcac08>, <Element li at 0x101dcabc8>, <Element li at 0x101dcacc8>]
複製程式碼

以上是Xpath一些常用用法,如果想了解更多的語法可以參考W3School

六、瀏覽器外掛

我們可以在瀏覽器安裝一些xpath外掛,方便我們進行解析資料。

  • Chrome外掛 XPath Helper
  • Firefox外掛 XPath Checker

去瀏覽器擴充套件下載這些外掛,會在瀏覽器左上角看到圖示,如下

外掛
大概使用方法:
使用方法

七、總結

我們把網路庫、解析庫,接下來我們就可以開始真正的爬蟲之旅,後續的文章打算用Requests和Xpath爬取幾個網站。

歡迎關注我的公眾號,我們一起學習。

關注我

相關文章