BeautifulSoup contents Listen error
Hallo Liste, ich versuche gerade ein eine, naja sagen wir mal, xml-Datei mit BeautifulSoup zu parsen und bekomme dabei eine mir unerklärliche Fehlermeldung. Es ist nicht so das ich diese nicht umgehen könnte, allerdings verwirrt es mich etwas wenn ich aus einer Liste mit der Länge 1 nicht auch das erste Element entnehmen kann. Aber seht selbst: from BeautifulSoup import BeautifulStoneSoup xml = '<HAM><EGG><HAM_ID><![CDATA[12345]]></HAM_ID></EGG></HAM>' soup = BeautifulStoneSoup(xml) for egg in soup('egg'): for ham in egg('ham_id'): print type(ham.contents) print len(ham.contents) print ham.contents print ham.contents[0] == Die Ausgabe lautet: <type 'list'> 1 [u'12345'] Traceback (most recent call last): File "test.py", line 9, in -toplevel- print ham.contents[0] TypeError: 'NoneType' object is not callable Kann mir das jemand Erklären? Gruß Alexander
--On 31. Mai 2008 11:06:55 +0200 "A. Nigl" <newsletter@que-world.net> wrote:
Hallo Liste, ich versuche gerade ein eine, naja sagen wir mal, xml-Datei mit BeautifulSoup zu parsen und bekomme dabei eine mir unerklärliche Fehlermeldung. Es ist nicht so das ich diese nicht umgehen könnte, allerdings verwirrt es mich etwas wenn ich aus einer Liste mit der Länge 1 nicht auch das erste Element entnehmen kann. Aber seht selbst:
from BeautifulSoup import BeautifulStoneSoup xml = '<HAM><EGG><HAM_ID><![CDATA[12345]]></HAM_ID></EGG></HAM>' soup = BeautifulStoneSoup(xml) for egg in soup('egg'): for ham in egg('ham_id'): print type(ham.contents) print len(ham.contents) print ham.contents print ham.contents[0]
==
Die Ausgabe lautet: <type 'list'> 1 [u'12345']
Traceback (most recent call last): File "test.py", line 9, in -toplevel- print ham.contents[0] TypeError: 'NoneType' object is not callable
Funktioniert hervorragend bei mir: ajung@suxmac:~ cat test.py from BeautifulSoup import BeautifulStoneSoup xml = '<HAM><EGG><HAM_ID><![CDATA[12345]]></HAM_ID></EGG></HAM>' soup = BeautifulStoneSoup(xml) for egg in soup('egg'): for ham in egg('ham_id'): print type(ham.contents) print len(ham.contents) print ham.contents print ham.contents[0] ajung@suxmac:~ !py python2.4 test.py <type 'list'> 1 [u'12345'] 12345 Unabhängig von Deinem Problem: XML parst man mit einem XML Parser - nicht mir Beautifulsoup - auch wenn es vorgibt in irgendeiner Form XML parsen zu können. Nimm bitte einer der vielen verfügbaren XML Parser, die es für Python gibt. Andreas
Andreas Jung schrieb:
Funktioniert hervorragend bei mir:
Eigenartig über die Konsole funktioniert es bei mir auch nur idle scheint damit ein Problem zu haben. Ist das ein Bug im idle, oder an irgendeiner meiner configs?
Unabhängig von Deinem Problem: XML parst man mit einem XML Parser - nicht mir Beautifulsoup - auch wenn es vorgibt in irgendeiner Form XML parsen zu können. Nimm bitte einer der vielen verfügbaren XML Parser, die es für Python gibt.
Ich hab mich aus zweierlei Gründen gegen einen der eingebauten XML Parser entschieden: Soup verarbeitet auch nicht standardkonforme xml-Datein, was leider die Regel und nicht die Ausnahme ist. Soup war schnell und einfach einzubauen. Nach kurzer Recherche schien mir das die bessere implementierung für meine Bedürfnisse zu sein oder spricht irgendwas gröberes gegen Soup? Gruß Alexander
--On 31. Mai 2008 13:23:30 +0200 "A. Nigl" <newsletter@que-world.net> wrote:
Ich hab mich aus zweierlei Gründen gegen einen der eingebauten XML Parser entschieden: Soup verarbeitet auch nicht standardkonforme xml-Datein, was leider die Regel und nicht die Ausnahme ist. Soup war schnell und einfach einzubauen
Nicht-standardkonformes XML? Du meinst irgendwas, was kein XML ist? Also Datenmüll? :-) Andreas
Andreas Jung schrieb:
Ich hab mich aus zweierlei Gründen gegen einen der eingebauten XML Parser entschieden: Soup verarbeitet auch nicht standardkonforme xml-Datein, was leider die Regel und nicht die Ausnahme ist. Soup war schnell und einfach einzubauen
Nicht-standardkonformes XML? Du meinst irgendwas, was kein XML ist? Also Datenmüll? :-)
Datenmüll aus dem ich leider was sinnvolles raus extrahieren muss. ;) Alexander
--On 31. Mai 2008 14:53:40 +0200 "A. Nigl" <newsletter@que-world.net> wrote:
Andreas Jung schrieb:
Ich hab mich aus zweierlei Gründen gegen einen der eingebauten XML Parser entschieden: Soup verarbeitet auch nicht standardkonforme xml-Datein, was leider die Regel und nicht die Ausnahme ist. Soup war schnell und einfach einzubauen
Nicht-standardkonformes XML? Du meinst irgendwas, was kein XML ist? Also Datenmüll? :-)
Datenmüll aus dem ich leider was sinnvolles raus extrahieren muss. ;)
XML Präambel vorschalten und dann durch einen XML Parser durchjagen.. ansonsten würde ich nicht das Wort XML in den Mund nehmen :-) Andreas
Hallo! A. Nigl schrieb:
Ich hab mich aus zweierlei Gründen gegen einen der eingebauten XML Parser entschieden:
Gibt ja auch noch andere nicht-eingebaute. Sehr gute sogar.
Soup verarbeitet auch nicht standardkonforme xml-Datein, was leider die Regel und nicht die Ausnahme ist.
"nicht standardkonforme" XML Dateien sind keine XML Dateien, da ist der Standard sehr konkret. Und die sind definitiv die Ausnahme, weil nämlich kein XML Parser die akzeptieren darf.
Nach kurzer Recherche schien mir das die bessere implementierung für meine Bedürfnisse zu sein oder spricht irgendwas gröberes gegen Soup?
Langsamkeit? Speicherverbrauch? http://blog.ianbicking.org/2008/03/30/python-html-parser-performance/ Stefan
On Sat, 31 May 2008 14:47:39 +0200 Stefan Behnel <python-de@behnel.de> wrote:
Nach kurzer Recherche schien mir das die bessere implementierung für meine Bedürfnisse zu sein oder spricht irgendwas gröberes gegen Soup?
Langsamkeit? Speicherverbrauch?
http://blog.ianbicking.org/2008/03/30/python-html-parser-performance/
Ich tät ja "implementation" sagen, denn Markup mit regulären Ausdrücken zu parsen ist irgendwie alles andere als vertrauenserweckend. Manchmal ist auch die API seltsam, das etwas schlichtweg nicht so funktioniert, wie man sich das denken würde und es auch logisch wäre (ich habe dann den Autor um Hilfe gefragt, der auch bald geantwortet hat - das rechne ich BS durchaus an). Ich würde aber inzwischen eher zu lxml tendieren, wenn da noch HTML im Spiel ist auch noch zur html5lib. Insbesondere XPath und CSS Selektoren sind etwas, was BS nicht bieten wird können und die IMHO sehr angehehm sind, wenn man mit XML arbeitet. Disclaimer: ich preise gerade eine Lib an, die von meinem Vorposter maintaint wird. Nichtsdestotrotz ist lxml der derzeit wohl beste Weg aus Python XML-Dateien zu verarbeiten, etwa "making XML suck less". grüße, Marek
Unabhängig von Deinem Problem: XML parst man mit einem XML Parser - nicht mir Beautifulsoup - auch wenn es vorgibt in irgendeiner Form XML parsen zu können. Nimm bitte einer der vielen verfügbaren XML Parser, die es für Python gibt.
Ich hab mich aus zweierlei Gründen gegen einen der eingebauten XML Parser entschieden: Soup verarbeitet auch nicht standardkonforme xml-Datein, was leider die Regel und nicht die Ausnahme ist. Soup war schnell und einfach einzubauen.
Was heisst "das ist die Regel"? Sofern du Einfluss darauf hast sollte es nicht passieren. Und auf jeden Fall sollte der erste "Griff ins Bibiliotheksregal" nach einem echten Parser sein. Wenn das 3rd-party-Sachen sind, dann erstmal Korrektheit anmahnen - wenn man sagt, man liefert XML - dann muss man auch XML liefern. Worum es mir geht ist das du den Eindruck erweckst BS zu verwenden weil es ja sein *koennte* das das XML nicht konform ist. Das waere aber grundfalsch! Nur wenn in einer konkreten Situation nix anderes mehr hilft - *dann* mag das ok gehen. HTML ist da eine andere Sache - weil es eben browserbedingt dort groessere Spielraueme gab & gibt. Diez
Diez B. Roggisch schrieb:
Worum es mir geht ist das du den Eindruck erweckst BS zu verwenden weil es ja sein *koennte* das das XML nicht konform ist. Das waere aber grundfalsch!
Also was ich bekomme ist genau spezifiziert und ist (wenn sich alle Distributoren daran halten würden) auch standardkonformes xml, ich hätte also kein Problem das mit dem inzwischen von mir favorisierten libxml zu parsen. Nun lebe ich aber leider in einer realen/fehlerhaften Welt und habe bei ersten Sichtungen schon gesehen das nun doch nicht alles XML ist was glänzt. Somit brauche ich einen fehlertoleranten Parser, da ich leider keinerlei Einfluss auf die Distributoren nehmen kann (wenn ich die Daten nicht so nehme wie sie kommen, nimmt sie wer anderes). BS erledigt diese Arbeit zu meiner Zufriedenheit, ich werde aber (bei gelegenheit) einmal den libxml testen und über die Daten laufen lassen sollte dieser gleich viele oder mehr Datein sinnvoll parsen können werde ich ihn logischerweise übernehmen. Gruß Alexander Ps.: Um zu meiner ursprünglichen Frage zurück zu kommen, hat jemand von euch den Sample Code mal mit idle laufen lassen und den gleichen Fehler bekommen oder ist das ein Problem das nur ich habe?
Hallo Alexander, On 2008-06-02 16:01, A. Nigl wrote:
Nun lebe ich aber leider in einer realen/fehlerhaften Welt und habe bei ersten Sichtungen schon gesehen das nun doch nicht alles XML ist was glänzt. Somit brauche ich einen fehlertoleranten Parser, da ich leider keinerlei Einfluss auf die Distributoren nehmen kann (wenn ich die Daten nicht so nehme wie sie kommen, nimmt sie wer anderes).
BS erledigt diese Arbeit zu meiner Zufriedenheit, ich werde aber (bei gelegenheit) einmal den libxml testen und über die Daten laufen lassen sollte dieser gleich viele oder mehr Datein sinnvoll parsen können werde ich ihn logischerweise übernehmen.
was ist, wenn Beautiful Soup die Datei ohne zu "meckern" parst, aber nicht das dabei rauskommt, was gemeint ist? Wenn du die Dateien so nimmst, wie sie kommen, kann es passieren, dass sie zwar gelesen werden aber falsche Daten in deiner Anwendung ankommen. (Zum Vergleich: Wenn jemand aus "Geben Sie mir die Hund" fehlertolerant "Geben Sie mir die Hand" macht, könnte er sich irren; vielleicht war "Geben Sie mir den Hund" gemeint.) Wenn du fehlerhaftes XML zurückweist, reduzierst du die Wahrscheinlichkeit solcher "Missverständnisse" schonmal ein Stück weit. Ich empfehle dir, die Wahrscheinlichkeit deiner Aussage "wenn ich die Daten nicht so nehme wie sie kommen, nimmt sie wer anderes" nochmal zu überdenken und, wie von anderen im Thread empfohlen, auf einwandfreiem XML zu bestehen. Du kannst das durchaus professionell - und zutreffend - als Qualitätssicherung verkaufen. Viele Grüße Stefan
-----Ursprüngliche Nachricht----- Von: python-de-bounces@python.net [mailto:python-de-bounces@python.net] Im Auftrag von Stefan Schwarzer Gesendet: Mittwoch, 4. Juni 2008 20:48 An: Die Deutsche Python Mailingliste Betreff: Re: [Python-de] BeautifulSoup contents Listen error
Hallo Alexander,
On 2008-06-02 16:01, A. Nigl wrote: was ist, wenn Beautiful Soup die Datei ohne zu "meckern" parst, aber nicht das dabei rauskommt, was gemeint ist? Wenn du die Dateien so nimmst, wie sie kommen, kann es passieren, dass sie zwar gelesen werden aber falsche Daten in deiner Anwendung ankommen. (Zum Vergleich: Wenn jemand aus "Geben Sie mir die Hund" fehlertolerant "Geben Sie mir die Hand" macht, könnte er sich irren; vielleicht war "Geben Sie mir den Hund" gemeint.) Wenn du fehlerhaftes XML zurückweist, reduzierst du die Wahrscheinlichkeit solcher "Missverständnisse" schonmal ein Stück weit.
Ich kann Alexander schon verstehen. Wenn er keinen Einfluß auf die Qualität hat wird alles "ich will aber nur 100% einwandfreies XML" nur dazu führen das seine Software den gewünschten Nutzen nicht bringen kann. Punktum. Ich hab in meinem Berufsleben solche Fälle schon zigmal gehabt. Hersteller die sich nicht an Specs halten, API's die unvollständig implementiert sind etc. Sich da auf den Standpunkt zu stellen: "damit arbeite ich nicht" hat nur zur Folge das nix passiert. Da ist dann Pragmatismus und nicht Ideologie angesagt. Ob man nun hergehen sollte und eine Bibliothek verwenden sollte, die einen eigenständigen, nicht kontrollierbaren Fehler-Korrekturmechanismus verwendet, sei mal dahingestellt. Für mich wäre hier interessant zu prüfen welche Form von Fehlern vorkommen: sind das eher technische Fehler wie "nicht geschlossene XML-Tags", sind es Syntaxfehler (nicht codierte Sonderzeichen, nicht geschlossene Strings etc) oder sind es eher semantische Fehler (Tags die es lt DTD geben muss sind nicht angegeben). Je nach Typ kann es in BeautifulSoup zu ganz unterschiedlichen gutgemeinten Fehlerkorrekturen kommen - gewollte und ungewollte. Und dann geht Alexander durchaus das Risiko "Hand" oder "Hund" ein. Ich würde da noch einen anderen Gedankengang vorschlagen: je nach Fehlerart könnte man auch ein XML-Lieferant-bezogenes Korrekturscript schreiben das korrektes XML herstellt. Die eigentliche Importschnittstelle erwartet dann 100% perfektes XML. Das trennt Fehlerbehandlung von der eigentlichen Schnittstelle, und hat zudem die Option spezifische Fehlerbehandlungen zuzulassen. Sollte nämlich mal einer der "guten" Lieferanten plötzlich ebenfalls mieses XML liefern dann würde man das mit der Konstruktion mitbekommen, während man sich bei einem BeautifulSoup-Ansatz fälschlicherweise in Sicherheit wiegt. Man minimiert somit die mögliche Fehlerquote durch dedizierte Fehlerbehandlung, und hat einen automatischen Mechanismus für die Qualitätssicherung. Setzt voraus das die Lieferanten konsequent bei ihren Fehlern bleiben, d.h. das es sich lohnt die Fehlerbehandlung gezielt zu implementieren. Wenn man einfach nur aus X Quellen Mist in varierender Qualität geliefert bekommt, dann kann man nur Duftwasser drüberkippen (BeatifulSoup) und hoffen das hinten irgendwas vernünftiges rauskommt. Just my 2cents, Andrew
participants (7)
-
A. Nigl
-
Andreas Jung
-
Andrew Smart
-
Diez B. Roggisch
-
Marek Kubica
-
Stefan Behnel
-
Stefan Schwarzer