我在Python中有一个接收响应的SOAP客户端,它在SOAP信封的主体的一个元素中接收到大量数据(gzipped文件,几个GB,机器的主存不一定足以容纳它)。 / p>
因此,我需要将信息作为流处理,我在发布SOAP请求时指定:
import requests
url = 'xyz.svc'
headers = {'SOAPAction': X}
response = requests.post(url, data=payload, headers=headers, stream=True)
为了用lxml.etree解析信息(我必须首先从头部读取一些信息,然后处理来自正文的字段,包括大文件元素),我现在想要使用流来提供iterparse :
from lxml import etree
context = etree.iterparse(response.raw, events = ('start', 'end'))
for event, elem in context:
if event == 'start':
if elem.tag == t_header:
# process header
if elem.tag == t_body:
# TODO: write element text to file, rely on etree to not load into memory?
else:
# do some cleanup
不幸的是,构建像这样的代码似乎不起作用,将response.raw传递给iterparse引发:
XMLSyntaxError: Document is empty, line 1, column 1
解决方案:etree收到一个无法正确处理的编码字节流,设置
response.raw.decode_content = True
似乎适用于第一部分。
更新:解析器正常工作(但我不确定解码是否正确完成,因为文件似乎最终被破坏 - 这可能是由于base64解码不良造成的) ,这仍有待妥善实施。
更新2 :一些额外的调试显示无法访问大元素文本中的所有内容。 打印
len(elem.text)
start
中的 - 事件显示33651
,而在end
- 事件中,它是10389304
。有关如何使用lxml迭代读取完整内容的任何想法吗?
关于包版本,我正在使用: