如何在lxml.html xpath中使用正则表达式



我正在尝试选择一个具有@ID的特定元素,该元素可能是任何非负整数。因此,我尝试使用Regex,看起来像:

response = get(url)
HTML_str = response.content
parser = html.fromstring(HTML_str)
search_string = r'./td[2]/span[re:match(id(), "^d+$")]/text()'
l_spans_tags = parser.xpath(search_string, namespaces={'re': 'http://exslt.org/regular-expressions'})

但是,结果是:

XPathEvalError: Invalid number of arguments

我知道,这种方法可能对XML文件有益,而不是HTML文件(也通过使用Etree对象 - 此处未使用(。有人可以指出如何使用LXML在HTML文件上使用Regex?

编辑:我需要的不是属性ID,而是属性类。查找标签为: <span class="158"><span class="19">

我认为问题不是由您使用"扩展"函数re:match来使用正则表达式而引起的,而是您使用表达式id(),因为这是对XPath 1的调用名为 id的函数期望一个参数:https://www.w3.org/tr/xpath-10/#function-id虽然尚未提供一个。

我不确定您要使用什么,也许您想选择所选span元素的id属性,这些元素可以与@id一起使用,例如。span[re:match(@id, "^d+$")]

根据您的评论,您要检查属性节点对正则表达式的值,因此您只需要知道XPath中名为id的属性节点是由@id选择的,而不是您的尝试id()或该属性。名为class的属性节点是由@class选择的,而不是您在评论中显示的 @class()

总而言之,您的原始问题中的错误以及评论中的代码中的错误都与尝试使用扩展函数re:match的尝试无关,但仅由错误的语法引起,以选择属性节点:使用例如@id@class要这样做。

我试图用@ID检测一个可以是任何整数的特定标签。

任何整数?即使是负面一个?

search_string = r'./td[2]/span[re:match(id(), "^d+$")]/text()'

尝试使用函数(在这种情况下为id()(选择属性

是不正确的

选择是上下文(当前(节点的元素的someAttribute,使用:

@someAttribute

您还想断言此属性的值是整数。这可以在纯XPath 1.0中完成,而无需使用任何扩展功能。当$m的值是整数时,以下XPATH表达式准确评估true()

$m = floor($m)

因此,这些组合并用于替换原始表达式中的谓词给予我们:

search_string = r'./td[2]/span[@id = floor(@id)]/text()'

并且,如果id必须是一个非负整数(如提供的正则命令所暗示的(,则使用:

search_string = r'./td[2]/span[@id >= 0 and @id = floor(@id)]/text()'

使用这些表达式会导致更便携,可能更有效的代码。


update :OP更新了问题,说他需要根据class属性的值而不是id属性选择。

在这种情况下,以上两个表达式将更改为以下内容:

search_string = r'./td[2]/span[@class = floor(@class )]/text()'

search_string = r'./td[2]/span[@class >= 0 and @class = floor(@class )]/text()'

最新更新