12.lxml模塊

lxml模塊

知識(shí)點(diǎn)
  • 了解 lxml模塊和xpath語(yǔ)法的關(guān)系
  • 了解 lxml模塊的使用場(chǎng)景
  • 了解 lxml模塊的安裝
  • 了解 谷歌瀏覽器xpath helper插件的安裝和使用
  • 掌握 xpath語(yǔ)法-基礎(chǔ)節(jié)點(diǎn)選擇語(yǔ)法
  • 掌握 xpath語(yǔ)法-節(jié)點(diǎn)修飾語(yǔ)法
  • 掌握 xpath語(yǔ)法-其他常用語(yǔ)法
  • 掌握 lxml模塊中使用xpath語(yǔ)法定位元素提取屬性值或文本內(nèi)容
  • 掌握 lxml模塊中etree.tostring函數(shù)的使用

1. 了解 lxml模塊和xpath語(yǔ)法

對(duì)html或xml形式的文本提取特定的內(nèi)容,就需要我們掌握l(shuí)xml模塊的使用和xpath語(yǔ)法。

  • lxml模塊可以利用XPath規(guī)則語(yǔ)法,來(lái)快速的定位HTML\XML 文檔中特定元素以及獲取節(jié)點(diǎn)信息(文本內(nèi)容、屬性值)
  • XPath (XML Path Language) 是一門在 HTML\XML 文檔中查找信息的語(yǔ)言,可用來(lái)在 HTML\XML 文檔中對(duì)元素和屬性進(jìn)行遍歷
  • 提取xml、html中的數(shù)據(jù)需要lxml模塊和xpath語(yǔ)法配合使用

知識(shí)點(diǎn):了解 lxml模塊和xpath語(yǔ)法

2. 谷歌瀏覽器xpath helper插件的安裝和使用

要想利用lxml模塊提取數(shù)據(jù),需要我們掌握xpath語(yǔ)法規(guī)則。接下來(lái)我們就來(lái)了解一下xpath helper插件,它可以幫助我們練習(xí)xpath語(yǔ)法

2.1 谷歌瀏覽器xpath helper插件的作用

在谷歌瀏覽器中對(duì)當(dāng)前頁(yè)面測(cè)試xpath語(yǔ)法規(guī)則

2.2 谷歌瀏覽器xpath helper插件的安裝和使用

我們以windos為例進(jìn)行xpath helper的安裝

2.2.1 xpath helper插件的安裝

  1. 下載Chrome插件 XPath Helper

  2. 把文件的后綴名crx改為rar,然后解壓到同名文件夾中

  3. 把解壓后的文件夾拖入到已經(jīng)開(kāi)啟開(kāi)發(fā)者模式的chrome瀏覽器擴(kuò)展程序界面

xpath_helper插件安裝-1.png
xpath_helper插件安裝-2.png
  1. 重啟瀏覽器后,訪問(wèn)url之后在頁(yè)面中點(diǎn)擊xpath圖標(biāo),就可以使用了
xpath_helper插件安裝-3.png
  1. 如果是linux或macOS操作系統(tǒng),無(wú)需操作上述的步驟2,直接將crx文件拖入已經(jīng)開(kāi)啟開(kāi)發(fā)者模式的chrome瀏覽器擴(kuò)展程序界面

知識(shí)點(diǎn):了解 谷歌瀏覽器xpath helper插件的安裝和使用

3. xpath的節(jié)點(diǎn)關(guān)系

學(xué)習(xí)xpath語(yǔ)法需要先了解xpath中的節(jié)點(diǎn)關(guān)系

3.1 xpath中的節(jié)點(diǎn)是什么

每個(gè)html、xml的標(biāo)簽我們都稱之為節(jié)點(diǎn),其中最頂層的節(jié)點(diǎn)稱為根節(jié)點(diǎn)。我們以xml為例,html也是一樣的

節(jié)點(diǎn).png

3.2 xpath中節(jié)點(diǎn)的關(guān)系

xpath中節(jié)點(diǎn)的關(guān)系.png

authortitle的第一個(gè)兄弟節(jié)點(diǎn)

4. xpath語(yǔ)法-基礎(chǔ)節(jié)點(diǎn)選擇語(yǔ)法

  1. XPath 使用路徑表達(dá)式來(lái)選取 XML 文檔中的節(jié)點(diǎn)或者節(jié)點(diǎn)集。
  2. 這些路徑表達(dá)式和我們?cè)诔R?guī)的電腦文件系統(tǒng)中看到的表達(dá)式非常相似。
  3. 使用chrome插件選擇標(biāo)簽時(shí)候,選中時(shí),選中的標(biāo)簽會(huì)添加屬性class="xh-highlight"

4.1 xpath定位節(jié)點(diǎn)以及提取屬性或文本內(nèi)容的語(yǔ)法

表達(dá)式 描述
nodename 選中該元素。
/ 從根節(jié)點(diǎn)選取、或者是元素和元素間的過(guò)渡。
// 從匹配選擇的當(dāng)前節(jié)點(diǎn)選擇文檔中的節(jié)點(diǎn),而不考慮它們的位置。
. 選取當(dāng)前節(jié)點(diǎn)。
.. 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。
@ 選取屬性。
text() 選取文本。

4.2 語(yǔ)法練習(xí)

接下來(lái)我們通過(guò)itcast的頁(yè)面來(lái)練習(xí)上述語(yǔ)法:http://www.itcast.cn/

  • 選擇所有的h2下的文本
    • //h2/text()
  • 獲取所有的a標(biāo)簽的href
    • //a/@href
  • 獲取html下的head下的title的文本
    • /html/head/title/text()
  • 獲取html下的head下的link標(biāo)簽的href
    • /html/head/link/@href

知識(shí)點(diǎn):掌握 xpath語(yǔ)法-選取節(jié)點(diǎn)以及提取屬性或文本內(nèi)容的語(yǔ)法

5. xpath語(yǔ)法-節(jié)點(diǎn)修飾語(yǔ)法

可以根據(jù)標(biāo)簽的屬性值、下標(biāo)等來(lái)獲取特定的節(jié)點(diǎn)

5.1 節(jié)點(diǎn)修飾語(yǔ)法

路徑表達(dá)式 結(jié)果
//title[@lang="eng"] 選擇lang屬性值為eng的所有title元素
/bookstore/book[1] 選取屬于 bookstore 子元素的第一個(gè) book 元素。
/bookstore/book[last()] 選取屬于 bookstore 子元素的最后一個(gè) book 元素。
/bookstore/book[last()-1] 選取屬于 bookstore 子元素的倒數(shù)第二個(gè) book 元素。
/bookstore/book[position()>1] 選擇bookstore下面的book元素,從第二個(gè)開(kāi)始選擇
//book/title[text()='Harry Potter'] 選擇所有book下的title元素,僅僅選擇文本為Harry Potter的title元素
/bookstore/book[price>35.00]/title 選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大于 35.00。

5.2 關(guān)于xpath的下標(biāo)

  • 在xpath中,第一個(gè)元素的位置是1
  • 最后一個(gè)元素的位置是last()
  • 倒數(shù)第二個(gè)是last()-1

5.3 語(yǔ)法練習(xí)

從itcast的頁(yè)面中,選擇所有學(xué)科的名稱、第一個(gè)學(xué)科的鏈接、最后一個(gè)學(xué)科的鏈接:http://www.itcast.cn/

  • 所有的學(xué)科的名稱
    • //div[@class="nav_txt"]//a[@class="a_gd"]
  • 第一個(gè)學(xué)科的鏈接
    • //div[@class="nav_txt"]/ul/li[1]/a/@href
  • 最后一個(gè)學(xué)科的鏈接
    • //div[@class="nav_txt"]/ul/li[last()]/a/@href

知識(shí)點(diǎn):掌握 xpath語(yǔ)法-選取特定節(jié)點(diǎn)的語(yǔ)法

6. xpath語(yǔ)法-其他常用節(jié)點(diǎn)選擇語(yǔ)法

可以通過(guò)通配符來(lái)選取未知的html、xml的元素

6.1 選取未知節(jié)點(diǎn)的語(yǔ)法

通配符 描述
* 匹配任何元素節(jié)點(diǎn)。
node() 匹配任何類型的節(jié)點(diǎn)。

6.2 語(yǔ)法練習(xí)

從itcast的頁(yè)面中 http://www.itcast.cn/ ,選中全部的標(biāo)簽、全部的屬性

  • 全部的標(biāo)簽
    • //*
  • 全部的屬性
    • //node()

知識(shí)點(diǎn):掌握 xpath語(yǔ)法-選取位置節(jié)點(diǎn)的語(yǔ)法

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

lxml模塊是一個(gè)第三方模塊,安裝之后使用

7.1 lxml模塊的安裝

對(duì)發(fā)送請(qǐng)求獲取的xml或html形式的響應(yīng)內(nèi)容進(jìn)行提取

pip/pip3 install lxml
知識(shí)點(diǎn):了解 lxml模塊的安裝

7.2 爬蟲(chóng)對(duì)html提取的內(nèi)容

  • 提取標(biāo)簽中的文本內(nèi)容
  • 提取標(biāo)簽中的屬性的值
    • 比如,提取a標(biāo)簽中href屬性的值,獲取url,進(jìn)而繼續(xù)發(fā)起請(qǐng)求

7.3 lxml模塊的使用

  1. 導(dǎo)入lxml 的 etree 庫(kù)

    from lxml import etree

  2. 利用etree.HTML,將html字符串(bytes類型或str類型)轉(zhuǎn)化為Element對(duì)象,Element對(duì)象具有xpath的方法,返回結(jié)果的列表

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

    • 返回空列表:根據(jù)xpath語(yǔ)法規(guī)則字符串,沒(méi)有定位到任何元素
    • 返回由字符串構(gòu)成的列表:xpath字符串規(guī)則匹配的一定是文本內(nèi)容或某屬性的值
    • 返回由Element對(duì)象構(gòu)成的列表:xpath規(guī)則字符串匹配的是標(biāo)簽,列表中的Element對(duì)象可以繼續(xù)進(jìn)行xpath

7.4 lxml模塊使用示例

運(yùn)行下面的代碼,查看打印的結(jié)果

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("http://li[@class='item-1']/a/@href")
title_list = html.xpath("http://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 練習(xí)

爬取百度貼吧內(nèi)任意吧的帖子標(biāo)題跟相應(yīng)網(wǎng)址鏈接

  • 注意:

    • 分頁(yè)
  • 參考代碼

import requests
from lxml import etree

class tieba:
   def __init__(self, word):
       self.word = word
       self.url = "https://tieba.baidu.com/f?kw={}".format(self.word)
       print(self.url)
       self.headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) '
       }
   def get_data(self, url):
       response = requests.get(url, headers = self.headers)
       return response.content

   def parse_data(self, data):
       # 創(chuàng)建element對(duì)象
       html = etree.HTML(data)
       el_list = html.xpath('//li[@class=" j_thread_list clearfix"]/div/div[2]/div[1]/div[1]/a')
       # 檢查是否獲取到
       # print(len(el_list))
       data_list = []
       for i in el_list:
           a = {}
           a['title'] = i.xpath("./text()")[0]
           a['herf'] = 'http://tieba.baidu.com' + i.xpath('./@href')[0]
           data_list.append(a)
       try:
           next_url = 'http:' + html.xpath('//*[contains(text(),"下一頁(yè)>")]/@href')[0]
       except:
           next_url = None
       return data_list, next_url

   def save_data(self, data_list):
       for data in data_list:
           print(data)


   def run(self):
       #url
       next_url = self.url
       #headers
       while True:
           # 發(fā)送列表請(qǐng)求,獲取響應(yīng)
           list_page_data = self.get_data(next_url)

           # 解析列表頁(yè)面的響應(yīng),提取帖子列表數(shù)據(jù)和下一頁(yè)url
           data_list, next_url = self.parse_data(list_page_data)
           self.save_data(data_list)
           # 翻頁(yè)&循環(huán)終止條件
           if next_url == None:
               break



if __name__ == '__main__':
   word = input("輸入想要爬取的貼吧名稱:")
   tieba = tieba(word)
   tieba.run()


知識(shí)點(diǎn):掌握 lxml模塊中使用xpath語(yǔ)法定位元素提取屬性值或文本內(nèi)容

9. lxml模塊中etree.tostring函數(shù)的使用

運(yùn)行下邊的代碼,觀察對(duì)比html的原字符串和打印輸出的結(jié)果

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)

9.1 現(xiàn)象和結(jié)論

打印結(jié)果和原來(lái)相比:

  1. 自動(dòng)補(bǔ)全原本缺失的li標(biāo)簽
  2. 自動(dòng)補(bǔ)全html等標(biāo)簽
<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>

結(jié)論

  • lxml.etree.HTML(html_str)可以自動(dòng)補(bǔ)全標(biāo)簽

  • lxml.etree.tostring函數(shù)可以將轉(zhuǎn)換為Element對(duì)象再轉(zhuǎn)換回html字符串

  • 爬蟲(chóng)如果使用lxml來(lái)提取數(shù)據(jù),應(yīng)該以lxml.etree.tostring的返回結(jié)果作為提取數(shù)據(jù)的依據(jù)


知識(shí)點(diǎn):掌握 lxml模塊中etree.tostring函數(shù)的使用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容