Feedparser - speichert nur letzten Node?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Hallo Leute, nach längerer Abstinenz von Python habe ich mal wieder ein kleines Projekt unter Python im Auge.
Ich bitte um Nachsicht, ich bin nach wie vor ein ziemlicher Anfänger in Python.

Hier mein aktuelles Problem:
Ich habe eine URL zu einem XML-Feed welcher mir Sportergebnisse zur verfügung stellt. Konkret Fußballdaten.
Ich möchte die Daten aufteilen und bestimmte Elemente davon weiterverarbeiten.
Kurz recherchiert und auf den 'Feedparser' gestossen. Installiert, ein neues Projekt geöffnet und feedparser importiert.
o.g. URL geparsed und alles sah erstmal gut aus.

Code: Alles auswählen

import feedparser
d = feedparser.parse('http://....URL....')

print d['feed']['tournament']['league']
# -> gibt mir die entsprechende Liga die im entsprechenden Node gespeichert wird
So weit so gut dachte ich mir.
Als ich dann die weiteren Elemente ausgeben wollte, habe ich bemerkt das der feedparser mir lediglich eine Spielepaarung, und zwar die letzte aller Spielpaarungen in dieser XML bereithält.
Ein

Code: Alles auswählen

print d
Hat mir dies dann auch bestätigt (das ganze dictionary wird ja damit ausgegeben).

Wenn ich diese URL im Browser angebe, wird mir die ganze XML angezeigt.
Wenn ich diese XML-Datei auf meine Festplatte speichere, erhält die XML-Datei natürlich auch alle Spielpaarungen. Wenn ich den feedparser dann von dieser lokalen Datei parsen lasse passiert wieder das oben beschriebene.

So, was könnte hier falsch laufen?
Legt feedparser bei gleichen Elementen kein Array/Sub-Dictionary/o.ä. an und überschreibt alle Elemente die er zuvor eingelesen hat und gleiche Nodes hat? z.B. habe ich die Nodes

<spielpaarung no="1">....</spielpaarung>

und

<spielpaarung no="2">.....</spielpaarung>

Ich brauche natürlich jedes Element dieser XML und würde gerne durch die einzelnen Spielpaarungen/Spieltage usw. iterieren/durchschleifen können. In diesem Falle habe ich lediglich die <spielpaarung no="2">....</spielpaarung> zur verfügung?!?

Der feedparser war erst einmal sehr vielversprechend weil es wirklich schnell und sehr einfach war auf die einzelnen Elemente zuzugreifen.
Ich hoffe hier Hilfe von euch zu dazu zu erhalten. Gegenüber Alternativen wäre ich jedoch auch nicht abgeneigt.

Schon einmal im Voraus vielen Dank für eure Mühe.
BlackJack

@kaineanung: Was soll man denn jetzt dazu sagen? `feedparser` sollte bei einem validen Newsfeed alle Daten enthalten. Also entweder ist der Newsfeed kaputt oder `feedparser`. Ohne den Newsfeed zu kennen kann man da logischerweise nichts zu sagen.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@blackjack

Ich hoffte daß mir hier gesagt wird: haja du Seppel, du hast vergessen dies und das zu machen. Typischer Anfängerfehler oder der Gleichen...

Ein Feed ist ja nichts anderes als eine XML-Datei die auf dem Server abgelegt ist.
Wenn ich diese aufmache im Browser, dann wird ja alles angezeigt. Wen nich diese herunterlade und öffne, ebenso.
Daher liegt meiner Vermutung nach kein XML-Fehler vor, oder bin ich da auf dem Irrweg?

XML Validator habe ich gerade auch benutzt und er meint auch 'no errors found'.
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

