如何以优雅的方式递归解析 LXML?
How do I parse with LXML recursively in an elegant way?
例如,考虑以下 HTML:
<div class="class1">
<div id="element1">
text1
</div>
<div id="element2">
text2
</div>
<div id="element3">
text3
</div>
</div>
我想要实现的是解析不同的元素,哪些属性是已知的。
我现在的做法:
index = len(tree.xpath('//div[@class="class1"]')
for i in range(0, index):
print tree.xpath('//div[@class="class1"][i]/text()')
但是当涉及到较长的 xpath 时,它会变得有点混乱。
还有其他方法吗?
编辑-
例如,
first_elem = tree.xpath('//div[@class="class1"]')[0]
是否可以这样做:
first_elem.xpath()
在 <div id="element1">
中搜索?
编辑-
在 lxml 中找到了执行此操作的奇怪方法:
for i in tree.xpath('//div[@class="class1"]'):
str1 = html.tostring(i)
tree = html.fromstring(str1)
< do things here >
您可以使用 starts-with
得到 div
其中 id
以 element
开头
for i in tree.xpath("//div[starts-with(@id, 'element')]/text()"):
print(i.strip())
这会产生
text1
text2
text3
您的 xpath
似乎是错误的,当您这样做时 -
tree.xpath('//div[@class="class1"][i]/text()')
i
不会在内部自动被替换。在任何情况下,你都不需要做你正在做的事情,tree.xpath
会 return 所有匹配元素的列表,你可以简单地使用你想要的 xpath(即使它会产生多个元素) ,然后遍历结果并打印出来。示例(或您正在尝试做的事情)-
for i in tree.xpath('//div[@class="class1"]/div/text()'):
print i
这应该打印主 div 中每个 div
内的文本,属性 class
为 class1
。
你甚至不需要它,如果你知道一种唯一标识元素的方法(使用 attributes/indexing 等),你可以直接使用它,例如,获取 [=19= 的文本] , 使用 -
for i in tree.xpath('//div[@id="element1"]/text()'):
print i
此外,您的 xml 似乎有很多不需要的换行符和空格,您可以通过调用 i.strip()
去除它们。
如果你想得到一个元素的所有子元素,我推荐使用iter()
:
for element in tree.iter():
print element.text.strip()
输出:
text1
text2
text3
您还可以定义标记名tree.iter(tag="div")
例如,考虑以下 HTML:
<div class="class1">
<div id="element1">
text1
</div>
<div id="element2">
text2
</div>
<div id="element3">
text3
</div>
</div>
我想要实现的是解析不同的元素,哪些属性是已知的。
我现在的做法:
index = len(tree.xpath('//div[@class="class1"]')
for i in range(0, index):
print tree.xpath('//div[@class="class1"][i]/text()')
但是当涉及到较长的 xpath 时,它会变得有点混乱。 还有其他方法吗?
编辑-
例如,
first_elem = tree.xpath('//div[@class="class1"]')[0]
是否可以这样做:
first_elem.xpath()
在 <div id="element1">
中搜索?
编辑-
在 lxml 中找到了执行此操作的奇怪方法:
for i in tree.xpath('//div[@class="class1"]'):
str1 = html.tostring(i)
tree = html.fromstring(str1)
< do things here >
您可以使用 starts-with
得到 div
其中 id
以 element
for i in tree.xpath("//div[starts-with(@id, 'element')]/text()"):
print(i.strip())
这会产生
text1
text2
text3
您的 xpath
似乎是错误的,当您这样做时 -
tree.xpath('//div[@class="class1"][i]/text()')
i
不会在内部自动被替换。在任何情况下,你都不需要做你正在做的事情,tree.xpath
会 return 所有匹配元素的列表,你可以简单地使用你想要的 xpath(即使它会产生多个元素) ,然后遍历结果并打印出来。示例(或您正在尝试做的事情)-
for i in tree.xpath('//div[@class="class1"]/div/text()'):
print i
这应该打印主 div 中每个 div
内的文本,属性 class
为 class1
。
你甚至不需要它,如果你知道一种唯一标识元素的方法(使用 attributes/indexing 等),你可以直接使用它,例如,获取 [=19= 的文本] , 使用 -
for i in tree.xpath('//div[@id="element1"]/text()'):
print i
此外,您的 xml 似乎有很多不需要的换行符和空格,您可以通过调用 i.strip()
去除它们。
如果你想得到一个元素的所有子元素,我推荐使用iter()
:
for element in tree.iter():
print element.text.strip()
输出:
text1
text2
text3
您还可以定义标记名tree.iter(tag="div")