【发布时间】:2014-06-26 20:22:54
【问题描述】:
我正在尝试使用 Yahoo Weather API,但在解析 API 响应的 XML 时遇到了一些问题。我正在使用Python 3.4。这是我正在使用的代码:
weather_url = 'http://weather.yahooapis.com/forecastrss?w=%s&u=%s'
url = weather_url % (zip_code, units)
try:
rss = parse(requests.get(url, stream=True).raw).getroot()
conditions = rss.find('channel/item/{%s}condition' % weather_ns)
return {
'current_condition': conditions.get('text'),
'current_temp': conditions.get('temp'),
'title': rss.findtext('channel/title')
}
except:
raise
这是我得到的堆栈跟踪:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/home/jonathan/PycharmProjects/pyweather/pyweather/pyweather.py", line 42, in yahoo_conditions
rss = parse(requests.get(url, stream=True).raw).getroot()
File "/usr/lib/python3.4/xml/etree/ElementTree.py", line 1187, in parse
tree.parse(source, parser)
File "/usr/lib/python3.4/xml/etree/ElementTree.py", line 598, in parse
self._root = parser._parse_whole(source)
File "<string>", line None
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 0
xml.etree.ElementTree 解析函数不喜欢请求库返回的原始对象。深入研究一下,原始对象解析为
>>> r = requests.get('http://weather.yahooapis.com/forecastrss?w=2502265', stream=True)
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x7f32c24f9e48>
我引用了this solution,但它仍然导致同样的问题。为什么上面的方法不起作用? ElementTree.parse 函数不支持 urllib3 响应对象吗?我已经阅读了所有文档,但它们根本没有启发我。
文档列表在这里:
编辑: 经过更多的实验,我仍然没有找到解决上述问题的方法。但是,我找到了一种解决方法。如果对 XML 内容使用 ElementTree 的 fromstring 方法,一切正常。
def fetch_xml(url):
"""
Fetch a url and parse the document's XML.
:param url: the URL that the XML is located at.
:return: the root element of the XML.
:raises:
:requests.exceptions.RequestException: Requests could not open the URL.
:xml.etree.ElementTree.ParseError: xml.etree.ElementTree failed to parse the XML document.
"""
return ET.fromstring(requests.get(url).content)
我想这种方法的缺点是它使用更多的内存。你怎么看?我想征求社区意见。
【问题讨论】:
标签: xml python-3.x python-requests elementtree