我正在使用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'))
如何在不应用一个特定正则表达式面对其他类似字符串的情况下清理该字符串?
编辑:现在,@b_c和@mzjn解释了我的问题是转义字符,我找到了一种可能的解决方案(Escape unescaped characters in XML with Python)
ElementTree.fromstring('<tag>&Sample ‘cp 99-3a’</tag>', parser = etree.XMLParser(recover = True))
答案 0 :(得分:0)
您的字符串包含HTML实体(无论是XML还是HTML),并且需要不转义。 {_id: '123',array:[{date:'2019-10-31T04:00:00.000',name:jack},{date:'2019-10-31T04:00:00.000',name:jill}]};
和‘
分别与’
和‘
相关。
如果您use html.unescape
,您将看到清理后的文本:
’
编辑:@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
个字符(并要求您可以控制字符串的内容)。这些是左右单引号的MS CP1252 encodings。使用上面的\x92
方法仍将为您提供清理后的文本。
评论跟进
在您的评论中,您添加了包含 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:
lxml.html
或者根据您的需求,在解析字符串以删除烦人的cp1252字符之前,最好做一个字符串/正则表达式替换:
>>> from lxml.html import soupparser
>>> soupparser.fromstring('<tag>&Sample ‘cp 99-3 a’</tag>').text_content()
'&Sample ‘cp 99-3 a’'