使用lxml.html的cssselect选择ID属性中带有冒号的元素

3 投票
2 回答
2912 浏览
提问于 2025-04-17 08:17

我在一个页面上有一个元素,看起来是这样的:

<a id="cid-694094:Comment:188384" name="694094:Comment:188384"></a>

如果你执行 document.cssselect("#cid-694094:Comment:188384"),你会得到:

lxml.cssselect.ExpressionError: 伪类 Symbol(u'Comment', 12) 是未知的

解决这个问题的方法可以在 这个问题 中找到(那个人使用的是Java)。

但是,当我在Python中尝试这样做时:

document.cssselect(r"#cid-694094\:Comment\:188384")

我得到:

lxml.cssselect.SelectorSyntaxError: 错误符号 'cid-694094\': 'unicodeescape' 编解码器无法解码字节 0x5c 在位置 10: \ 在字符串末尾 [Token(u'#', 0)] -> None

这个错误的原因和一个建议的解决方案可以在 这个问题 中找到。如果我理解得没错,我应该这样做:

document.cssselect(r"#cid-694094\\:Comment\\:188384")

但是这仍然不行。相反,我再次得到了:

lxml.cssselect.ExpressionError: 伪类 Symbol(u'Comment\', 14) 是未知的

有没有人能告诉我我哪里做错了?

你可以自己试试:

import lxml.html
document = lxml.html.fromstring(
    '<a id="cid-694094:Comment:188384" name="694094:Comment:188384"></a>'
)
document.cssselect(r"#cid-694094\:Comment\:188384")

2 个回答

1

: 通常在 ID 选择器中是不允许使用的,确实有正确的方法来处理它:

document.cssselect(r"#cid-694094\:Comment\:188384")

不过,直到最近,选择器解析器的功能真的很糟糕。(它实际上并没有正确实现反斜杠转义。)我在 cssselect 0.7 中修复了这个问题,现在它已经成为一个独立的项目,从 lxml 中提取出来。

http://packages.python.org/cssselect/

现在使用它的方法稍微复杂一些:

import cssselect
document.xpath(cssselect.HTMLTranslator().css_to_xpath('#cid-694094\:Comment\:188384'))

lxml 2.4(还没有发布)将会使用新的 cssselect,这样更简单的语法也能正常工作。

4

难道在CSS中,:这个符号不可以用在ID或类名里吗?你可以查看这个链接了解更多信息:CSS类名中允许使用的字符

不过,这里有个解决办法:

document.xpath('//a[@id="cid-694094:Comment:188384"]')

撰写回答