Sollte ich PyXML verwenden oder was ist in der Standardbibliothek?Wie kann ich XML aus RESTful-Webdiensten mit Django/Python konsumieren?
Antwort
ElementTree wird als Teil des Standard Python libs vorgesehen. ElementTree ist reiner Python und celementtree ist die schnellere C-Implementierung:
# Try to use the C implementation first, falling back to python
try:
from xml.etree import cElementTree as ElementTree
except ImportError, e:
from xml.etree import ElementTree
Hier ist ein Beispiel für die Verwendung, wo ich xml von einem RESTful Web-Service bin raubend:
def find(*args, **kwargs):
"""Find a book in the collection specified"""
search_args = [('access_key', api_key),]
if not is_valid_collection(kwargs['collection']):
return None
kwargs.pop('collection')
for key in kwargs:
# Only the first keword is honored
if kwargs[key]:
search_args.append(('index1', key))
search_args.append(('value1', kwargs[key]))
break
url = urllib.basejoin(api_url, '%s.xml' % 'books')
data = urllib.urlencode(search_args)
req = urllib2.urlopen(url, data)
rdata = []
chunk = 'xx'
while chunk:
chunk = req.read()
if chunk:
rdata.append(chunk)
tree = ElementTree.fromstring(''.join(rdata))
results = []
for i, elem in enumerate(tree.getiterator('BookData')):
results.append(
{'isbn': elem.get('isbn'),
'isbn13': elem.get('isbn13'),
'title': elem.find('Title').text,
'author': elem.find('AuthorsText').text,
'publisher': elem.find('PublisherText').text,}
)
return results
Ich bevorzuge immer, wenn möglich, die Standardbibliothek zu verwenden. ElementTree ist unter Pythonisten bekannt, daher sollten Sie viele Beispiele finden. Teile davon wurden auch in C optimiert, also ist es ziemlich schnell.
Es gibt auch BeautifulSoup, das hat eine API, die manche bevorzugen könnten. Hier ist ein Beispiel dafür, wie Sie alle Tweets extrahieren, die von Twitter Public Timeline favorisiert wurden:
from BeautifulSoup import BeautifulStoneSoup
import urllib
url = urllib.urlopen('http://twitter.com/statuses/public_timeline.xml').read()
favorited = []
soup = BeautifulStoneSoup(url)
statuses = soup.findAll('status')
for status in statuses:
if status.find('favorited').contents != [u'false']:
favorited.append(status)
Leider, BeautifulSoup ist nicht mehr gepflegt. Ich würde es vermeiden und mich zu lxml oder ElementTree neigen. – mlissner
@mlissner Ich kann nicht sehen, wo es auf BS4 Website sagt, dass es nicht mehr gepflegt wird. Ist das wirklich so? – mrkzq
An einem Punkt droht der Maintainer zurückzutreten, aber es scheint, dass die Realität nie zustande kam. – mlissner
vezult, wie kommt es manchmal verwenden Sie elem.get() und manchmal verwenden Sie elem.find() Text.? – rick
@rick: elem.get() ruft den Wert eines Elementattributs ab, während elem.find() nach Elementen im Element elem sucht. – vezult
'tree = ElementTree.parse (urllib2.urlopen (url, data))' sollte ohne 'rdata' Liste funktionieren. – jfs