Ich habe eine Flask-Anwendung, die ein XML-Dokument von einer URL abruft und verarbeitet. Ich verwende requests_cache mit redis, um zusätzliche Anfragen zu vermeiden, und ElementTree.iterparse, um über den gestreamten Inhalt zu iterieren. Hier ist ein Beispiel von meinem Code (gleiches Ergebnis aus tritt sowohl den Entwicklungsserver und den interaktiven Interpreter):ElementTree.iterparse mit gestreamter und zwischengespeicherter Anfrage wirft ParseError
>>> import requests, requests_cache
>>> import xml.etree.ElementTree as ET
>>> requests_cache.install_cache('test', backend='redis', expire_after=300)
>>> url = 'http://myanimelist.net/malappinfo.php?u=doomcat55&status=all&type=anime'
>>> response = requests.get(url, stream=True)
>>> for event, node in ET.iterparse(response.raw):
... print(node.tag)
den obigen Code Lauf einmal wirft einen ParseError:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/xml/etree/ElementTree.py", line 1301, in __next__
self._root = self._parser._close_and_return_root()
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/xml/etree/ElementTree.py", line 1236, in _close_and_return_root
root = self._parser.close()
xml.etree.ElementTree.ParseError: no element found: line 1, column 0
jedoch genau die gleichen Lauf Code erneut, bevor der Cache abläuft, druckt tatsächlich das erwartete Ergebnis! Wie kommt es, dass die XML-Analyse nur beim ersten Mal fehlschlägt und wie kann ich das beheben?
Edit: Wenn es hilfreich ist, habe ich bemerkt, dass in einem anderen ParseError ohne die Cache-Ergebnisse mit dem gleichen Code ausgeführt wird:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/xml/etree/ElementTree.py", line 1289, in __next__
for event in self._parser.read_events():
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/xml/etree/ElementTree.py", line 1272, in read_events
raise event
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/xml/etree/ElementTree.py", line 1230, in feed
self._parser.feed(data)
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 0
Interessant, wenn Sie das tun würde 'ET.iterparse (StringIO (response.text))' statt, wäre es die ganze Zeit arbeiten, obwohl ich glaube, dass Sie eine haben Grund, '.raw' in diesem Fall zu verwenden. – alecxe
@alecxe Hm, das scheint mir zu bedeuten, dass das Problem verursacht wird, weil ET versucht, ein Dokument zu analysieren, das nicht vollständig geladen ist ... Ich bin mir ziemlich sicher, dass es möglich ist, dies zu tun: http: // stackoverflow.com/questions/18308529/python-requests-package-handling-xml-response – Noah
@alecxe, erste Ausführung Caching verbraucht die Daten, nicht Caching bedeutet, dass Sie gziped Daten übergeben, die Etree nicht analysieren kann –