为什么这个特定的 xml 解析代码对小 xml 有效,但对大 xml 无效?
Why this particular xml parsing code works for small xml, but fails for large xml?
我有一个解析 xml 内容的函数,如下所示:
def parse_individual_xml(self, xml_url):
xml_data_to_parse = urlopen(xml_url).read()
jobs = ET.fromstring(xml_data_to_parse)
return jobs
在我处理较小的文件 (1-2 mb) 之前,此功能运行良好。但是当我取了一个大的 xml url 时,我得到了这个错误。
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 0
Afaik,这是一些编码解码问题。
下面的函数给出了完全相同的行为。
def parse_individual_xml(self, xml_url):
xml_data_to_parse = urlopen(xml_url)
jobs = ET.parse(xml_data_to_parse).getroot()
return jobs
然后我尝试了一些不同的方法。
我在本地下载了那个大文件,并更改了如下功能:
def parse_individual_xml(self, xml_local_path):
jobs = ET.parse(xml_local_path).getroot()
return jobs
而且,它适用于任何大小的文件。最终我会使用etree的iterparse
。但起初我想知道上述行为的原因。
我该如何解决?
几乎可以肯定远程服务器 compressing large responses 使用 GZIP(或者,不太常见,deflate)。
基于 Content-Encoding
header,在尝试解析流之前解压缩流:
import gzip
response = urlopen(xml_url)
if response.info().get('Content-Encoding') == 'gzip':
# transparent decompression of a GZIP-ed response
response = gzip.GzipFile(fileobj=response)
jobs = ET.parse(response).getroot()
您可能需要考虑改用 requests
库,它可以透明地为您处理。要将数据 流 到迭代解析器,请使用 stream=True
,访问 response.raw
file-like object 并将其配置为进行透明解压缩:
response = requests.get(xml_url, stream=True)
response.raw.decode_content = True # handle content-encoding compression
jobs = ET.parse(response.raw).getroot() # or use iterparse
我有一个解析 xml 内容的函数,如下所示:
def parse_individual_xml(self, xml_url):
xml_data_to_parse = urlopen(xml_url).read()
jobs = ET.fromstring(xml_data_to_parse)
return jobs
在我处理较小的文件 (1-2 mb) 之前,此功能运行良好。但是当我取了一个大的 xml url 时,我得到了这个错误。
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 0
Afaik,这是一些编码解码问题。
下面的函数给出了完全相同的行为。
def parse_individual_xml(self, xml_url):
xml_data_to_parse = urlopen(xml_url)
jobs = ET.parse(xml_data_to_parse).getroot()
return jobs
然后我尝试了一些不同的方法。
我在本地下载了那个大文件,并更改了如下功能:
def parse_individual_xml(self, xml_local_path):
jobs = ET.parse(xml_local_path).getroot()
return jobs
而且,它适用于任何大小的文件。最终我会使用etree的iterparse
。但起初我想知道上述行为的原因。
我该如何解决?
几乎可以肯定远程服务器 compressing large responses 使用 GZIP(或者,不太常见,deflate)。
基于 Content-Encoding
header,在尝试解析流之前解压缩流:
import gzip
response = urlopen(xml_url)
if response.info().get('Content-Encoding') == 'gzip':
# transparent decompression of a GZIP-ed response
response = gzip.GzipFile(fileobj=response)
jobs = ET.parse(response).getroot()
您可能需要考虑改用 requests
库,它可以透明地为您处理。要将数据 流 到迭代解析器,请使用 stream=True
,访问 response.raw
file-like object 并将其配置为进行透明解压缩:
response = requests.get(xml_url, stream=True)
response.raw.decode_content = True # handle content-encoding compression
jobs = ET.parse(response.raw).getroot() # or use iterparse