首页 > 其他分享 >lxml与XPath

lxml与XPath

时间:2023-01-07 14:44:46浏览次数:54  
标签:XPath lxml value html print 节点

lxml与XPath

​ 尽管正则表达式处理字符串的能力非常强,但编写功能强大的正则表达式并不容易,而且难以维护,复杂的正则表达式也并不容易理解

​ 幸好还有其他的方式处理字符串,这就是 XPath

​ XPath 以非常容易理解的路径方式选择 XML 和 HTML 中的节点,容易编写和维护;目前支持 XPath 的库非常多,lxml 就是其中一个

lxml

​ lxml 是 Python 的一个解析库,用于解析 HTML 和 XML,支持 XPath 解析方式;并且由于 lxml 底层是 C 语言编写的,所以解析效率非常高

安装 lxml

​ lxml 官网:https://lxml.de/

​ lxml 在 GitHub 的地址:https://github.com/lxml/lxml

​ 这里只介绍在 Windows 下的安装方法:执行pip install lxml安装命令即可;lxml 安装完成后即可通过import lxml导入依赖

操作 xml

​ lxml 可以读取 xml 文件,也可以使用字符串形式的 xml 文档;如果读取 xml 文件,需要使用 parse 函数,该函数需要传入一个 xml 文件名;如果要解析字符串形式的 xml 文档,需要使用 fromstring 函数,该函数的参数就是 xml 字符串,eg:

​ 准备一个 xml 文件(products.xml),内容如下:

<products>
	<product id="0001">
		<name>phone</name>
		<price>4500</price>
	</product>
	<product>
		<name>computer</name>
		<price>6000</price>
	</product>
</products>

​ 读取 products.xml 文件(文件与代码在同一目录下)

from lxml import etree

# 读取 products.xml 文件
tree = etree.parse('products.xml')

print(type(tree))
# 将 tree 转换为字符串形式的 xml 文档并输出
print(str(etree.tostring(tree, encoding='utf-8'), 'utf-8'))
# 获取根节点对象
root = tree.getroot()

print(type(root))
# 获取根节点名称并输出
print(root.tag)
# 获取根节点所有子节点
childrens = root.getchildren()

for children in childrens:
    print(children.get('id'))
    print(children[0].text)
    print(children[1].text)

​ 解析字符串形式的 xml 文档

from lxml import etree

root = etree.fromstring('''
<products>
	<product id="0001">
		<name>phone</name>
		<price>4500</price>
	</product>
	<product id="0002">
		<name>computer</name>
		<price>6000</price>
	</product>
</products>
''')
print(type(root))
print(root.tag)
childrens = root.getchildren()
for children in childrens:
    print(children.get('id'))
    print(children[0].text)
    print(children[1].text)

​ 使用 lxml 库也可以操作 HTML 文档,HTML 本质上与 XML 类似,它们所不同的是 XML 除了这些节点,不能有其他东西,而 HTML 的语法比较自由,不仅可以有节点,还可以有其他任何文本

​ 用 lxml 库操作 HTML 的方式与操作 XML 非常类似,同样可以通过 getroot 方法获取根节点,通过 get 方法获得节点属性值,通过 text 属性获取节点内容,通过索引的方式引用子节点,eg:

​ 准备一个 test.html 文件(与代码在同一目录下),内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body></body>
</html>

​ 解析 html

from lxml import etree

# 获取 HTMLParser 对象
html_parser = etree.HTMLParser()

print(type(html_parser))
# 读取并解析 test.html 文件
tree = etree.parse('test.html', html_parser)
# 获取根节点
root = tree.getroot()
# 获取 html 文档内容
result = etree.tostring(root, encoding='utf-8', pretty_print=True, method='html')
# 将文档转换为可读形式并输出
print(str(result, 'utf-8'))

print(root.tag)
print(root.get('lang'))
print(root[0][0].get('charset'))
print(root[0][1].text)

