解析lxml.etree._Element内容
我有一个从一个 <table>
中解析出来的元素。
<td align="center" valign="top">
<a href="ConfigGroups.aspx?cfgID=451161&prjID=11778&grpID=DTST"
target="_blank">
5548U
</a><br/>Power La Vaca<br/>(M8025K)<br/>Linux 4.2.x.x<br/>
</td>
我想从这个元素中提取出“55488 Power La Vaca (8025K) Linux 4.2.x.x”(包括空格)。
import lxml.etree as ET
td_html = """
<td align="center" valign="top">
<a href="ConfigGroups.aspx?cfgID=451161&prjID=11778&grpID=DTST"
target="_blank">
5548U
</a><br/>Power La Vaca<br/>(M8025K)<br/>Linux 4.2.x.x<br/>
</td>
"""
td_elem = ET.fromstring(td_html)
fail_1 = td_elem.find('a').text + td_elem.text
print "FAIL_1", fail_1
print "FAIL_2"
for elem in td_elem.iterchildren():
print elem.tag, elem.text
结果
$ python textxml.py
FAIL_1
5548U
FAIL_2
a
5548U
br None
br None
br None
br None
$
问题
我觉得问这个问题有点丢脸,因为这看起来应该不难。
我该如何从 td_elem
元素中提取出“Power La Vaca (8025K) Linux 4.2.x.x”(包括空格)呢?
请不要给我正则表达式的解决方案。
解决方案
明确的解决方案(使用Finn的建议 itertext()
):
import lxml.etree as ET
td_html = """
<td align="center" valign="top">
<a href="ConfigGroups.aspx?cfgID=451161&prjID=11778&grpID=DTST"
target="_blank">
5548U
</a><br/>Power La Vaca<br/>(M8025K)<br/>Linux 4.2.x.x<br/>
</td>
"""
td_elem = ET.fromstring(td_html)
print "SUCCESS", ' '.join([txt.strip() for txt in td_elem.itertext()])
2 个回答
3
在处理XML的时候,即使是在Python中,我也喜欢尝试使用一些专门的工具来帮助我。对于解析XML的一部分内容,我觉得XPath是最合适的选择。
>>> td_elem = ET.fromstring(td_html)
>>>
>>> # Use XPath to grab just the text nodes under <td/>,
>>> # ignoring any text nodes in child nodes of <td/> (i.e., <a...>5548U</a>)
>>> print(td_elem.xpath('/td/text()'))
['\n ', 'Power La Vaca', '(M8025K)', 'Linux 4.2.x.x', '\n']
>>>
>>> # Make it a little cleaner
>>> ' '.join(x.strip() for x in td_elem.xpath('/td/text()'))
' Power La Vaca (M8025K) Linux 4.2.x.x '
>>>
>>> # Just for reference, grab all text nodes with '//'
>>> ' '.join(x.strip() for x in td_elem.xpath('/td//text()'))
' 5548U Power La Vaca (M8025K) Linux 4.2.x.x '
3
我知道一定有更好的方法,但这个方法可以用。
link = td_elem.find('a').text.strip()
text = ''.join(td_elem.itertext()).strip()
text.split(link)[1]
输出结果是 Power La Vaca(M8025K)Linux 4.2.x.x
更新:如果你想用空格代替那些 <br>
,这样做其实更好。
' '.join(map(str, [el.tail for el in td_elem.iterchildren() if el.tail]))
其实这个 map
str
并不是必须的,但我能想象有其他值是需要它的。