您的位置:首頁(yè) > 軟件教程 > 教程 > Xpath解析及其語(yǔ)法

Xpath解析及其語(yǔ)法

來(lái)源:好特整理 | 時(shí)間:2024-12-04 10:15:46 | 閱讀:120 |  標(biāo)簽: a T XP   | 分享到:

XPath解析 XPath(XML Path Language)是一種用于在XML和HTML文檔中查找信息的語(yǔ)言,其通過(guò)路徑表達(dá)式來(lái)定位節(jié)點(diǎn),屬性和文本內(nèi)容,并支持復(fù)雜查詢條件,XPath 是許多 Web 抓取工具如 Scrapy,Selenium 等的核心技術(shù)之一 XPath 解析的基本步驟 導(dǎo)入

XPath解析

XPath(XML Path Language)是一種用于在XML和HTML文檔中查找信息的語(yǔ)言,其通過(guò)路徑表達(dá)式來(lái)定位節(jié)點(diǎn),屬性和文本內(nèi)容,并支持復(fù)雜查詢條件,XPath 是許多 Web 抓取工具如 Scrapy,Selenium 等的核心技術(shù)之一

XPath 解析的基本步驟

  1. 導(dǎo)入lxml.etree

    from lxml import etree
    
  2. 使用etree.parse(filename, parser=None)函數(shù)返回一個(gè)樹形結(jié)構(gòu)

    • etree.parse() 用于解析本地XML或HTML文件,并將其轉(zhuǎn)換為一個(gè)樹形結(jié)構(gòu)即 ElementTree 對(duì)象,可以通過(guò)該對(duì)象訪問(wèn)文檔的各個(gè)節(jié)點(diǎn)
    • filename :要解析的文件路徑
    • parser (可選):默認(rèn)情況下,parser()會(huì)根據(jù)文件擴(kuò)展名自動(dòng)選擇合適的解析器,如 .xml 文件使用XML解析器,.html使用HTML解析器
  3. 使用etree.HTML(html_string, parser=None)解析網(wǎng)絡(luò)html字符串

    • html_string :要解析的HTML字符串
    • parser :(可選):默認(rèn)情況下 etree.HTML() 使用 etree.HTMLparser() 進(jìn)行解析
    • 返回值 :etree.HTML()返回一個(gè) ELement 對(duì)象,表示HTML文檔的 根元素 ,可以通過(guò)該對(duì)象訪問(wèn)文檔各個(gè)節(jié)點(diǎn)
  4. 使用.xpath(xpath_expression)在已經(jīng)解析好的HTML文檔中執(zhí)行XPath查詢

    result = html_tree.xpath(xpath_expression)
    
    • xpath_expression :XPath表達(dá)式,用于在文檔中查找節(jié)點(diǎn),XPath表達(dá)式可以是絕對(duì)路徑或相對(duì)路徑,也可以包含謂詞,函數(shù)和軸操作,主要的XPath語(yǔ)法下面會(huì)展開(kāi)講解
    • html_tree :可以是 ElementTree 對(duì)象(由 etree.parse() 返回)或 Element 對(duì)象(由 etree.HTML() 返回)
from lxml import etree

# 使用etree.parser()解析文件路徑
parser = etree.HTMLParser(encoding='utf-8')  # 以u(píng)tf8進(jìn)行編碼
tree = etree.parse('../Learning02/三國(guó)演義.html', parser=parser)
print(tree)
#output-> 

# 使用etree.HTML()解析本地文件或網(wǎng)絡(luò)動(dòng)態(tài)HTML
# 讀取文件 解析為字符串
file = open('../Learning02/三國(guó)演義.html', 'r', encoding='utf-8')
data = file.read()
root = etree.HTML(data)
print(root)

#整合
root = etree.HTML(open('../Learning02/三國(guó)演義.html', 'r', encoding='utf-8').read())
print(root)
#output-> 

XPath語(yǔ)法

XPath 語(yǔ)法可以用于在XML與HTML文檔中查找信息的語(yǔ)言

