Mit Python Werte aus einer HTML-Seite auslesen
Dieser Post beschreibt nicht einen allgemeinen Screen-Scraper, sondern ein Script das Variablen aus einer HTML-Seite mit vorgegebenem Format extrahieren kann.
Wenn Sie also den Aufbau der HTML-Seite nicht ändern können, bleibt nichts anderes übrig als das Script anzupassen.
Update 19. Nov. 2019
Das Script lief mit Python 2. Heute sollte besser Python 3 eingesetzt werden. Ein passendes Script gibt es unter HTML auslesen mit BeautifulSoup.
Die Struktur der HTML-Seite
Die HTML-Seite für dieses Script hat folgenden Aufbau:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Eine Tabelle mit Variablen</title> </head> <body> <table> <tr> <td class="name">Spannung</td><td class="value">13</td> </tr> <tr> <td class="name">Strom</td><td class="value">31</td> </tr> </table> </body> </html>
Die Inhalte der td-Elemente werden extrahiert, und das class-Attribut gibt an, was der String sein soll. class="name" gibt an, dass die Zelle einen Variablennamen enthält, während class="value" den Wert der Variablen bezeichnet.
Um das Script relativ einfach zu halten, kann es nur eine Variable pro Zeile der Tabelle geben. Weitere Zellen mit beliebigem Inhalt sind dagegen erlaubt, so lange sie keinen der beiden Attributwerte haben.
Entities wie ℃ (℃) werden nicht expandiert.
Was macht das Script ?
Das Script erwartet ein oder mehrere URLs auf der Kommandozeile. Die entsprechenden Seiten werden geladen und die Variablen gesammelt:
pi@raspberrypi ~ $ python fetch.py http://192.168.1.222/test/variables.html Spannung = 13 Strom = 31 pi@raspberrypi ~ $
Die Ausgabe des Scripts ist nur für den Funktionstest gedacht, denn der User will ja schliesslich mit diesen Variablen etwas anfangen.
Das Script
Das Script wurde mit Python 2.7.3 auf einem Raspberry PI geschrieben und dort auch getestet.
Es benutzt httplib zum Laden der HTML-Seite und die HTMLParser-Klasse um sie zu zerlegen.
"""This script reads a HTML page and extracts variable names and values. The names and values are encoded as table cells with class-attributes like this: <tr> <td class="name">Voltage</td><td class="value">13</td> </tr> The number of variables in the file is not limited, but only one variable definition per table row is allowed. Limits: Entities in names or values will be ignored. V0.01 16-FEB-2014 Te """ import sys import httplib from HTMLParser import HTMLParser from urlparse import urlparse class HTMLHandler( HTMLParser ): """Parses the HTML and collects the variables.""" def __ignore( self, text ): """Ignores the text.""" pass def __addtoname( self, text ): """Adds the test to the name.""" self.__name += text def __addtovalue( self, text ): """Adds the test to the value.""" self.__value += text def handle_starttag( self, tag, attrs ): """Handles the start tag of td.""" if tag == "td": for attr in attrs: if attr[0] == "class": if attr[1] == "name": self.__name = "" self.__texthandler = self.__addtoname elif attr[1] == "value": self.__value = "" self.__texthandler = self.__addtovalue def handle_endtag( self, tag ): """Handles the end tag of td and tr.""" if tag == "td": self.__texthandler = self.__ignore elif (tag == "tr") and (self.__name != ""): self.variables.append( (self.__name, self.__value) ) def handle_data( self, data ): """Forwards the text to the current texthandler.""" self.__texthandler( data ) def __init__( self ): """Initializes the class members.""" HTMLParser.__init__( self ) self.variables = [] self.__texthandler = self.__ignore self.__name = "" self.__value = "" def processpage( url, parser ): """Reads and parses one URL from the command line.""" try: components = urlparse( url ) connection = httplib.HTTPConnection( components.netloc ) connection.putrequest( "GET", components.path ) connection.putheader( "Accept", "text/html" ) connection.endheaders() reply = connection.getresponse() if reply.status != 200: print "Error: {0} {1} {2}".format( url, reply.status, reply.reason ) else: body = reply.read() reply.close() parser.feed( body ) except Exception as exception: print "Error: {0} {1}".format( url, exception ) def main( argv ): """The main function of the script.""" parser = HTMLHandler() for url in argv[1:]: processpage( url, parser ) for var in parser.variables: print "{0} = {1}".format( var[0], var[1] ) if __name__ == "__main__": main( sys.argv )
Ueber diesen Link können Sie das Script herunterladen.