使用 XPath 和 CSS 选择器查询数据

CSS 选择器是用于选择元素的模式,通常用于定义应应用样式的元素。它们还可与 lxml 结合使用,以选择 DOM 中的节点。CSS 选择器比 XPath 更简洁,在代码中的可重用性也更高,因此很常用。可使用的常用选择器示例如下 的例子如下:

您在寻找什么 例子

所有标签

*

特定标签(即 tr)

.planet

类名(即 "planet")

tr.planet

一个 ID 为 "planet3" 的标签

tr#planet3

表格的子项 tr

table tr

表的后代 tr

table tr

带有属性的标签(即 id="planet4" 的 tr)。

a[id=Mars]

准备工作

让我们使用上一个食谱中的启动代码开始研究 CSS 选择器。这些代码片段也在 02/04_css_selectors.py 中。

In [1]: from lxml import html
...: import requests
...: page_html = requests.get("http://localhost:8080/planets.html").text
...: tree = html.fromstring(page_html)
...:

如何做

现在,让我们开始使用 XPath 和 CSS 选择器。下面的代码选择所有 <tr> 类等于 "planet" 的元素:

In [2]: [(v, v.xpath("@name")) for v in tree.cssselect('tr.planet')]
Out[2]:
[(<Element tr at 0x10d3a2278>, ['Mercury']),
(<Element tr at 0x10c16ed18>, ['Venus']),
(<Element tr at 0x10e445688>, ['Earth']),
(<Element tr at 0x10e477228>, ['Mars']),
(<Element tr at 0x10e477408>, ['Jupiter']),
(<Element tr at 0x10e477458>, ['Saturn']),
(<Element tr at 0x10e4774a8>, ['Uranus']),
(<Element tr at 0x10e4774f8>, ['Neptune']),
(<Element tr at 0x10e477548>, ['Pluto'])]

地球的数据可以通过几种方式找到。下面的方法是根据 id 获取行:

In [3]: tr = tree.cssselect("tr#planet3")
...: tr[0], tr[0].xpath("./td[2]/text()")[0].strip()
...:
Out[3]: (<Element tr at 0x10e445688>, 'Earth')

下面使用的是具有特定值的属性:

In [4]: tr = tree.cssselect("tr[name='Pluto']")
...: tr[0], tr[0].xpath("td[2]/text()")[0].strip()
...:
Out[5]: (<Element tr at 0x10e477548>, 'Pluto')

请注意,与 XPath 不同,@ 符号不必用于指定属性。

工作原理

lxml 会将你提供的 CSS 选择器转换为 XPath,然后针对底层文档执行 XPath 表达式。实质上,lxml 中的 CSS 选择器为 XPath 提供了一个 简写,这使得查找符合特定模式的节点比使用 XPath。

还有更多

由于 CSS 选择器隐藏了 XPath,因此与直接使用 XPath 相比,使用 CSS 选择器会产生一些开销。不过,这种差异几乎不是问题,因此在某些情况下 因此在某些情况下,使用 cssselect 更为简单。

有关 CSS 选择器的完整说明,请访问: https://www.w3.org/TR/2011/RECcss3-selectors-20110929/