Python (novato) Parse XML from API call

He buscado algunos tutoriales / otras preguntas en la stack / documentación y todavía no puedo resolverlo. ugh !!!

Hacer la solicitud de la API y el análisis (quiero asignarlo a las variables, pero eso es una ventaja a esta pregunta), esto es lo que estoy intentando. ¿Por qué no puedo enumerar el título y el enlace de los artículos?

#!/usr/bin/python # Screen Scraper for Subs import urllib from xml.etree import ElementTree as ET show = 'heroes' season = '4' language = 'en' limit = '1' requestURL = 'http://api.allsubs.org/index.php?' \ + 'search=' + show \ + '+season+' + season \ + '&language=' + language \ + '&limit=' + limit root = ET.parse(urllib.urlopen(requestURL)).getroot() print root print '\n' items = root.findall('items') for item in items: item.find('title').text # should print:  item.find('link').text # Should print: http://www.allsubs.org/subs-download/heroes+season+4/1223435/ 

Respuesta XML

   AllSubs API: Subtitles Search http://www.allsubs.org  en-us 1 24    http://www.allsubs.org/subs-download/heroes+season+4/1223435/ heroes-season-4-english-heroes-season-4-en.zip Heroes - 4x01-02 - Orientation.HDTV.FQM.en.srt|Heroes - 4x17 - The Art of Deception.HDTV.2HD.en.srt|Heroes - 4x07 - Strange Attractors.HDTV.LOL.en.srt|Heroes - 4x08 - Once Upon a Time in Texas.HDTV.2HD.en.srt|Heroes - 4x07 - Strange Attractors.720p HDTV.DIMENSION.en.srt|Heroes - 4x05 - Hysterical Blindness.720p HDTV.X264.en.srt|Heroes - 4x09 - Shadowboxing.HDTV.LOL.en.srt|Heroes - 4x16 - Pass Fail.HDTV.LOL.en.srt|Heroes - 4x04 - Acceptance.HDTV.en.srt|Heroes - 4x01-02 - Orientation.720p HDTV.DIMENSION.en.srt|Heroes - 4x06 - Tabula Rasa.HDTV.NoTV.en.srt|Heroes - 4x10 - Brother's Keeper.HDTV.FQM.en.srt|Heroes - 4x04 - Acceptance.HDTV.FQM.en.srt|Heroes - 4x14 - Let It Bleed.720p HDTV.DIMENSION.en.srt|Heroes - 4x06 - Tabula Rasa.720p HDTV.SiTV.en.srt|Heroes - 4x08 - Once Upon a Time in Texas.HDTV.NoTV.en.srt|Heroes - 4x12 - The Fifth Stage.HDTV.LOL.en.srt|Heroes - 4x19 - Brave New World.HDTV.LOL.en.srt|Heroes - 4x15 - Close to You.720p HDTV.DIMENSION.en.srt|Heroes - 4x03 - Ink.720p HDTV.DIMENSION.en.srt|Heroes - 4x11 - Thanksgiving.720p HDTV.DIMENSION.en.srt|Heroes - 4x13 - Upon This Rock.720p HDTV.DIMENSION.en.srt|Heroes - 4x13 - Upon This Rock.HDTV.LOL.en.srt|Heroes - 4x14 - Let It Bleed.HDTV.LOL.en.srt|Heroes - 4x15 - Close to You.HDTV.LOL.en.srt|Heroes - 4x12 - The Fifth Stage.720p HDTV.DIMENSION.en.srt|Heroes - 4x18 - The Wall.HDTV.LOL.en.srt|Heroes - 4x08 - Once Upon a Time in Texas.720p HDTV.CTU.en.srt|Heroes - 4x17 - The Art of Deception.HDTV.CTU.en.srt|Heroes - 4x09 - Shadowboxing.720p HDTV.DIMENSION.en.srt|Heroes - 4x10 - Brother's Keeper.720p HDTV.DIMENSION.en.srt|Heroes - 4x04 - Acceptance.720p HDTV.CTU.en.srt|Heroes - 4x11 - Thanksgiving.HDTV.FQM.en.srt|Heroes - 4x03 - Ink.HDTV.FQM.en.srt|Heroes - 4x05 - Hysterical Blindness.HDTV.XII.en.srt| en 2010-02-16    

ACTUALIZAR:

Esto funcionó, gracias por la ayuda y por señalar mi error tipográfico.

 items = root.findall('items/item') for item in items: print item.find('title').text print item.find('link').text 

 items = root.findall('items') 

debiera ser

 items = root.findall('items/item') 

Esto funciona para mi Tenga en cuenta que estoy usando urllib2 para pasar por un proxy:

 import urllib2 from xml.etree import ElementTree as ET show = 'heroes' season = '4' language = 'en' limit = '1' requestURL = 'http://api.allsubs.org/index.php?' \ + 'search=' + show \ + '+season+' + season \ + '&language=' + language \ + '&limit=' + limit root = ET.parse(urllib2.urlopen(requestURL)).getroot() print root print '\n' items = root.findall('items')[0].findall('item') for item in items: print item.find('title').text # should print:  print item.find('link').text # Should print: http://www.allsubs.org/subs-download/heroes+season+4/1223435/ 

tenga en cuenta que findall (‘items’) encuentra la etiqueta “items”, lo que quiere hacer un bucle (creo) son las tags “item” dentro de eso, por lo que encontramos all () de esas. Además, necesitas imprimir para sacar algo de python.

Además, si lo hago con limit = 2, obtengo un:

 Traceback (most recent call last): File "heros.py", line 18, in  root = ET.parse(urllib2.urlopen(requestURL)).getroot() File "/usr/lib/python2.6/xml/etree/ElementTree.py", line 862, in parse tree.parse(source, parser) File "/usr/lib/python2.6/xml/etree/ElementTree.py", line 586, in parse parser.feed(data) File "/usr/lib/python2.6/xml/etree/ElementTree.py", line 1245, in feed self._parser.Parse(data, 0) xml.parsers.expat.ExpatError: not well-formed (invalid token): line 24, column 95 

No estoy seguro de que el XML que regresa de esta API esté bien formado: no hay ningún elemento “xml” al comienzo para empezar. Yo no confiaria en eso

No está iterando sobre los elementos de “elemento”, de hecho está iterando sobre los elementos de “elemento”.

Creo que debería ser:

 items = root.findall('items') childItems = items.findall('item') for childItem in childItems: childItem.find('title').text # should print:  childItem.find('link').text # Should print: http://www.allsubs.org/subs-download/heroes+season+4/1223435