【问题标题】:Python TypeError while using xml.etree.ElemenTree and requests使用 xml.etree.ElemenTree 和请求时出现 Python TypeError
【发布时间】:2013-06-05 07:09:55
【问题描述】:

这对我有用:

import xml.etree.ElementTree as ET from urllib2 import urlopen url = 'http://example.com' # this url points to a `xml` page tree = ET.parse(urlopen(url))

但是,当我切换到requests 时,出了点问题:

import requests import xml.etree.ElementTree as ET url = 'http://example.com' # this url points to a `xml` page tree = ET.parse(requests.get(url))

引用错误如下图:

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 tree = ET.parse(requests.get(url, proxies={'http': '192.168.235.36:7788'})) /usr/lib/python2.7/xml/etree/ElementTree.py in parse(source, parser) 1180 def parse(source, parser=None): 1181 tree = ElementTree() -> 1182 tree.parse(source, parser) 1183 return tree 1184 /usr/lib/python2.7/xml/etree/ElementTree.py in parse(self, source, parser) 645 close_source = False 646 if not hasattr(source, "read"): --> 647 source = open(source, "rb") 648 close_source = True 649 try: TypeError: coercing to Unicode: need string or buffer, Response found

所以,我的问题是:在我的情况下,requests 有什么问题,我怎样才能让它在 ETrequests 下工作?

【问题讨论】:

    标签: python xml urllib2 python-requests


    【解决方案1】:

    您正在将 requests respones 对象 传递给 ElementTree;你想传入raw file object

    r = requests.get(url, stream=True)
    ET.parse(r.raw)
    

    .raw 返回“类文件”套接字对象,ElementTree.parse() 将从该对象中读取,就像从 urllib2 响应中读取一样(它本身就是一个类文件对象)。

    具体例子:

    >>> r = requests.get('http://www.enetpulse.com/wp-content/uploads/sample_xml_feed_enetpulse_soccer.xml', stream=True)
    >>> tree = ET.parse(r.raw)
    >>> tree
    <xml.etree.ElementTree.ElementTree object at 0x109dadc50>
    >>> tree.getroot().tag
    'spocosy'
    

    如果你有一个压缩的 URL,原始套接字(如urllib2)会返回未解码的压缩数据;在这种情况下,您可以在binary response content 上使用ET.fromstring() 方法:

    r = requests.get(url)
    ET.fromstring(r.content)
    

    【讨论】:

    • 我以前试过这个,但没有成功。我回来了:ParseError: no element found: line 1, column 0
    • 抱歉,当前的 API 要求您使用 stream=True 才能使原始读取正常工作,否则数据会提前下载。使用更新后的答案重试。
    • 这不起作用,因为requests 已经在第一行末尾读取了来自套接字的数据。将 stream=True 作为参数传递给请求是强制性的
    • @doukremt:这就是我在我的 cmets 中所说的。 :-)
    • @MartijnPieters 它有效!你一直对我很有帮助。非常感谢:)
    【解决方案2】:

    您提供的不是响应文本,而是 requests Response 对象本身,这就是您收到类型错误的原因:need string or buffer, Response found。改为这样做:

    r = requests.get(url)
    tree = ET.fromstring(r.text)
    

    【讨论】:

    • 这不起作用有两个原因:r.text 是 Unicode(解码)结果,您应该始终将 XML 解析为未解码的数据,ET.parse() 想要一个文件名或类似文件目的。 ET.parse() 将看到 r.text 结果作为文件名并将其传递给 open()
    猜你喜欢
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多