在Python中解析巨大的,编码错误的XML文件
问题内容:
我一直在研究解析外部XML文件的代码。其中一些文件非常大,数据量高达千兆字节。不用说,这些文件需要解析为流,因为将它们加载到内存中效率太低,并且经常导致OutOfMemory问题。
我已经使用了miniDOM,ElementTree,cElementTree库,并且当前正在使用lxml。现在,我使用了一个有效的内存有效脚本lxml.etree.iterparse
。问题在于,我需要解析的某些XML文件包含编码错误(它们以UTF-8广告,但包含不同编码的字符)。使用lxml.etree.parse
此recover=True
选项时,可以通过使用自定义解析器的选项进行修复,但iterparse
不接受自定义解析器。(另请参阅:此问题)
我当前的代码如下所示:
from lxml import etree
events = ("start", "end")
context = etree.iterparse(xmlfile, events=events)
event, root_element = context.next() # <items>
for action, element in context:
if action == 'end' and element.tag == 'item':
# <parse>
root_element.clear()
iterparse
遇到错误字符时发生错误(在本例中为^Y
):
lxml.etree.XMLSyntaxError: Input is not proper UTF-8, indicate encoding !
Bytes: 0x19 0x73 0x20 0x65, line 949490, column 25
我什至不希望解码此数据,我可以删除它。但是我不知道跳过元素的任何方法-我尝试过context.next
并continue
在try /
except语句中。
任何帮助,将不胜感激!
更新资料
一些其他信息:这是iterparse失败的行:
<description><![CDATA:[musea de la photographie fonds mercator. Met meer dan 80.000 foto^Ys en 3 miljoen negatieven is het Muse de la...]]></description>
根据etree,错误发生在bytes处0x19 0x73 0x20 0x65
。
根据hexedit,19 73 20 65
将其转换为ASCII .s e
。.
在此位置应为撇号(foto’s)。
我也发现了这个问题,但没有提供解决方案。
问题答案:
由于问题是由 非法
XML字符引起的,在这种情况下为0x19字节,因此我决定将其剥离。我在该网站上发现了以下正则表达式:
invalid_xml = re.compile(u'[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]')
我写了这段代码,在保存xml feed的同时删除了非法字节:
conn = urllib2.urlopen(xmlfeed)
xmlfile = open('output', 'w')
while True:
data = conn.read(4096)
if data:
newdata, count = invalid_xml.subn('', data)
if count > 0 :
print 'Removed %s illegal characters from XML feed' % count
xmlfile.write(newdata)
else:
break
xmlfile.close()