python学习笔记 | xpath
关于lxml
lxml是python的一个解析库,支持「HTML」和「XML」的解析,支持xpath解析方式,而且解析效率非常高。
1. 安装
-
Windows/macOS
pip3 install lxml
-
Linux
yum install -y epel-release libxslt-devel libxml2-devel openssl-devel pip3 install lxml
2. 导入
from lxml import etree
3. 解析为文档树
etree.parse(source, parser=None, base_url=None)
- Return an ElementTree object loaded with source elements.
- source - 文件名\路径、文件对象、url
- parser - 例:
etree.XMLParser()
、etree.HTMLParser()
等,如不设置则使用默认的parser - base_url -
etree.XML(text, parser=None, base_url=None)
- Parses an XML document or fragment from a string constant.
- text - byte类型
- parser -
- base_url -
etree.HTML(text, parser=None, base_url=None)
- Parses an HTML document from a string constant. Returns the root node (or the result returned by a parser target).
- text -
- parser -
- base_url -
etree.fromstring(text, parser=None, base_url=None)
- Parses an XML document or fragment from a string.
4. 文档树的一些方法
etree.tostring(element_or_tree, encoding=None, ...)
- 解析成字节
etree.tostringlist(element_or_tree, ...)
- 解析成列表
关于xpath
XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。
XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择。
XPath于1999年11月16日成为W3C标准,它被设计为供XSLT、XPointer以及其他XML解析软件使用,更多的文档可以访问其官方网站:https://www.w3.org/TR/xpath/
- XPath 使用路径表达式在 XML 文档中进行导航
- XPath 包含一个标准函数库
- XPath 是 XSLT 中的主要元素
- XPath 是一个 W3C 标准
推荐阅读
- http://www.zvon.org/xxl/XPathTutorial/General_chi/examples.html
- https://docs.microsoft.com/zh-cn/previous-versions/dotnet/netframework-2.0/ms256471(v=vs.80)
- https://www.cnblogs.com/zhaozhan/archive/2009/09/11/1564420.html
1. xpath方法
lxml.etree._ElementTree.xpath(_path)
- 使用lxml提供的这个方法可以对文档树对象进行解析,从而获取节点信息,此方法返回结果的类型均为「list」
eleTree = etree.HTML(text)
html = eleTree.xpath(' ') # ' '中的规则如下
2. xpath选取节点
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 根节点 |
// | 从匹配的当前节点选择后代中所有符合的节点,而不考虑它们的位置 |
. | 当前节点 |
.. | 当前节点的父节点 |
@ | 属性 |
[] | 条件检索 |
* | 通配符,表示该路径下的所有元素,例//* (选择所有元素),@* 匹配任何属性的节点 |
3. xpath运算符
运算符 | 描述 | 实例 |
---|---|---|
| | 多个路径选择的并集 | `//p |
+ | 加法 | |
- | 减法 | |
* | 乘法 | |
div | 除法 | |
= | 等于 | |
!= | 不等于 | |
< | 小于 | |
<= | 小于或等于 | |
> | 大于 | //div/li[position() > 3] |
>= | 大于或等于 | |
or | 或 | |
and | 与 | //div[contains(@id,"test") and contains(@id,"title")] |
mod | 计算除法的余数 |
4. xpath谓语(Predicates)
被嵌在方括号[]中的条件语句,可以理解为xpath语法中的谓语,用来查找符合条件的「某个特定的节点或者包含某个指定的值的节点」。
表达式 | 描述 |
---|---|
[ ] | 条件检索 |
//div/li[1] |
选取div节点下第一个li节点 |
//div/li[last()] |
选取div节点下最后一个li节点 |
//div/li[position()<3] |
选取div节点下前两个li节点 |
//div/li[@GOD] |
选取div节点下所有拥有GOD属性的li节点 |
5. xpath谓语函数
XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择。 XPath 函数改进 了XPath 查询,并提高 XPath 的编程能力和灵活性。
推荐阅读 - XPath、XQuery 以及 XSLT 函数函数参考手册
-
text()
xpath('//div/text()') # 功能强大,是我觉得最powerful的一个功能 xpath('//div[text() = "黄卡特"]') # 条件检索
-
contains()
- 包含指定的元素xpath('//div/ul/li[contains(text(),"列表1")]') # 等同于上面的用法2 xpath('//div/ul/li[contains(@id,"conleyhuang")]')
-
not()
- 否定xpath('//div[not(text()="全村的笋都让你夺完了")]')
-
starts-with()
- 获取以str开头的元素xpath('//div[stars-with(@class,"test")]')
-
last()
- 最后一个节点xpath('//div/li[last()]') # 选择div下最后一个li节点 xpath('//div/li[last()-1]') # 选择div下倒数第二个li节点
-
position()
- 位置节点xpath('//div/li[position() = 1]') # 选择所有li中的第一个 xpath('//div/li[position() > 3]') # 选择所有li中第三个之后的
-
count()
- 节点数量 -
sum()
- 节点的数值总和 -
avg()
- 参数平均值 -
max()
- 最大的参数 -
min()
- 最小的参数
6. xpath轴(Axes)
XPath轴(XPath Axes)可定义某个相对于当前节点的节点集
表达式 | 描述 |
---|---|
child | 选取当前节点的所有子元素 |
parent | 选取当前节点的父节点 |
descendant | 选取当前节点的所有后代元素(子、孙等) |
ancestor | 选取当前节点的所有先辈(父、祖父等) |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身 |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身 |
preceding-sibling | 选取当前节点之前的所有同级节点 |
following-sibling | 选取当前节点之后的所有同级节点 |
preceding | 选取文档中当前节点的开始标签之前的所有节点 |
following | 选取文档中当前节点的结束标签之后的所有节点 |
self | 选取当前节点 |
attribute | 选取当前节点的所有属性 |
namespace | 选取当前节点的所有命名空间节点。名称空间轴用来选取名称空间结点。每个元素结点都有一个专门名称空间结点表示每个作用域名称空间。 |
# 获取p标签下所有的a标签的href值
xpath('//*[@id="PageContent_C006_Col01"]/div[1]/div/p/descendant::a/@href')
# 获取位置为四的li节点的所有属性值
xpath('//li[position()=4]/attribute::*')
# from maersk
xpath(f'//a[contains(text(),"{sub_num}")]/../../td[2]/input')
# 获取文本为冻结的td标签同级之后的td标签的子标签中文本为查看的a标签的onclick属性值 😄
xpath('//td[text()="冻结"]/following-sibling::td/a[text()="查看"]/@onclick')[0]
# 获取span标签的先辈tr标签
driver.find_..._xpath(f"//span[contains(text(),'{yhzh}')]/ancestor::tr")