kaineanung hat geschrieben: Ein Feed ist ja nichts anderes als eine XML-Datei die auf dem Server abgelegt ist.
Wenn ich diese aufmache im Browser, dann wird ja alles angezeigt. Wen nich diese herunterlade und öffne, ebenso.
Daher liegt meiner Vermutung nach kein XML-Fehler vor, oder bin ich da auf dem Irrweg?
Na ja, ich halte das im konkreten Fall für nicht so wahrscheinlich, aber theoretisch besteht schon die Möglichkeit, dass du mit deinem Browser andere Daten erhältst, als mit dem Feedparser. Der Server hat die Möglichkeit, Content abhängig vom Request-Header auszuliefern (https://de.wikipedia.org/wiki/Content_Negotiation).

Bei mir schickt Feedparser folgenden Header:

Code: Alles auswählen

GET /rss HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: UniversalFeedParser/5.2.1 +https://code.google.com/p/feedparser/
Accept-Encoding: gzip, deflate
Accept: application/atom+xml,application/rdf+xml,application/rss+xml,application/x-netcdf,application/xml;q=0.9,text/xml;q=0.2,*/*;q=0.1
A-Im: feed
Connection: close
Wenn du tatsächlich herausfinden möchtest, ob der Server dieselbe Datei verteilt, könntest du also mit einem geeigneten Tool (z.B. händisch per netcat oder notfalls telnet, ansonsten mit curl, python-requests, o.Ä. ) den Header simulieren (insb. Accept, ggf. 'A-IM') und die Ergebnisse vergleichen.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@kaineanung: was meinst Du mit dem "Feedparser"? Bei meinem Feedparser greift man über Attribute auf die Daten zu und da enthält d.entries alle Einträge.
BlackJack

@kaineanung: Ein Feed muss keine Datei sein die auf dem Server liegt, genau wie alles andere was ein Webserver ausliefert kann das auch dynamisch generiert werden. Was bei einem Feed sogar recht wahrscheinlich ist.

Mit valide war nicht nur das XML selbst gemeint, sondern ob sich das Dokument an eine der Feed-Spezifikation hält.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@nezzcarth

Händisch simulieren über Telnet hört sich super an. Was muss ich konkret dabei tun? Gibt es irgendwo eine Kurzinfo was ich nacheinander eingeben muss so ála SMTP-Protokoll mit 'helo' usw..

@Sirius3

Bei mir ist 'entries' leer!
Das sieht ungefähr so aus wenn ich das parse-Ergebnis in 'd' ausgebe:

Code: Alles auswählen

d = feedparser.parse('URL')
print d

#Ergebnis:
{{....Eigene Einträge (Dictionaries).....}, 'encoding': u'utf-8', 'bozo': 0, 'version': u'', 'namespaces': {}, 'entries': []}
Eigene Einträge (Dictionaries) ist dann in diesem Falle das Dictionary mit der letzten Spielpaarung (wer gegen wen, Ergebnis, wo, wann usw...).
Alle anderen Spielpaarungen, die mir in der XML angezeigt werden, sind hier aber nicht vorhanden.

Wenn ich mir das genau anschaue, wird die Vermutung immer stärker daß der Feed doch kaputt ist. Das ich der Erste bin dem das auffällt glaube ich jetzt aber auch nicht...but who knows?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

kaineanung hat geschrieben:

Code: Alles auswählen

import feedparser
d = feedparser.parse('http://....URL....')

print d['feed']['tournament']['league']
# -> gibt mir die entsprechende Liga die im entsprechenden Node gespeichert wird
Das kann nicht sein und wäre bei einem validen Atom oder RSS Feed nicht der Fall.
<spielpaarung no="1">....</spielpaarung>

und

<spielpaarung no="2">.....</spielpaarung>
Das sieht überhaupt nicht nach Atom oder RSS aus.

Dein Problem ist wahrscheinlich dass du feedparser benutzt für etwas nicht nicht wirklich ein Feed, also Atom oder RSS, ist.
BlackJack

@kaineanung: Das `entries` leer ist und es Schlüssel gibt die 'tournament' und 'league' heissen, lässt IMHO ja eher vermuten das Du da irgendeine XML-Datei verarbeitest die überhaupt gar kein RSS- oder Atom-Feed ist.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Ok. Dann war die Aussage wohl falsch das es ein 'Feed' ist.
Auf der Seite, die o.g. Quelle anbietet steht jedoch eindeutig 'XML-Feed' und der Server unterstützt auch ein sogenanntes 'eTag' damit der Enduser eine Kontrolle darüber hat keine Daten doppelt zu beziehen.
Daraus habe ich abgeleitet es sein ein korrektes Feed und wollte natürlich mit dem Feedparser die Daten abgreifen.

Kann ich damit mit sicherheit dann sagen es kein Feed ist und dem Anbieter eine eMail schreiben das er sich gewaltig irrt?
Aber wie passt das zusammen mit dem 'eTag' und kein Feed?

Alternativ könnte ich dann lxtree (o.ä) nutzen um die XML 'manuell zu lesen', richtig?
BlackJack

@kaineanung: Feedparser kann Newsfeeds verarbeiten und normalerweise bezeichnet man auch nur solche als Feeds, also alles was sich so ungefähr an die RSS- oder Atom-Spezifikation hält. „XML-Feed“ kann letztlich aber auch alles mögliche bedeuten, solange es XML ist. ETag und kein Newsfeed passt prima zusammen weil es nicht wirklich zusammengehört. ETag ist Bestandteil des HTTP-Protokolls und kann dementsprechend auch für *alles* was man über HTTP abfragen kann verwendet werden. Webseiten, Downloads, Bilder, und eben *auch* Feeds jeglicher Art.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@Blackjack

Ok, vielen Dank für die Information. Dann habe ich die falschen Schlussfolgerungen aus dem 'eTag' und dem Namen 'Feed' ansich gezogen.
Damit bleibt mir dann nichts anderes übrig als die XML-Daten auf herkömmliche Weise zu parsen.

Was schlägt ihr vor? Soll ich das wie letztes Jahr bei meinem Übungsprojekt mit BeautifulSoup machen? Ich parse dann sozusagen manuell die XML-Structur? Oder das Eine mit 'lxtree' (oder war das lmtree? oder wie auch immer das heisst)? Oder bringe ich hier wieder was durcheinander?

Ihr habt mir jedenfalls mal wieder sehr schnell geholfen. Vielen Dank dafür!

Übrigens: hat das schon jemand mal gesagt das ihr hier das beste deutschsprachige Python-Forum seid? Jedenfalls sage ich es jetzt einmal.. :D
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@kaineanung: XML-Dateien kann man mit lxml bzw. ElementTree parsen, wobei lxml.etree.parse den Vorteil hat, direkt von URLs lesen zu können. Wie Du die Daten weiterverarbeiten willst, kommt auf Deine Daten und Deine Vorlieben an.
Antworten