我正在尝试使用Yahoo天气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的解析函数不支持requests库返回的原始对象。稍微深入了解一下,这个原始对象解析为
>>> r = requests.get('http://weather.yahooapis.com/forecastrss?w=2502265', stream=True)
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x7f32c24f9e48>
我参考了这个解决方案,但仍然导致相同的问题。为什么上面的方法不起作用?是urllib3响应对象不支持ElementTree.parse函数吗?我已经阅读了所有文档,但没有任何启示。
文档列表在这里:
编辑: 经过更多的实验,我仍然没有找到上述问题的解决方案。然而,我发现了一个变通方法。如果使用ElementTree的fromstring方法来处理XML内容,一切都能正常工作。
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)
我想这种方法的缺点就是它使用了更多的内存。你认为呢?我希望能听到社区的意见。