首页 > 解决方案 > 修改 xpath 表达式以获得正确的 etree.getpath() 结果

问题描述

我有很多存储在数据库中的 xpath 表达式,我相信这些表达式是正确的。我面临的问题是,如果不修改它们,我在尝试使用 lxml 获取元素路径时无法获得正确的结果。这是python代码:

def get_elements(response, xpath):

    # Scrapy SelectorList
    elements = response.xpath(xpath)

    if not elements:
        return []

    result = []
    tree = elements[0].root.getroottree()
    for element in elements:
        result.append(tree.getpath(element.root))

    return result

例如,这个 xpath 表达式

`//div[contains(@class, 'class')]//h3//a/@href` 

工作正常,我可以得到值,但不是元素路径。

在这条线上

tree = elements[0].root.getroottree()

它引发了一个错误

str 对象没有属性 getroottree

如果我删除/@href表达式中的最后一个,它将获得元素路径。

对于其他表达式,例如

//div[contains(@class, 'class')]//h3//a/@href|//div[contains(@class, 'another_class')]//h2//a/@href

或者

//h3//a/text()|//strong[contains(@class, 'title')]//a/text()

我需要删除所有内容/@href/text()获得结果。

现在,我像这样修改 xpath 以获得正确的元素:

element_path = "|".join(
        "/".join(r for r in s.split("/") if not (r.startswith('@') or r.endswith('()'))) for s in xpath.split("|")
    )

但是数据库中有很多表达式,例如

.//div[contains(concat(' ', normalize-space(./@class), ' '), ' bref_list ')]//a/@href

修改后会不正确

.//div[contains(concat(' ', normalize-space(.//h2[contains(concat(' ', normalize-space(.//a

并引发 Invalid Xpath 错误,或者像这样

.//article[contains(concat(' ', normalize-space(./@class), ' '), ' post-11508 ')]//span[contains(concat(' ', normalize-space(./@class), ' '), ' posted-on ')] | .//article[(contains(concat(' ', normalize-space(./@class), ' '), ' post ') and (position() >= 3) and (((position() - 3) mod 1) = 0))]//time[contains(concat(' ', normalize-space(./@class), ' '), ' entry-date ')]/text()

那么,是否有任何基本规则或类似的东西可以使用,或者我应该如何修改 xpath 表达式以使其工作?

PS:我无法直接修改数据库中的表达式。

标签: pythonhtmlxpathlxml

解决方案


推荐阅读