kostenloser Webspace werbefrei: lima-city


Daten aus HTMLParser zurückgeben

lima-cityForumProgrammiersprachenPython

  1. Autor dieses Themas

    w*****e

    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
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. 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
  4. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!