路徑表達(dá)式

XPath使用路徑表達(dá)式來(lái)定位文檔中的節(jié)點(diǎn),路徑也可以分為絕對(duì)路徑與相對(duì)路徑

絕對(duì)路徑

  • / :表示從根節(jié)點(diǎn)開(kāi)始選擇,其用于定義一個(gè)絕對(duì)路徑

從根節(jié)點(diǎn)html開(kāi)始查找到head,再?gòu)膆ead下找出title標(biāo)簽

root = etree.HTML(open('../Learning02/三國(guó)演義.html', 'r', encoding='utf-8').read())
all_titles = root.xpath('/html/head/title')
for title in all_titles:
    print(etree.tostring(title, encoding='utf-8').decode('utf-8'))
#output-> 《三國(guó)演義》全集在線閱讀_史書典籍_詩(shī)詞名句網(wǎng)

相對(duì)路徑

相比與絕對(duì)路徑,相對(duì)路徑使用率更好,更好用

  • // :表示從 當(dāng)前節(jié)點(diǎn)開(kāi)始, 選擇文檔中 所有符合條件的節(jié)點(diǎn), 并且不考慮他們的位置
root = etree.HTML(open('../Learning02/三國(guó)演義.html', 'r', encoding='utf-8').read())
all_a = root.xpath('//a')
for a in all_a:
    print(a.text)
#None
#首頁(yè)
#分類
#作者
#...

當(dāng)前節(jié)點(diǎn)

  • ./ :表示當(dāng)前節(jié)點(diǎn),通常用于指明當(dāng)前節(jié)點(diǎn)本身,避免混淆
all_a = root.xpath('//a')
print(all_a[1].xpath('./text()')) #./表示當(dāng)前的a標(biāo)簽
#output-> ['首頁(yè)']

選擇屬性

  • @ :用于選擇元素的屬性,而不是元素本身
# 使用 @ 選擇  標(biāo)簽的 href 屬性
all_hrefs = root.xpath('//a[@href]')
for hrefs in all_hrefs:
    print(etree.tostring(hrefs, encoding='unicode'))

XPath謂語(yǔ)

謂語(yǔ)是 xpath 中用于進(jìn)一步篩選節(jié)點(diǎn)的表達(dá)式,通常放在方括號(hào) [] 內(nèi),其可以基于節(jié)點(diǎn)的位置,屬性值,文本內(nèi)容或其他條件來(lái) 選擇特定的節(jié)點(diǎn),謂語(yǔ)可以嵌套使用,也可以與其他謂語(yǔ)組合使用

  • 基本語(yǔ)法

    //element[condition]
    
    • element :要選擇的元素
    • condition :謂語(yǔ)中的條件,用于進(jìn)一步篩選符合條件的元素

位置謂語(yǔ)

