我正在使用Python 3从API检索数据,但是在从检索到的字符串中解析某些XML文档时遇到问题。
我已经确定了导致此问题的特定字符串:
from xml.etree import ElementTree
bad_string = '<tag>Sample ‘cp 99-3a’</tag>'
ElementTree.fromstring(bad_string)
这是返回的错误,它将停止脚本:
ParseError: not well-formed (invalid token): line 1, column 31
[我尝试使用下面的解决方案来解决它,结果与以前相同
ElementTree.fromstring('<tag>Sample ‘cp 99-3a’</tag>'.encode('ascii', 'ignore'))
如何在不应用一个特定正则表达式面对其他类似字符串的情况下清理该字符串?
Edit:现在,@b_c和@mzjn解释了我的问题是未转义的字符,我找到了一种可能的解决方案(Escape unescaped characters in XML with Python)
ElementTree.fromstring('<tag>&Sample ‘cp 99-3a’</tag>', parser = etree.XMLParser(recover = True))
您的字符串包含HTML实体(无论是XML还是HTML),并且需要不转义。 ‘
和’
分别与‘
和’
相关。
如果您是use html.unescape
,则会看到清理后的文本:
html.unescape
Edit:@mzjn指出,您还可以通过在第二个实体中添加缺少的分号来修复字符串:
>>> import html
>>> html.unescape('<tag>Sample ‘cp 99-3a’</tag>')
'<tag>Sample ‘cp 99-3a’</tag>'
但是,您会看到>>> import xml.etree.ElementTree as ET
>>> tag = ET.fromstring('<tag>Sample ‘cp 99-3a’</tag>')
>>> tag.text
'Sample \x91cp 99-3a\x92'
和\x91
字符(并要求您可以控制字符串的内容)。这些是左右单引号的\x92
。使用上面的MS CP1252 encodings方法仍将为您提供清理后的文本。
评论跟进
在您的评论中,您添加了包含other有效XML转义序列(例如html.unescape
)的字符串的附加皱纹,&
将很高兴清除此序列。不幸的是,正如您所看到的,最终导致您回到第一个方框,因为您现在有一个html.unescape
可以<>进行转义,但不是(&
会为您取消转义) 。ElementTree
您需要尝试使用>>> import html >>> import xml.etree.ElementTree as ET >>> cleaned = html.unescape('<tag>&Sample ‘cp 99-3a’</tag>') >>> print(cleaned) <tag>&Sample ‘cp 99-3a’</tag> >>> ET.fromstring(cleaned) Traceback (most recent call last): ... ParseError: not well-formed (invalid token): line 1, column 12
中的soupparser
的其他一些选项,这在处理有问题的HTML / XML方面要好得多:
soupparser
或者根据您的需求,在解析字符串以删除烦人的cp1252字符之前,最好先进行字符串/正则表达式替换:
lxml.html