XPath解析 XPath(XML Path Language)是一種用于在XML和HTML文檔中查找信息的語言,其通過路徑表達式來定位節(jié)點,屬性和文本內(nèi)容,并支持復雜查詢條件,XPath 是許多 Web 抓取工具如 Scrapy,Selenium 等的核心技術(shù)之一 XPath 解析的基本步驟 導入
XPath(XML Path Language)是一種用于在XML和HTML文檔中查找信息的語言,其通過路徑表達式來定位節(jié)點,屬性和文本內(nèi)容,并支持復雜查詢條件,XPath 是許多 Web 抓取工具如
Scrapy,Selenium
等的核心技術(shù)之一
導入lxml.etree
from lxml import etree
使用etree.parse(filename, parser=None)函數(shù)返回一個樹形結(jié)構(gòu)
etree.parse()
用于解析本地XML或HTML文件,并將其轉(zhuǎn)換為一個樹形結(jié)構(gòu)即
ElementTree
對象,可以通過該對象訪問文檔的各個節(jié)點
filename
:要解析的文件路徑
parser
(可選):默認情況下,parser()會根據(jù)文件擴展名自動選擇合適的解析器,如
.xml
文件使用XML解析器,.html使用HTML解析器
使用etree.HTML(html_string, parser=None)解析網(wǎng)絡(luò)html字符串
html_string
:要解析的HTML字符串
parser
:(可選):默認情況下
etree.HTML()
使用
etree.HTMLparser()
進行解析
ELement
對象,表示HTML文檔的
根元素
,可以通過該對象訪問文檔各個節(jié)點
使用.xpath(xpath_expression)在已經(jīng)解析好的HTML文檔中執(zhí)行XPath查詢
result = html_tree.xpath(xpath_expression)
xpath_expression
:XPath表達式,用于在文檔中查找節(jié)點,XPath表達式可以是絕對路徑或相對路徑,也可以包含謂詞,函數(shù)和軸操作,主要的XPath語法下面會展開講解
html_tree
:可以是
ElementTree
對象(由 etree.parse() 返回)或
Element
對象(由 etree.HTML() 返回)
from lxml import etree
# 使用etree.parser()解析文件路徑
parser = etree.HTMLParser(encoding='utf-8') # 以utf8進行編碼
tree = etree.parse('../Learning02/三國演義.html', parser=parser)
print(tree)
#output->
# 使用etree.HTML()解析本地文件或網(wǎng)絡(luò)動態(tài)HTML
# 讀取文件 解析為字符串
file = open('../Learning02/三國演義.html', 'r', encoding='utf-8')
data = file.read()
root = etree.HTML(data)
print(root)
#整合
root = etree.HTML(open('../Learning02/三國演義.html', 'r', encoding='utf-8').read())
print(root)
#output->
XPath
語法可以用于在XML與HTML文檔中查找信息的語言
XPath使用路徑表達式來定位文檔中的節(jié)點,路徑也可以分為絕對路徑與相對路徑
/
:表示從根節(jié)點開始選擇,其用于定義一個絕對路徑
從根節(jié)點html開始查找到head,再從head下找出title標簽
root = etree.HTML(open('../Learning02/三國演義.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-> 《三國演義》全集在線閱讀_史書典籍_詩詞名句網(wǎng)
相比與絕對路徑,相對路徑使用率更好,更好用
//
:表示從
當前節(jié)點開始,
選擇文檔中
所有符合條件的節(jié)點,
并且不考慮他們的位置
root = etree.HTML(open('../Learning02/三國演義.html', 'r', encoding='utf-8').read())
all_a = root.xpath('//a')
for a in all_a:
print(a.text)
#None
#首頁
#分類
#作者
#...
./
:表示當前節(jié)點,通常用于指明當前節(jié)點本身,避免混淆
all_a = root.xpath('//a')
print(all_a[1].xpath('./text()')) #./表示當前的a標簽
#output-> ['首頁']
@
:用于選擇元素的屬性,而不是元素本身
# 使用 @ 選擇 標簽的 href 屬性
all_hrefs = root.xpath('//a[@href]')
for hrefs in all_hrefs:
print(etree.tostring(hrefs, encoding='unicode'))
謂語是
xpath
中用于進一步篩選節(jié)點的表達式,通常放在方括號[]
內(nèi),其可以基于節(jié)點的位置,屬性值,文本內(nèi)容或其他條件來 選擇特定的節(jié)點,謂語可以嵌套使用,也可以與其他謂語組合使用
基本語法
//element[condition]
element
:要選擇的元素
condition
:謂語中的條件,用于進一步篩選符合條件的元素
位置謂語用于根據(jù)節(jié)點在兄弟節(jié)點中的位置進行選擇,可以使用
position()
或直接指定位置編號
獲取第一個
ul
標簽中的第一個
li
標簽
#//ul獲取的是所有ul,[0]選擇第一個
lis = root.xpath('//ul')[0].xpath('./li[1]')
for li in lis:
print(etree.tostring(li, encoding='unicode'))
#output-> - 首頁
使用
last()
獲取最后第一個節(jié)點,和導數(shù)第二個節(jié)點
# 倒一個
last_li = root.xpath('//ul')[0].xpath('./li[last()]')
print(etree.tostring(last_li[0], encoding='unicode'))
# 倒二個
last_second_li = root.xpath('//ul')[0].xpath('./li[last()-1]')
print(etree.tostring(last_second_li[0], encoding='unicode'))
#output-> - 安卓下載
#- 古籍
使用
position()
獲取位置進行篩選
# 獲取前兩個li標簽
last_li = root.xpath('//ul')[0].xpath('./li[position()<3]')
for li in last_li:
print(etree.tostring(li, encoding='unicode'))
# 獲取偶數(shù)位標簽
lis = root.xpath('//ul')[0].xpath('./li[position() mod 2=0]')
for li in lis:
print(etree.tostring(li, encoding='unicode'))
屬性謂語
屬性謂語用于 選擇具體特定屬性的節(jié)點
@attribute
來獲取屬性名稱,結(jié)合條件進行篩選
# 選取所有具有 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)
組合謂語
將多個條件組合在一起,使用邏輯運算符
and,or
等來創(chuàng)建更復雜的謂語
#選取href屬性值為https://example.com且class屬性值為link的a元素
//a[@href='https://example.com' and @class='link']
#選取href屬性值為https://example.com或https://another.com的a 元素
//a[@href='https://example.com' or @href='https://another.com']
函數(shù)謂語
Xpath提供了許多內(nèi)置函數(shù),來應(yīng)對更復雜的篩選條件
contains((string1, string2)
函數(shù):
string1
:要搜索的字符串
string2
:要查找的字符串
# 選取class包含"book"的img標簽
images = root.xpath('//img[contains(@src,"book")]')
for image in images:
print(etree.tostring(image, encoding='unicode'))
starts-with(string1, string2)
函數(shù):
檢查一個字符串是否以指定字符的前綴開始,是返回
true
,否返回false
string1:
要檢查的字符串
string2:
作為前綴的字符串
# 選取所有href以https://開頭的a標簽
all_a = root.xpath('//a[starts-with(@href,"https:")]')
for a in all_a:
print(etree.tostring(a, encoding='unicode'))
文本內(nèi)容謂語
用于選擇包含特定文本內(nèi)容的節(jié)點,可以使用
text()
函數(shù)來提取節(jié)點的文本內(nèi)容
# 選擇使用包含"三國"文本的p標簽
paragraphs = root.xpath('//p[contains(text(),"三國")]')
for p in paragraphs:
print(etree.tostring(p, encoding='unicode'))
xpath提供了多種通配符,用于在路徑表達式中匹配未知的元素,屬性,或任何節(jié)點.這些通配符非常有用,尤其是當不確定具體節(jié)點名稱和結(jié)構(gòu)的情況下
通配符 | 描述 |
---|---|
* | 匹配任何元素節(jié)點。 一般用于瀏覽器copy xpath會出現(xiàn) |
@* | 匹配任何屬性節(jié)點。 |
node() | 匹配任何類型的節(jié)點。 |
*
匹配任何元素節(jié)點
*
是最常用的通配符之一,其可以匹配任何元素,而不需要具體標簽名.這在不確定元素名稱或希望選擇所有類型的元素時非常有用
# 選擇所有 div 下的所有子元素
divs = root.xpath("http://div/*")
for div in divs:
print(etree.tostring(div, encoding='unicode'))
@*
匹配任何屬性節(jié)點
@*
用于匹配任何屬性節(jié)點,而不用指定具體屬性名稱,在你不確定屬性名稱或希望選擇所有屬性時非常有用
# 選擇所有 a 元素的所有屬性
all_a = root.xpath('//a/@*')
for a in all_a:
print(a)
node()
匹配任何類型的節(jié)點
node()
是一個更通用的通配符,其能匹配任何類型節(jié)點,包括元素節(jié)點,文本節(jié)點,屬性節(jié)點,注釋節(jié)點等等,其在需要選擇不僅僅是元素節(jié)點是十分有用
# 選擇所有 ul 下的所有子節(jié)點(包括文本節(jié)點)
nodes = root.xpath('//ul/node()')
print(nodes)
#output-> ['\n ', , '\n,...]
在之前的學習中我們首先學習了re正則表達式,其次學習了更加便捷的bs4,哪為何還要學習XPath解析呢,接下來我們將它們的優(yōu)點和適用場景進行對比學習
工具 | 優(yōu)點 | 缺點 | 適用場景 |
---|---|---|---|
XPath
|
強大的路徑表達能力,支持層級結(jié)構(gòu)和條件查詢 | 學習曲線較陡,對不規(guī)范 HTML 容錯性較差 | 結(jié)構(gòu)化良好的 XML/HTML,復雜查詢 |
re
|
靈活性高,適合處理純文本中的模式匹配 | 不適合解析 HTML/XML,可讀性差 | 從純文本中提取特定模式的數(shù)據(jù) |
BeautifulSoup
|
易于使用,容錯性強,適合初學者 | 性能稍低,功能有限 | 不規(guī)范的 HTML,簡單數(shù)據(jù)提取,網(wǎng)頁抓取 |
機器學習:神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實現(xiàn)對象集合與DataTable的相互轉(zhuǎn)換
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細使用
閱讀Java代理模式:靜態(tài)代理和動態(tài)代理的對比分析
閱讀Win11筆記本“自動管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請發(fā)郵件[email protected]
湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2025 haote.com 好特網(wǎng)