位置謂語(yǔ)用于根據(jù)節(jié)點(diǎn)在兄弟節(jié)點(diǎn)中的位置進(jìn)行選擇,可以使用 position() 或直接指定位置編號(hào)

  • 獲取第一個(gè) ul 標(biāo)簽中的第一個(gè) li 標(biāo)簽

    #//ul獲取的是所有ul,[0]選擇第一個(gè)
    lis = root.xpath('//ul')[0].xpath('./li[1]')
    for li in lis:
        print(etree.tostring(li, encoding='unicode'))
    #output-> 
  • 首頁(yè)
  • 使用 last() 獲取最后第一個(gè)節(jié)點(diǎn),和導(dǎo)數(shù)第二個(gè)節(jié)點(diǎn)

    # 倒一個(gè)
    last_li = root.xpath('//ul')[0].xpath('./li[last()]')
    print(etree.tostring(last_li[0], encoding='unicode'))
    # 倒二個(gè)
    last_second_li = root.xpath('//ul')[0].xpath('./li[last()-1]')
    print(etree.tostring(last_second_li[0], encoding='unicode'))
    #output-> 
  • 安卓下載
  • #
  • 古籍
  • 使用 position() 獲取位置進(jìn)行篩選

    # 獲取前兩個(gè)li標(biāo)簽
    last_li = root.xpath('//ul')[0].xpath('./li[position()<3]')
    for li in last_li:
        print(etree.tostring(li, encoding='unicode'))
    # 獲取偶數(shù)位標(biāo)簽
    lis = root.xpath('//ul')[0].xpath('./li[position() mod 2=0]')
    for li in lis:
        print(etree.tostring(li, encoding='unicode'))
    
  • 屬性謂語(yǔ)

    屬性謂語(yǔ)用于 選擇具體特定屬性的節(jié)點(diǎn)

    • 使用 @attribute 來(lái)獲取屬性名稱,結(jié)合條件進(jìn)行篩選
    # 選取所有具有 href 屬性的 a 元素
    hrefs = root.xpath("http://a[@href]")
    for href in hrefs:
        print(etree.tostring(href, encoding='unicode'))
    
    • 查找 class 屬性值
    all_class = root.xpath('//@class')
    print(all_class)
    
  • 組合謂語(yǔ)

    將多個(gè)條件組合在一起,使用邏輯運(yùn)算符 and,or 等來(lái)創(chuàng)建更復(fù)雜的謂語(yǔ)

    #選取href屬性值為https://example.com且class屬性值為link的a元素
    //a[@href='https://example.com' and @class='link']
    
    #選取href屬性值為https://example.comhttps://another.com的a 元素
    //a[@href='https://example.com' or @href='https://another.com']
    
  • 函數(shù)謂語(yǔ)

    Xpath提供了許多內(nèi)置函數(shù),來(lái)應(yīng)對(duì)更復(fù)雜的篩選條件

    • contains((string1, string2) 函數(shù):

      • string1 :要搜索的字符串
      • string2 :要查找的字符串
      # 選取class包含"book"的img標(biāo)簽
      images = root.xpath('//img[contains(@src,"book")]')
      for image in images:
          print(etree.tostring(image, encoding='unicode'))
      
    • starts-with(string1, string2) 函數(shù):

      檢查一個(gè)字符串是否以指定字符的前綴開(kāi)始,是返回 true ,否返回 false

      • string1: 要檢查的字符串
      • string2: 作為前綴的字符串
      # 選取所有href以https://開(kāi)頭的a標(biāo)簽
      all_a = root.xpath('//a[starts-with(@href,"https:")]')
      for a in all_a:
          print(etree.tostring(a, encoding='unicode'))
      
  • 文本內(nèi)容謂語(yǔ)

    用于選擇包含特定文本內(nèi)容的節(jié)點(diǎn),可以使用 text() 函數(shù)來(lái)提取節(jié)點(diǎn)的文本內(nèi)容

    # 選擇使用包含"三國(guó)"文本的p標(biāo)簽
    paragraphs = root.xpath('//p[contains(text(),"三國(guó)")]')
    for p in paragraphs:
        print(etree.tostring(p, encoding='unicode'))
    

通配符

xpath提供了多種通配符,用于在路徑表達(dá)式中匹配未知的元素,屬性,或任何節(jié)點(diǎn).這些通配符非常有用,尤其是當(dāng)不確定具體節(jié)點(diǎn)名稱和結(jié)構(gòu)的情況下

通配符 描述
* 匹配任何元素節(jié)點(diǎn)。 一般用于瀏覽器copy xpath會(huì)出現(xiàn)
@* 匹配任何屬性節(jié)點(diǎn)。
node() 匹配任何類型的節(jié)點(diǎn)。

使用 * 匹配任何元素節(jié)點(diǎn)

  • * 是最常用的通配符之一,其可以匹配任何元素,而不需要具體標(biāo)簽名.這在不確定元素名稱或希望選擇所有類型的元素時(shí)非常有用
# 選擇所有 div 下的所有子元素
divs = root.xpath("http://div/*")
for div in divs:
    print(etree.tostring(div, encoding='unicode'))

使用 @* 匹配任何屬性節(jié)點(diǎn)

  • @* 用于匹配任何屬性節(jié)點(diǎn),而不用指定具體屬性名稱,在你不確定屬性名稱或希望選擇所有屬性時(shí)非常有用
# 選擇所有 a 元素的所有屬性
all_a = root.xpath('//a/@*')
for a in all_a:
    print(a)

使用 node() 匹配任何類型的節(jié)點(diǎn)

  • node() 是一個(gè)更通用的通配符,其能匹配任何類型節(jié)點(diǎn),包括元素節(jié)點(diǎn),文本節(jié)點(diǎn),屬性節(jié)點(diǎn),注釋節(jié)點(diǎn)等等,其在需要選擇不僅僅是元素節(jié)點(diǎn)是十分有用
# 選擇所有 ul 下的所有子節(jié)點(diǎn)(包括文本節(jié)點(diǎn))
nodes = root.xpath('//ul/node()')
print(nodes)
#output-> ['\n ', , '\n,...] 

XPath,re正則,BeautifulSoup對(duì)比

在之前的學(xué)習(xí)中我們首先學(xué)習(xí)了re正則表達(dá)式,其次學(xué)習(xí)了更加便捷的bs4,哪為何還要學(xué)習(xí)XPath解析呢,接下來(lái)我們將它們的優(yōu)點(diǎn)和適用場(chǎng)景進(jìn)行對(duì)比學(xué)習(xí)

工具 優(yōu)點(diǎn) 缺點(diǎn) 適用場(chǎng)景
XPath 強(qiáng)大的路徑表達(dá)能力,支持層級(jí)結(jié)構(gòu)和條件查詢 學(xué)習(xí)曲線較陡,對(duì)不規(guī)范 HTML 容錯(cuò)性較差 結(jié)構(gòu)化良好的 XML/HTML,復(fù)雜查詢
re 靈活性高,適合處理純文本中的模式匹配 不適合解析 HTML/XML,可讀性差 從純文本中提取特定模式的數(shù)據(jù)
BeautifulSoup 易于使用,容錯(cuò)性強(qiáng),適合初學(xué)者 性能稍低,功能有限 不規(guī)范的 HTML,簡(jiǎn)單數(shù)據(jù)提取,網(wǎng)頁(yè)抓取
  • 總結(jié)
    • 若需要處理結(jié)構(gòu)良好的XML或HTML文檔,并需要進(jìn)行復(fù)雜查詢 ,那么XPath解析是最佳選擇
    • 若需要從純文本中提取特定模式的數(shù)據(jù)時(shí) ,如從日志中提取日期,IP地址的,re正則表達(dá)式是最佳選擇
    • 需要解析不規(guī)范的 HTML 或者只需要進(jìn)行簡(jiǎn)單的數(shù)據(jù)提取, BeautifulSoup 是最友好的選擇
小編推薦閱讀

好特網(wǎng)發(fā)布此文僅為傳遞信息,不代表好特網(wǎng)認(rèn)同期限觀點(diǎn)或證實(shí)其描述。

a 1.0
a 1.0
類型:休閑益智  運(yùn)營(yíng)狀態(tài):正式運(yùn)營(yíng)  語(yǔ)言:中文   

游戲攻略

游戲禮包

游戲視頻

游戲下載

游戲活動(dòng)

《alittletotheleft》官網(wǎng)正版是一款備受歡迎的休閑益智整理游戲。玩家的任務(wù)是對(duì)日常生活中的各種雜亂物

相關(guān)視頻攻略

更多

掃二維碼進(jìn)入好特網(wǎng)手機(jī)版本!

掃二維碼進(jìn)入好特網(wǎng)微信公眾號(hào)!

本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請(qǐng)發(fā)郵件[email protected]

湘ICP備2022002427號(hào)-10 湘公網(wǎng)安備:43070202000427號(hào)© 2013~2025 haote.com 好特網(wǎng)