lxml.etree到iterparse请求响应(使用stream = True)

时间:2016-07-22 13:46:55

标签: python python-requests lxml

我在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
  1. 如何解决这个问题?寻找类似的解决方案,这种方法通常似乎适用于人。
  2. 解决方案:etree收到一个无法正确处理的编码字节流,设置

    response.raw.decode_content = True
    

    似乎适用于第一部分。

    1. 如何正确实现流式元素文本?请问etree.iterparse将完整的element.text处理成内存,还是可以以块的形式读取?
    2. 更新:解析器正常工作(但我不确定解码是否正确完成,因为文件似乎最终被破坏 - 这可能是由于base64解码不良造成的) ,这仍有待妥善实施。

      更新2 :一些额外的调试显示无法访问大元素文本中的所有内容。 打印

      len(elem.text)
      
      start中的

      - 事件显示33651,而在end - 事件中,它是10389304。有关如何使用lxml迭代读取完整内容的任何想法吗?

      关于包版本,我正在使用:

      • 要求2.9.1
      • python 3.4.4
      • etree 3.4.4(来自lxml)

0 个答案:

没有答案