xpath

1. 认识xml

1.1 html和xml的区别

数据格式 描述 设计目标
XML Extensible Markup Language(可扩展标记语言) 被设计为传输和存储数据,其焦点是数据的内容
HTML HyperText Markup Language(超文本标记语言) 显示数据以及如何更好的显示数据

1.2 xml的树结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>

2. 为什么要学习xpath

网页的解析方式

  1. xpath(简单)
  2. 正则(最难)
  3. css(需要懂网页的css)
  4. bs4(比xpath难一点点)

3. 什么是xpath

XPath,全称 XML Path Language,即 XML 路径语言(通俗一点讲就是通过元素的路径来查找到这个标签元素),它是一门在 XML 文档中查找信息的语言。最初是用来搜寻 XML 文档的,但同样适用于 HTML 文档的搜索。所以在做爬虫时完全可以使用 XPath 做相应的信息抽取。

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

W3School官方文档:http://www.w3school.com.cn/xpath/index.asp

4.xpath语法

XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。

4.1 选取节点

表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取(取子节点)。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置(取子孙节点)。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。

实例

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。

4.2 查找特定的节点-谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式 结果
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=’eng’] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]//title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

4.3 选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式 结果
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。

4.4 选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

路径表达式 结果
//book/title //book/price
//title //price
/bookstore/book/title //price

4.5 文本获取

有两种方法:一是获取文本所在节点后直接获取文本,二是使用 //。

第二种方法会获取到补全代码时换行产生的特殊字符,推荐使用第一种方法,可以保证获取的结果是整洁的。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 第一种
from lxml import etree

html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li[@class="item-0"]/a/text()')
print(result)

# 第二种
from lxml import etree

html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li[@class="item-0"]//text()')
print(result)

4.6 属性获取

在 XPath 语法中,@符号相当于过滤器,可以直接获取节点的属性值:

1
2
3
4
5
6
7
from lxml import etree

html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li/a/@href')
print(result)

# 运行结果:['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']

5 一些示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/元素标签名
例如: //div,查找网页内的所有div

//元素标签名[@属性名='具体内容']
例如: //div[@class='box'],查找classboxdiv

//元素标签名[第几个]
例如: //div[@class='box'][2],查找符合条件的第2个div

//元素1/元素2/元素3...
例如: //ul/li/div/a/img,查找ul下的li下的div下的a下的img标签

//元素1/@属性名
例如://ul/li/div/a/img/@src, 查找ul下的li下的div下的a下的img标签的src属性

//元素/text()
例如://a/text(), 获取a标签之间的文本(一级文本)

//元素//text()
例如://div[@class='box']//text(), 获取classdiv下的所有文本

//元素[contains(@属性名,'相关属性值')]
例如://div[contains(@class,'zhangsan')] 查找class中包含zhangsandiv

//*[@属性='值']
例如://*[@name='lisi']查找所有name为lisi的元素


逻辑运算定位。andor。通过and来缩小过滤的范围,只有条件都符合时才能定位到
//select[@name='city' and @size='4' and @multiple="multiple"]

or就相反了,只要这些筛选中,其中一个出现那么久匹配到了
//select[@name='city' or @size='4']

xpath
https://flepeng.github.io/021-frontend-xpath/
作者
Lepeng
发布于
2021年3月12日
许可协议