parameter extrahieren aus html

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • ich würde in PYTHON gerne folgenden regulären Ausdruck benutzen um aus einer html Seite, die ich als file lese, bestimmte ids zu extrahieren:

    r'[id=\"M_][id=\"S_]+\"'

    Ziel soll ein dictionary sein, mit allen gefundenen ids:

    {"M_22_V": "",
    "M:33_V":""
    }

    ich kann mir vorstellen den string der Sete entsprechend r zu suchen und dann aus der Seite zu löschen.

    git es einen besseren, einfacheren Weg?
    Es kommt nicht auf Laufzeit an, da ich den Vorgang im init Teil eines Objekts nur einmal durchlaufe

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

  • Gemäß der Überschrift nennt sich das: parse'n

    Hast du die html lokal oder remote vorliegen?
    Aber ich versteh nicht so richtig was deine Frage ist - ohne den HTML Quellcode zu sehen kann man dazu nicht viel sagen...

    Es gibt mehrere Möglichkeiten eine Datei parsen. Der allgemein übliche Weg ist mithilfe von BeautifulSoup oder lxml. Speziell im Fall von HTML empfehle ich aber HTMLParser.. Aber wie gesagt, ohne zu wissen wie dein HTML Quellcode aussieht vermag ich nicht mehr dazu zu sagen :s


  • Gemäß der Überschrift nennt sich das: parse'n

    Hast du die html lokal oder remote vorliegen?
    Aber ich versteh nicht so richtig was deine Frage ist - ohne den HTML Quellcode zu sehen kann man dazu nicht viel sagen...

    Es gibt mehrere Möglichkeiten eine Datei parsen. Der allgemein übliche Weg ist mithilfe von BeautifulSoup oder lxml. Speziell im Fall von HTML empfehle ich aber HTMLParser.. Aber wie gesagt, ohne zu wissen wie dein HTML Quellcode aussieht vermag ich nicht mehr dazu zu sagen :s

    ich habe die Datei lokal als File vorliegen und bearbeite sie in meinem Meldungs- und Messwertverarbeitungs Prozess. ich erstelle damit die Rückantwort für eine Ajax Anfrage der Seite, um diese an den webserver als json objekt (dictionary) zu senden.

    hier das File, erst mal rudimentär:

    Panel_Datenstrukturen.xlsx

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

    Einmal editiert, zuletzt von Wolfgang Glück (12. Februar 2016 um 14:50)

  • Hm wie kannst du die Datei lokal vorliegen haben? Wird die nicht erst mithilfe von tornado mit deinen Queue's befüllt? Weil es geht ja anscheint um dein Robot.

    Und für was brauchst du es? Python2 oder Python3? :fies:

    Anyway

    Code
    pip3 install beautifulsoup4


    [code=php]from bs4 import BeautifulSoup
    import urllib.request

    target = 'http://raspberrypi.roxxs.org/test/r.html'
    req = urllib.request.Request(url=target)
    f = urllib.request.urlopen(req)
    xhtml = f.read()

    soup = BeautifulSoup(xhtml, 'html.parser')
    for td in soup.find_all('td'):
    id = td.get('id')
    if id: print(id)
    [/php]

  • Hallo meigraf, es geht mir sicher um meinen Roboter und ich verwende python 3.4

    ich gehe folgenden Weg:
    Webbrowser hat die seite Panel.html im Bauch
    Webbrowser fordert die daten per Ajax für Panel.html an ohne Deteils zu nennen, denn die sind ja im Backend bekannt.
    Webserver schickt die Anforderung über die Queue an den Meldungs- und Messwertverarbeitungs-Prozess.
    Meldungs und Messwertverarbitungs-Prozess baut ein dictionary mit den dynamischen Daten für die Seite auf und schickt das Dictionary über die Queue an den Webserver zurück
    Webserver gibt die Ajax Antwort zurück, jscript baut die gelieferten Daten in die Seite ein.

    So und nun soll der Messwert- und Meldungsverarbeitungs-Prozess schlicht aus der Panle.html die Details für den Aufbau des dictionaries extrahieren (parsen meinetwegen)
    daher liest dieser Prozess die Panel.html aus dem Filesystem. Was ist daran nicht zu verstehen?

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

  • Vieles gibt es daran nicht zu verstehen ;) Ich bin einer der wenigen hier die ein Projekt schon länger betreut, aber ein Außenstehender kann das ME anhand des hier bisher geschriebenen nicht nachvollziehen.

    Nicht der Webbrowser hat die Panel.html vorliegen und auch wird nicht der Client mithilfe von python irgend was verarbeiten...

    Deine Panel.html wird dynamisch von tornado erzeugt bzw befüllt. Du hast nur ein Grundgerüst lokal liegen. Das fertige Ergebnis wird einem möglichen Client angezeigt.

    Ein Javascript eines Clients stellt eine Anfrage an den Webserver. Dieser wiederum schickt Daten zurück und das Javascript aktualisiert irgendwelche Felder.

    Es kann also zu keinem Zeitpunkt eine bereits fertig befüllte Datei lokal auf irgend einem Dateisystem vorhanden sein - du hast die befüllte Panel.html nicht lokal liegen, wenn dann nur im entferntesten Sinne im Ram von tornado.

    Dieser Umstand verwirrt denn Deine Aussage sagt was anderes. Wenn du auf deiner Seite ein Rechtsklick machst und dann Seitenquelltext-anzeigen, ist das was anderes als wenn ein auf dem Pi laufendes Python Script auf eine Datei zugreifen würde - das würde in dem Fall nicht funktionieren. Deshalb habe ich bewusst urllib.request ins Beispiel oben eingefügt, da ich davon überzeugt bin dass die befüllte Tabelle nur Dynamisch verfügbar ist - erst nachdem tornado diese an den Client gesendet und dessen Javascript die id's befüllt hat.

  • Wenn man das missverstehn will wird man es auch!
    Natürlich hat der webbrowser nicht das file im Bauch sondern dessen Inhalt!
    Ich erwarte kein fertig befülltes File! ich will das dictionary für die dynamischen daten im Backend mit den Schlüsseln aus dem html file befüllen! anschliessend mit den daten aus dem Daten abbild und dann an den webserver zurückgeben!

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

  • Wie meigrafd schon richtig sagt, BeautifulSoup ist da dein Freund. Du müsstest etwas in der Art machen:

    Code
    def get_ids(html_file, regular_expression):
        soup = BeautifulSoup(html_file, 'html.parser')
        ids = dict()
        for element in soup.find_all('td', id=re.compile(regular_expression)):
            ids[element.id] = ""
        return ids

    Wobei html_file der Inhalt deiner HTML Datei ist und regular_expression dein Regulärer Ausdruck zum filtern der vorkommenden ids.

    Nebenbei denke ich kaum, dass meigrafd deine Beiträge missverstehen wollte. ;)

    Edit: Danke an meigrafd für den Hinweis! Könnte man sicherlich mit lambdas schöner machen, aber für mich ist das schwarze Magie und Hexerei...

    Einmal editiert, zuletzt von Chris1705 (12. Februar 2016 um 17:12)

  • :thumbs1:

    Da fehlt ME noch ein "return ids" nach der "for" :fies:
    Also so:

    Code
    def get_ids(html_file, regular_expression):
        soup = BeautifulSoup(html_file, 'html.parser')
        ids = dict()
        for element in soup.find_all('td', id=re.compile(regular_expression)):
            ids[element.id] = ""
        return ids

  • :thumbs1:

    Da fehlt ME noch ein "return ids" nach der "for" :fies:
    Also so:

    ich mach da noch etwas falsch, ich beomme nur ein leeres dictionary zurück
    fehlt da nicht noch ein update auf das dictionary?

    die Seite:

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

    Einmal editiert, zuletzt von Wolfgang Glück (12. Februar 2016 um 19:11)

  • Vielleicht hilft das zum Verständnis:

    ich würde allerdings das with Statement verwenden, das kümmert sich dann auch ums schließen des fileHandlers. Allerdings muss man die Datei nicht vorher auch noch auslesen (read()), das macht BeautifulSoup selber ;)

    //EDIT:
    Meine oben gezeigte Lösung gefällt mir aber irgendwie besser weil man dann tatsächlich nur die id's kriegt, egal ob nun M_ oder S_ :fies:

  • ich verstehe nur noch Bahnhof

    1. meine regular expression ist also falsch was wird erwartet?
    2. ich will ja als Ergebnis nicht die ganze td Zeile sondern nur den inhalt des id (z.B. "MV_15_V") dieser key solle rgänzt werden um den value ""

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

  • 1. meine regular expression ist also falsch

    Ja.
    Siehe:

    Code
    >>> fh = codecs.open("r.html", "r", encoding='utf-8', errors='ignore')
    >>> soup = BeautifulSoup(fh, 'html.parser')
    >>> for element in soup.find_all('td', id=re.compile(r'[id="M_][id="S_]+"')):
    ...   print(element)
    ... 
    >>>


    Mit Deiner re kommt keine Ausgabe. Das Problem ist dass du sowohl M_ als auch S_ erwartest, du musst aber angeben "entweder oder" => '[id="M_]|[id="S_]+"'
    (das r kannst du übrigens auch weg lassen)

    Code
    >>> for element in soup.find_all('td', id=re.compile('[id="M_]|[id="S_]+"')): 
    ...   print(element)
    ... 
    <td class="mv right c-3" id="M_15_V">270.3</td>
    <td class="mv right c-3" id="M_11_V">1</td>
    <td class="mv right c-3" id="M_13_V">270.5</td>
    <td class="mv right c-3" id="S_12_V">-2</td>
    >>>

    2. ich will ja als Ergebnis nicht die ganze td Zeile sondern nur den inhalt des id (z.B. "MV_15_V") dieser key solle rgänzt werden um den value ""

    Das dachte ich mir schon ;) verwende einfach das aus Beitrag#4 als Funktion => Siehe EDIT von Beitrag#12

  • so jetzt hat der alte Mann das verstanden und umgesetzt

    Es gibt natürlich uU weitere ids, die ich nicht auslesen möchte deshalb doch die regular expression!

    Ergebnis:

    Code
    {"M_12_V": "", "M_11_V": "", "M_15_V": "", "M_13_V": ""}


    Automatisch zusammengefügt:
    Vielen Dank für Eure Geduld mit dem alten Mann

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

    Einmal editiert, zuletzt von Wolfgang Glück (12. Februar 2016 um 20:07)

  • Wie gesagt ich würde das "open" direkt in die Funktion einfügen da dass nun mal zu der Funktion an sich gehört, wieso sollte man das vorher machen müssen :-/
    Und da es Probleme mit dem Encoding geben kann, im Bezug auf "non ASCII" Zeichen, wäre die von mir verwendete codecs Variante besser ;)
    Es hatte schon gute Gründe wieso ich das so umgesetzt hab :fies:


    PS: Um so weniger Variablen du definierst um wo weniger RAM wird verbraucht. "ids" vorher zu befüllen bevor es von json behandelt wird ist also eigentlich überflüssig.

  • ich lerne ja gerne dazu, allerdings ist die Geschwindigkeit und der Abstraktionslevel hier manchmal etwas hoch.

    Wenn dann noch Schreibweisen auftauchen, die in keim Buch stehen und auch nicht in der PYTHON doku zu finden sind, dann bin ich erst mal am grübeln...

    final version:

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

  • Das liegt an meinem Projektbaum, das muss so sein


    Zu den Variablen kann ich nur sagen, ich lege Wert auf Performance wenn diese Daten im 1 s Takt angefordert werden, dann möchte ich das dictionary nicht jedesmal von Grund auf neu erzeugen müssen

    Softwarefehler suchen ist wie Pilze suchen. Wenn man erst einen gefunden hat, findet man meist mehrere.

    Bei Hardware ist es schlimmer, da findet man bereits Fehler wenn man gar keine sucht!

  • Das liegt an meinem Projektbaum, das muss so sein

    Hm, das kann ich nicht nachvollziehen - ich glaube (ohne herabwertend wirken zu wollen) dass das nur auf "Unwissen" basiert. Ich weiß das so eine Schreibweise weit verbreitet ist (auch sowas wie zB "/home/pi/./script.py"), es ist aber unnötig - gut, mag auch letztlich nicht sooo viel Unterschied ausmachen, nur denk ich, vergisst man son "." schon evtl. mal und dann ist das Ergebnis plötzlich ein völlig anderes, und Ausführen willst du ja auch nichts.. Also alleine wegen letzterem ist der Eindruck schon komisch ;)

    Zu den Variablen kann ich nur sagen, ich lege Wert auf Performance wenn diese Daten im 1 s Takt angefordert werden, dann möchte ich das dictionary nicht jedesmal von Grund auf neu erzeugen müssen

    Jetzt bin ich verwirrt. Durch " ids = " wird eine ggf zuvor gesetzte Variable vollständig überschrieben. Oder speicherst du das irgendwie?

    Wie gesagt vorbraucht das mehr Arbeitsspeicher:

    Code
    ids = get_ids("./Robbi/Panel.html", r'["id=M_]|["id=S_]+"')
    ouput = json.dumps(ids)


    Als das:

    Code
    ouput = json.dumps(get_ids("./Robbi/Panel.html", r'["id=M_]|["id=S_]+"'))

    vor allem wenn du mit der Variable "ids" später nicht mehr weiter arbeitest.


    Ich will dir aber auch nichts aufzwingen - dachte nur ich erwähne's mal da dein Projekt ja allgemein größer ist, da kann sowas früher oder Später schon von Bedeutung werden.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!