Необходим глубокий абсолютный xpath текста также с использованием функции lxml getpath - PullRequest
0 голосов
/ 05 октября 2018

В РИ можно получить желаемые результаты.

library(xml2)
root = read_html("<div><p>abc<br> xyz</p></div>")
elements = xml_find_all(root, "//.")
xml_path(elements)
#> [1] "/"                          "/html"                     
#> [3] "/html/body"                 "/html/body/div"            
#> [5] "/html/body/div/p"           "/html/body/div/p/text()[1]"
#> [7] "/html/body/div/p/br"        "/html/body/div/p/text()[2]"

Требуются узлы
(/ html / body / div / p / text () [1], / html / body / div / p / text () [2]).

В python, когда я использую lxml getpath, я получаю ошибку, потому что некоторые пустые фрагменты текстовых элементов также возвращаются вместе с элементами узла.

root = html.fromstring("<div><p>abc<br> xyz</p></div>")
elements = root.xpath("//.")
xpath_elements = [etree.ElementTree(root).getpath(x) for x in elements]

Но когда я использую использование xpath, заканчивающееся узламиЯ не получу те же результаты, что и при использовании R xml2

root = html.fromstring("<div><p>abc<br> xyz</p></div>")
elements = root.xpath("//*")
xpath_elements = [etree.ElementTree(root).getpath(x) for x in elements]
print(xpath_elements)  

#> ['/html', '/html/body', '/html/body/div', '/div/p', '/div/p/br']

. Как я могу получить желаемый результат xpath, который дает библиотека xml2 R.

1 Ответ

0 голосов
/ 05 октября 2018

In lxml root.xpath(XPATH) возвращает текстовые узлы как строка , а не как Элемент объект.

Вы можете попробовать обходной путь ниже (он все еще не будетработать так же, как на R):

elements = root.xpath("//*[text()]")
xpath_elements = []
for element in elements:
    for text_node in list(element.itertext()):
        if text_node.strip():
            xpath_elements.append(etree.ElementTree(root).getpath(element) + "/text()[%d]" % (list(element.itertext()).index(text_node) + 1))

print(xpath_elements)  # ['/div/p/text()[1]', '/div/p/text()[2]']

PS Поскольку list.index(element) возвращает индекс первого вхождения element, это не будет работать для узла с точно такими же текстовыми узлами, например, <p>QWERTY<br>QWERTY</p>.Это довольно редкий случай, но дайте мне знать, если вам нужно обработать такие случаи также

...