XPath

​ XPath 的功能非常强大,它提供了非常简单的路径选择表达式;另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等;几乎所有想定位的节点,都可以用 XPath 来选择

​ XPath 于1999年11月16日成为 W3C 标准,它被设计为可以在 XSLT、XPointer 以及其他 XML 解析软件中使用

​ 官方文档:https://www.w3.org/TR/xpath-31

​ XPath 的基本语法规则:

XPath 语法规则 描述
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前节点选取子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性

​ 从文件装载,通过 parse 函数指定 HTML 文件名;eg(还是解析上面的 test.html 文件):

from lxml import etree

html_parser = etree.HTMLParser()
tree = etree.parse('test.html', html_parser)
# 使用 xpath 定位 title 节点,返回一个集合
titles = tree.xpath('/html/head/title')

if len(titles) > 0:
    print(titles[0].text)

​ 从代码装载,通过 HTML 函数指定 HTML 代码,eg:

from lxml import etree

html = '''
<div>
    <ul>
        <li class="item1"><a href="https://geekori.com">geekori.com</a></li>
        <li class="item2"><a href="https://www.jd.com">京东</a></li>
        <li class="item3"><a href="https://www.taobao.com">淘宝</a></li>
    </ul>
</div>
'''
# 分析 html 代码
tree = etree.HTML(html)
# 使用 xpath 定位 class 属性值为 item2 的<li>节点
a_tags = tree.xpath("//li[@class='item2']")

if len(a_tags) > 0:
    print(a_tags[0][0].get('href'), a_tags[0][0].text)

注意:通过 XPath 定位节点返回的是节点集合,即使只有一个节点,返回的也是一个节点集合;使用 XPath 分析的 HTML 文档并不一定是标准的

​ 选取所有节点

// 开头的 XPath 规则会选取所有符合要求的节点,如果使用//*那么会选取整个 HTML 文档中的所有节点

​ 选取子节点

​ 在选取子节点时,通常会将///规则放在一起使用,eg://li/a表示选取 li 节点下的 a 节点

​ 选取父节点

​ 如果知道子节点,想得到父节点,可以使用..,eg://a[@class='class1']/..可以得到 class 属性为 class1 的 a 节点的父节点;得到父节点还可以使用parent::*,所以这个例子也可以使用//a[@class='class1']/parent::*

# 获取 href 属性值为 https://www.jd.com 的 a 节点的父节点的 class 属性值
result = tree.xpath('//a[@href="https://www.jd.com"]/../@class')
result = tree.xpath('//a[@href="https://www.jd.com"]/parent::*/@class')

​ 属性匹配与获取

# 获取所有 href 属性值包含 www 的 a 节点
nodes = tree.xpath('//a[contains(@href,"www")]')

​ 多属性匹配

# 获取所有 href 属性值为 https://www.jd.com 或 https://geekori.com 的 a 节点
node_list = tree.xpath('//a[@href="https://www.jd.com" or @href="https://geekori.com"]')
# 获取 href 属性值包含 www,并且父节点中 value 属性值等于 1234 的 a 节点
node_list = tree.xpath('//a[contains(@href,"www") and ../@value="1234"]')

​ XPath 中的运算符及其描述:

运算符 描述 实例 返回值
| 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集
+ 加法 10 + 5 15
- 减法 10 - 5 5
* 乘法 10 * 5 50
div 除法 10 div 5 2
= 等于 value = 218 如果 value 是218,返回 true,否则返回 false
!= 不等于 value != 218 如果 value 不是218,返回 true,否则返回 false
< 小于 value < 218 如果 value 小于218,返回 true,否则返回 false
<= 小于或等于 value <= 218 如果 value 小于或等于218,返回 true,否则返回 false
> 大于 value > 218 如果 value 大于218,返回 true,否则返回 false
>= 大于或等于 value >= 218 如果 value 大于或等于218,返回 true,否则返回 false
or value = 20 or value = 30 如果 value 等于20或30,返回 true,否则返回 false
and value = 20 and age = 19 如果 value 等于20并且 age 等于30,返回 true,否则返回 false
mod 取余 10 mod 3 1

