也就是说,所有文本和子标签,没有元素本身的标签?
有
<p>blah <b>bleh</b> blih</p>
我想
blah <b>bleh</b> blih
element.text 返回“blah”并且 etree.tostring(element) 返回:
<p>blah <b>bleh</b> blih</p>
也就是说,所有文本和子标签,没有元素本身的标签?
有
<p>blah <b>bleh</b> blih</p>
我想
blah <b>bleh</b> blih
element.text 返回“blah”并且 etree.tostring(element) 返回:
<p>blah <b>bleh</b> blih</p>
ElementTree 完美运行,您必须自己组装答案。像这样的东西...
"".join( [ "" if t.text is None else t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )
感谢 JV amd PEZ 指出错误。
编辑。
>>> import xml.etree.ElementTree as xml
>>> s= '<p>blah <b>bleh</b> blih</p>\n'
>>> t=xml.fromstring(s)
>>> "".join( [ t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )
'blah <b>bleh</b> blih'
>>>
不需要尾巴。
这是我最终使用的解决方案:
def element_to_string(element):
s = element.text or ""
for sub_element in element:
s += etree.tostring(sub_element)
s += element.tail
return s
这些是很好的答案,可以回答 OP 的问题,特别是如果问题仅限于 HTML。但是文档本质上是杂乱无章的,元素嵌套的深度通常是无法预测的。
要模拟 DOM 的 getTextContent(),您必须使用(非常)简单的递归机制。
要获取纯文本:
def get_deep_text( element ):
text = element.text or ''
for subelement in element:
text += get_deep_text( subelement )
text += element.tail or ''
return text
print( get_deep_text( element_of_interest ))
要获取有关原始文本之间边界的所有详细信息:
class holder: pass # this is just a way of creating a holder object
holder.element_count = 0
def get_deep_text_w_boundaries(element, depth = 0):
holder.element_count += 1
element_no = holder.element_count
indent = depth * ' '
text1 = f'{indent}(el {element_no} tag {element.tag}: text |{element.text or ""}| - attribs: {element.attrib})'
print(text1)
for subelement in element:
get_deep_text_w_boundaries(subelement, depth + 1)
text2 = f'{indent}(el {element_no} tag {element.tag} - tail: |{element.tail or ""}|)'
print(text2)
get_deep_text_w_boundaries(etree_element)
示例输出:
(el 1 tag source: text |DEVANT LE | - attribs: {})
(el 2 tag g: text |TRIBUNAL JUDICIAIRE| - attribs: {'style_no': '3'})
(el 2 tag g - tail: ||)
(el 1 tag source - tail: | DE VERSAILLES|)
我怀疑 ElementTree 是用来做这个的。但是假设您有充分的理由使用它,也许您可以尝试从片段中剥离根标签:
re.sub(r'(^<%s\b.*?>|</%s\b.*?>$)' % (element.tag, element.tag), '', ElementTree.tostring(element))
这里的大部分答案都是基于 XML parser的ElementTree
,即使PEZ 的基于正则表达式的答案仍然部分依赖于 ElementTree。
所有这些都很好并且适用于大多数用例,但为了完整起见,值得注意的是,它ElementTree.tostring(...)
会给你一个等效的片段,但并不总是与原始有效负载相同。如果出于某种非常罕见的原因,您想按原样提取内容,则必须使用纯正则表达式解决方案。这个例子是我如何使用基于正则表达式的解决方案。
这个答案稍微修改了Pupeno 的回复。在这里,我将编码类型添加到“tostring”中。这个问题花了我好几个小时。我希望这个小修正能帮助其他人。
def element_to_string(element):
s = element.text or ""
for sub_element in element:
s += ElementTree.tostring(sub_element, encoding='unicode')
s += element.tail
return s
不知道是否可以选择外部库,但无论如何——假设<p>
页面上有一个带有此文本的库,则 jQuery 解决方案将是:
alert($('p').html()); // returns blah <b>bleh</b> blih