Python爬蟲之路-lxml模組

Jiayu920716發表於2021-01-04

資料提取-lxml模組

知識點
  • 瞭解 lxml模組和xpath語法的關係
  • 瞭解 lxml模組的使用場景
  • 瞭解 lxml模組的安裝
  • 瞭解 谷歌瀏覽器xpath helper外掛的安裝和使用
  • 掌握 xpath語法-基礎節點選擇語法
  • 掌握 xpath語法-節點修飾語法
  • 掌握 xpath語法-其他常用語法
  • 掌握 lxml模組中使用xpath語法定位元素提取屬性值或文字內容
  • 掌握 lxml模組中etree.tostring函式的使用

1. 瞭解 lxml模組和xpath語法

對html或xml形式的文字提取特定的內容,就需要我們掌握lxml模組的使用和xpath語法。

  • lxml模組可以利用XPath規則語法,來快速的定位HTML\XML 文件中特定元素以及獲取節點資訊(文字內容、屬性值)
  • XPath (XML Path Language) 是一門在 HTML\XML 文件中查詢資訊的語言,可用來在 HTML\XML 文件中對元素和屬性進行遍歷
  • 提取xml、html中的資料需要lxml模組和xpath語法配合使用

知識點:瞭解 lxml模組和xpath語法

2. 谷歌瀏覽器xpath helper外掛的安裝和使用

要想利用lxml模組提取資料,需要我們掌握xpath語法規則。接下來我們就來了解一下xpath helper外掛,它可以幫助我們練習xpath語法

2.1 谷歌瀏覽器xpath helper外掛的作用

在谷歌瀏覽器中對當前頁面測試xpath語法規則

2.2 谷歌瀏覽器xpath helper外掛的安裝和使用

我們以windos為例進行xpath helper的安裝

2.2.1 xpath helper外掛的安裝

  1. 下載Chrome外掛 XPath Helper

  2. 把檔案的字尾名crx改為rar,然後解壓到同名資料夾中

  3. 把解壓後的資料夾拖入到已經開啟開發者模式的chrome瀏覽器擴充套件程式介面

在這裡插入圖片描述
在這裡插入圖片描述

  1. 重啟瀏覽器後,訪問url之後在頁面中點選xpath圖示,就可以使用了

  2. 如果是linux或macOS作業系統,無需操作上述的步驟2,直接將crx檔案拖入已經開啟開發者模式的chrome瀏覽器擴充套件程式介面


知識點:瞭解 谷歌瀏覽器xpath helper外掛的安裝和使用

3. xpath的節點關係

學習xpath語法需要先了解xpath中的節點關係

3.1 xpath中的節點是什麼

每個html、xml的標籤我們都稱之為節點,其中最頂層的節點稱為根節點。我們以xml為例,html也是一樣的

在這裡插入圖片描述

3.2 xpath中節點的關係

在這裡插入圖片描述

authortitle的第一個兄弟節點

4. xpath語法-基礎節點選擇語法

  1. XPath 使用路徑表示式來選取 XML 文件中的節點或者節點集。
  2. 這些路徑表示式和我們在常規的電腦檔案系統中看到的表示式非常相似。
  3. 使用chrome外掛選擇標籤時候,選中時,選中的標籤會新增屬性class="xh-highlight"

4.1 xpath定位節點以及提取屬性或文字內容的語法

表示式描述
nodename選中該元素。
/從根節點選取、或者是元素和元素間的過渡。
//從匹配選擇的當前節點選擇文件中的節點,而不考慮它們的位置。
.選取當前節點。
選取當前節點的父節點。
@選取屬性。
text()選取文字。

4.2 語法練習

接下來我們通過itcast的頁面來練習上述語法:http://www.itcast.cn/

  • 選擇所有的h2下的文字
    • //h2/text()
  • 獲取所有的a標籤的href
    • //a/@href
  • 獲取html下的head下的title的文字
    • /html/head/title/text()
  • 獲取html下的head下的link標籤的href
    • /html/head/link/@href

知識點:掌握 xpath語法-選取節點以及提取屬性或文字內容的語法

5. xpath語法-節點修飾語法

可以根據標籤的屬性值、下標等來獲取特定的節點

5.1 節點修飾語法

路徑表示式結果
//title[@lang=“eng”]選擇lang屬性值為eng的所有title元素
/bookstore/book[1]選取屬於 bookstore 子元素的第一個 book 元素。
/bookstore/book[last()]選取屬於 bookstore 子元素的最後一個 book 元素。
/bookstore/book[last()-1]選取屬於 bookstore 子元素的倒數第二個 book 元素。
/bookstore/book[position()>1]選擇bookstore下面的book元素,從第二個開始選擇
//book/title[text()=‘Harry Potter’]選擇所有book下的title元素,僅僅選擇文字為Harry Potter的title元素
/bookstore/book[price>35.00]/title選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大於 35.00。