​ 扩展

​ 在 Chrome 中自动获取 XPath 代码

​ 尽管 XPath 代码写起来要比正则表达式简单,但遇到复杂的节点,写起来仍然比较费劲;很多浏览器提供了自动获取 XPath 代码的能力,可以在自动获取 XPath 代码的基础上修改,很多时候甚至不需要修改就可以直接使用;eg:

​ 通过 Chrome 浏览器中的开发者工具定位到指定元素,选择对应的 HTML 代码,然后右击,选择 Copy->Copy XPath 即可将当前选中的 HTML 代码对应的 XPath 代码复制到剪贴板

​ 使用 Chrome 验证 XPath

​ 在浏览器控制台输入对应代码可定位到指定元素(如果元素存在),eg:

$x('//*[@id="s_tab"]/div/b')

​ $x 用来运行 XPath 函数,参数需要指定 XPath 代码

标签:XPath,lxml,value,html,print,节点
From: https://www.cnblogs.com/Y-wee/p/17032595.html

相关文章

  • python_selenium元素定位_xpath(2)
     selenium自动化脚本最基础的就是元素定位和元素操作,下面就以百度为例介绍最常见的xpath定位方式基本定位方式:以百度的搜索框为例fromseleniumimportwebdriverim......
  • 一步一步学爬虫(3)网页解析之xpath语法
    (一步一步学爬虫(3)网页解析之xpath语法)3.1网页解析之xpath语法  XPath,全称是XMLPathLanguage,即XML路径语言,它是一门在XML文档中查找信息的语言。它最初是用来搜......
  • sun.security.validator.ValidatorException: PKIXpath building failed: sun.securit
    报错信息:javax.net.ssT.SSLHandshakeExceptions.certpath.SunCertPathBuilderException:unabletofindvalidcertificationpathtoreguestedtarget问题描述:在ja......
  • C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)
    阅读目录1.HtmlAgilityPack简介2.XPath技术介绍与使用3.采集天气网站案例4.资源第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一......
  • 使用xpath爬取对应百度贴吧下面的帖子图片
    hello,小伙伴们,上次给大家分享了如何使用python的正则匹配爬取百思不得姐的网站代码,虽然说正则匹配爬取网站的执行效率高,但是正则匹配的规则编写着实是令人头痛的一件事。今......
  • 爬虫之 xPath 用法总结整理
    在网络爬虫中,对于HTML的解析,XPath是一种常用的方法。XPath最初是用于XML中,其主要使用路径表达式在XML文档中进行导航。用于HTML中主要是因为HTML和XML非常的相似:它们具有......
  • lxml案例~豆瓣版生日星空图片下载的源码
    有不少小伙伴反应,昨天更新的NASA的源码在运行的时候出错了,出现:其实小编当时也遇到了这个错误,当时去网上搜了下说是可能会和网络有问题,因为网站本身就是个国外的网站,后来增加......
  • Python中使用xpath一键获取各国国旗
    国旗是一个国家的主权意识不断增强后必然的产物,国旗是国家的一种标志性旗帜,是国家的象征。代表着一个国家的主权和民族的尊严。每个国家的国旗都由特有的颜色和图案构成,这些......
  • 通讯录系统(控制台+dom4j+xPath+xml)
    设计一个通讯录程序    联系人: 编号  姓名  性别  年龄  电话  QQ 邮箱    功能要求:        添加联系人    ......
  • 爬虫学习笔记 -- 实战某电影网(lxml库版)
    0x01安装lxml库文件pip3installlxml0x02初始化字符串1、通过HTML类初始化字符串fromlxmlimportetreeimportrequestsurl="https://www.dandanzan10.top/dianying/i......