大槐树人家 发表于 2024-12-4 01:17:55

Xpath解析及其语法

XPath解析

XPath(XML Path Language)是一种用于在XML和HTML文档中查找信息的语言,其通过路径表达式来定位节点,属性和文本内容,并支持复杂查询条件,XPath 是许多 Web 抓取工具如 Scrapy,Selenium 等的核心技术之一
XPath 解析的基本步骤


[*]导入lxml.etree
from lxml import etree
[*]使用etree.parse(filename, parser=None)函数返回一个树形结构

[*]etree.parse()用于解析本地XML或HTML文件,并将其转换为一个树形结构即ElementTree对象,可以通过该对象访问文档的各个节点
[*]filename:要解析的文件路径
[*]parser(可选):默认情况下,parser()会根据文件扩展名自动选择合适的解析器,如.xml文件使用XML解析器,.html使用HTML解析器

[*]使用etree.HTML(html_string, parser=None)解析网络html字符串

[*]html_string :要解析的HTML字符串
[*]parser:(可选):默认情况下etree.HTML()使用etree.HTMLparser()进行解析
[*]返回值:etree.HTML()返回一个ELement对象,表示HTML文档的根元素,可以通过该对象访问文档各个节点

[*]使用.xpath(xpath_expression)在已经解析好的HTML文档中执行XPath查询
result = html_tree.xpath(xpath_expression)

[*]xpath_expression:XPath表达式,用于在文档中查找节点,XPath表达式可以是绝对路径或相对路径,也可以包含谓词,函数和轴操作,主要的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-> <lxml.etree._ElementTree object at 0x000001A240107000>

# 使用etree.HTML()解析本地文件或网络动态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-> <Element html at 0x1a23e462880>XPath语法

XPath语法可以用于在XML与HTML文档中查找信息的语言
路径表达式

XPath使用路径表达式来定位文档中的节点,路径也可以分为绝对路径与相对路径
绝对路径


[*]/:表示从根节点开始选择,其用于定义一个绝对路径
从根节点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-> <title>《三国演义》全集在线阅读_史书典籍_诗词名句网</title>相对路径

相比与绝对路径,相对路径使用率更好,更好用


[*]//:表示从当前节点开始,选择文档中所有符合条件的节点,并且不考虑他们的位置
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
#首页
#分类
#作者
#...当前节点


[*]./:表示当前节点,通常用于指明当前节点本身,避免混淆
all_a = root.xpath('//a')
print(all_a.xpath('./text()')) #./表示当前的a标签
#output-> ['首页']选择属性


[*]@:用于选择元素的属性,而不是元素本身
# 使用 @ 选择 <a> 标签的 href 属性
all_hrefs = root.xpath('//a[@href]')
for hrefs in all_hrefs:
    print(etree.tostring(hrefs, encoding='unicode'))XPath谓语

谓语是xpath中用于进一步筛选节点的表达式,通常放在方括号[] 内,其可以基于节点的位置,属性值,文本内容或其他条件来选择特定的节点,谓语可以嵌套使用,也可以与其他谓语组合使用


[*]基本语法
//element

[*]element:要选择的元素
[*]condition:谓语中的条件,用于进一步筛选符合条件的元素

位置谓语

位置谓语用于根据节点在兄弟节点中的位置进行选择,可以使用position()或直接指定位置编号
<ul>获取第一个ul标签中的第一个li标签
#//ul获取的是所有ul,选择第一个
lis = root.xpath('//ul').xpath('./li')
for li in lis:
    print(etree.tostring(li, encoding='unicode'))
#output-> <li><a target="_blank" href="https://www.cnblogs.com/">首页</a></li>使用last()获取最后第一个节点,和导数第二个节点
# 倒一个
last_li = root.xpath('//ul').xpath('./li')
print(etree.tostring(last_li, encoding='unicode'))
# 倒二个
last_second_li = root.xpath('//ul').xpath('./li')
print(etree.tostring(last_second_li, encoding='unicode'))
#output-> <li><a target="_blank" href="https://www.cnblogs.com/app/">安卓下载</a></li>
#<li><a target="_blank" href="https://www.cnblogs.com/book/">古籍</a></li>使用position()获取位置进行筛选
# 获取前两个li标签last_li = root.xpath('//ul').xpath('./li[position()
页: [1]
查看完整版本: Xpath解析及其语法