在R中,我可以获得预期的结果。
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']
当R的xml2库生成时,如何生成所需的xpath结果。
答案 0 :(得分:1)
在lxml
root.xpath(XPATH)
中,文本节点以 string 的形式返回,而不是以 Element 对象的形式返回。
您可以尝试以下解决方法(它仍然无法像在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]']
P.S。当list.index(element)
返回第一个element
出现的索引时,这不适用于文本节点完全相同的节点,例如<p>QWERTY<br>QWERTY</p>
。这是一种极为罕见的情况,但请告知我是否也需要处理此类情况