Daten aus HTMLParser zurückgeben
lima-city → Forum → Programmiersprachen → Python
aufrufen
code
datei
dokumentation
ergebnis
globale ergebnis
http
import
links code
links ergebnis
links http
links links ausgabe
listen
methode
problem
semantik
tag
text
tip
zuweisung
-
Guten Tag allerseits,
ich habe mir für ein Projekt ein Script gebaut, bei dem ich alle Links aus einer Html-Datei bekommen möchte.
Hier ist einmal der Code:
from HTMLParser import HTMLParser links = [] class MyHTMLParser(HTMLParser): def handle_starttag(self, tag, attrs): if tag.startswith('a'): for attr in attrs: if attr[0].startswith('href'): link = attr[1] links.append(link) print links return links parser = MyHTMLParser() links = parser.feed('<a href="http://pbeckmann.de"><a href="http://pbeckmann.de">') print parser print links[/code die Ausgabe ist die folgende: [code]['http://pbeckmann.de'] ['http://pbeckmann.de', 'http://pbeckmann.de'] <__main__.MyHTMLParser instance at 0xb748dd8c> None
Mein Problem ist, dass da wo das None steht meiner Meinung nach eigentlich dasselbe wie in der zweiten Zeile stehen müsste. Leider habe ich noch nicht soviel Erfahrung mir Python und wollte deswegen wissen, ob einer von euch eine Idee zu meinem Problem hat.
Viele Grüße -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hi,
ich habe zwar keine Ahnung von Python, aber die OO-Prinzipien sind oft sehr ähnlich. Dieser Schnipsel funktioniert wie gewünscht:
from HTMLParser import HTMLParser links = [] # globale Variable: nicht gut class MyHTMLParser(HTMLParser): def handle_starttag(self, tag, attrs): if tag.startswith('a'): for attr in attrs: if attr[0].startswith('href'): link = attr[1] links.append(link) print "in: ",link return links def feed(self, text): # super(MyHTMLParser,self).feed( text ) # geht nicht - k.A. warum... HTMLParser.feed(self, text) # Basisklasse erledigt die Arbeit return links # Ergebnis (aus globaler Variable - urgh!) parser = MyHTMLParser() links = parser.feed('<a href="http://pbeckmann.de"><a href="http://pbeckmann.de/2">') print "links : ", links #-- Ausgabe # in: http://pbeckmann.de # in: http://pbeckmann.de/2 # links : ['http://pbeckmann.de', 'http://pbeckmann.de/2']
Wenn Du link = parser.feed(...) aufruft, dann wird die Methode parser() von HTMLParser aufgerufen, da Du in MyHTMLParser diese Methode nicht überschrieben hast. (Edit:)MyHTMLParser::parser() kennt jedoch Deine globale Variable links[] nicht und weiß auch nicht, dass Du diese Liste als Ergebnis haben möchtest. Vielleicht gibt es eine andere Möglichkeit, das Ergebnis aus der Callback-Methode (handle_starttag) an die Basisklasse zu übergeben? Dazu müsste man die Dokumentation von HMTLParser lesen
Die Lösung besteht darin, die Methode feed zu überschreiben. Diese ruft nun die Methode selben Namens der Basisklasse auf und gibt dann das Ergebnis zurück. Ist nicht schön, funktioniert aber. Nicht schön, weil die Basisklassendefinition scheinbar nicht vorsieht, dass diese Methode ein Ergebnis zurückliefert und weil hier der Rückgabewert nicht aus einer Objektvariable stammt. Ggf. Macht es Sinn eine Methode get_links() einzuführen, die dann das Ergebnis zurückgibt?
Alternativ könntest Du auch in Deiner ursprünglichen Version die Zuweisung links = parser.feed(...) weglassen und nur parser.feed() aufrufen (Du überschreibst das globale Ergebnis mit dem leeren Rückgabewert der Methode der Basisklasse). Das Ergebnis steht ja schon in links (globale Variable) und müsste nur noch ausgegeben werden.
Einfachste Lösung:
#falsch: links = parser.feed('<a href="http://pbeckmann.de"><a href="http://pbeckmann.de">') #korrekt (links nicht überschreiben): parser.feed('<a href="http://pbeckmann.de"><a href="http://pbeckmann.de">')
Noch ein Tipp: Verwende besser eine Objektvariable (etwa: self.links) statt der globalen Variable (links). Wenn Du mehrere Instanzen von MyHTMLParser verwendest, könnte es sonst passieren, dass sie sich gegenseitig die Link-Listen überschreiben. Hier eine Variante, die das umsetzt und außerdem nicht die Semantik der Methode feed() verändert. Das Ergebnis wird per get_links() übergeben.
from HTMLParser import HTMLParser class MyHTMLParser(HTMLParser): def __init__(self): HTMLParser.__init__(self) # Konstruktor der Basisklasse aufrufen self.links = [] # Objektvariable initialisieren def handle_starttag(self, tag, attrs): if tag.startswith('a'): for attr in attrs: if attr[0].startswith('href'): link = attr[1] self.links.append(link) print "in: ",link return # scheinbar erwartet HTMLParser hier keinen Rückgabewert? def get_links(self): return self.links parser = MyHTMLParser() # Keine Zuweisung an die "links"-Variable, das ist ein extra Schritt, # hier wird HTMLParser.feed() verwendet! parser.feed('<a href="http://pbeckmann.de"><a href="http://pbeckmann.de/2">') links = parser.get_links() print "links : ", links #-- Ausgabe # in: http://pbeckmann.de # in: http://pbeckmann.de/2 # links : ['http://pbeckmann.de', 'http://pbeckmann.de/2']
HTH
Beitrag zuletzt geändert: 20.1.2013 17:49:26 von perlbotics -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage