¿Cómo consumir XML de los servicios web RESTful usando Django / Python?
Pregunta
¿Debo usar PyXML o lo que está en la biblioteca estándar?
Solución
ElementTree se proporciona como parte de las librerías estándar de Python. ElementTree es python puro, y cElementTree es la implementación más rápida de C:
# 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
Aquí hay un ejemplo de uso, donde estoy consumiendo xml de un servicio web RESTful:
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
Otros consejos
Siempre prefiero usar la biblioteca estándar cuando sea posible. ElementTree es bien conocido entre los pitones, por lo que deberías poder encontrar muchos ejemplos. Algunas partes también se han optimizado en C, por lo que es bastante rápido.
También hay BeautifulSoup , que tiene una API que algunos pueden preferir. Aquí hay un ejemplo de cómo puedes extraer todos los tweets que han sido favoritos de la línea de tiempo pública de Twitter:
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)