5.2 關於xpath的下標

  • 在xpath中,第一個元素的位置是1
  • 最後一個元素的位置是last()
  • 倒數第二個是last()-1

5.3 語法練習

從itcast的頁面中,選擇所有學科的名稱、第一個學科的連結、最後一個學科的連結:http://www.itcast.cn/

  • 所有的學科的名稱
    • //div[@class="nav_txt"]//a[@class="a_gd"]
  • 第一個學科的連結
    • //div[@class="nav_txt"]/ul/li[1]/a/@href
  • 最後一個學科的連結
    • //div[@class="nav_txt"]/ul/li[last()]/a/@href

知識點:掌握 xpath語法-選取特定節點的語法

6. xpath語法-其他常用節點選擇語法

可以通過萬用字元來選取未知的html、xml的元素

6.1 選取未知節點的語法

萬用字元描述
*匹配任何元素節點。
node()匹配任何型別的節點。

6.2 語法練習

從itcast的頁面中 http://www.itcast.cn/ ,選中全部的標籤、全部的屬性

  • 全部的標籤
    • //*
  • 全部的屬性
    • //node()

知識點:掌握 xpath語法-選取位置節點的語法

7. lxml模組的安裝與使用示例

lxml模組是一個第三方模組,安裝之後使用

7.1 lxml模組的安裝

對傳送請求獲取的xml或html形式的響應內容進行提取

pip/pip3 install lxml
知識點:瞭解 lxml模組的安裝

7.2 爬蟲對html提取的內容

  • 提取標籤中的文字內容
  • 提取標籤中的屬性的值
    • 比如,提取a標籤中href屬性的值,獲取url,進而繼續發起請求

7.3 lxml模組的使用

  1. 匯入lxml 的 etree 庫

    from lxml import etree

  2. 利用etree.HTML,將html字串(bytes型別或str型別)轉化為Element物件,Element物件具有xpath的方法,返回結果的列表

    html = etree.HTML(text) 
    ret_list = html.xpath("xpath語法規則字串")
    
  3. xpath方法返回列表的三種情況

    • 返回空列表:根據xpath語法規則字串,沒有定位到任何元素
    • 返回由字串構成的列表:xpath字串規則匹配的一定是文字內容或某屬性的值
    • 返回由Element物件構成的列表:xpath規則字串匹配的是標籤,列表中的Element物件可以繼續進行xpath

7.4 lxml模組使用示例

執行下面的程式碼,檢視列印的結果

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

html = etree.HTML(text)

#獲取href的列表和title的列表
href_list = html.xpath("//li[@class='item-1']/a/@href")
title_list = html.xpath("//li[@class='item-1']/a/text()")

#組裝成字典
for href in href_list:
    item = {}
    item["href"] = href
    item["title"] = title_list[href_list.index(href)]
    print(item)

8 練習

將下面的html文件字串中,將每個class為item-1的li標籤作為1條新聞資料。提取a標籤的文字內容以及連結,組裝成一個字典。

text = ''' <div> <ul> 
        <li class="item-1"><a>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> '''
  • 注意:

    • 先分組,再提取資料,可以避免資料的錯亂

    • 對於空值要進行判斷

  • 參考程式碼

  from lxml import etree
  text = ''' 
'''

#根據li標籤進行分組

  html = etree.HTML(text)
  li_list = html.xpath("//li[@class='item-1']")

  #在每一組中繼續進行資料的提取
  for li in li_list:
      item = {}
      item["href"] = li.xpath("./a/@href")[0] if len(li.xpath("./a/@href"))>0 else None
      item["title"] = li.xpath("./a/text()")[0] if len(li.xpath("./a/text()"))>0 else None
      print(item)
知識點:掌握 lxml模組中使用xpath語法定位元素提取屬性值或文字內容

10. lxml模組中etree.tostring函式的使用

執行下邊的程式碼,觀察對比html的原字串和列印輸出的結果

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

html = etree.HTML(html_str)

handeled_html_str = etree.tostring(html).decode()
print(handeled_html_str)

10.1 現象和結論

列印結果和原來相比:

  1. 自動補全原本缺失的li標籤
  2. 自動補全html等標籤
<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">fourth item</a></li> 
<li class="item-0"><a href="link5.html">fifth item</a> 
</li></ul> </div> </body></html>

結論

  • lxml.etree.HTML(html_str)可以自動補全標籤

  • lxml.etree.tostring函式可以將轉換為Element物件再轉換回html字串

  • 爬蟲如果使用lxml來提取資料,應該以lxml.etree.tostring的返回結果作為提取資料的依據


知識點:掌握 lxml模組中etree.tostring函式的使用

相關文章