Stundenplan mittels Httpmod auslesen | Html Tabelle parsen

Begonnen von Aekschn, 13 Januar 2022, 13:58:16

Vorheriges Thema - Nächstes Thema

Aekschn

Hallo zusammen,
ich möchte gern den Stundenplan meines Filius von der Seite der Schule abrufen und entsprechende Readings mit Tag, Stunde und Vertreter in FHEM generieren.
Leider wird der Stundenplan als HTML-Table bereitgestellt und ich habe keinen Schimmer wie ich die Daten abgreifen kann.
Hier der Plan: http://waldorfschule-minden.de/vertret/jetzt.html
Hat jemand eine Idee wie ich daran gehen kann?

Vielen Dank vorab!
Florian

mr_petz

#1
Hi.
Das geht denke ich nur mit httpmod und regex.
Auf deiner angegebenen Seite gibt es aber im Code keine ID´s oder Ansetzpunkte wo regex gut anzuwenden ist. (so gut kann ich das leider auch nicht :-[)
Bei einer html Seite ist halt bissl schwierig...
Aber zum Anfang habe ich dir ein Beispiel erstellt.

Hier ein Bsp:

defmod VPWaldorf HTTPMOD http://waldorfschule-minden.de/vertret/jetzt.html
attr VPWaldorf userattr reading01Regex
attr VPWaldorf reading01Regex size=5>([A-z].*)</font></i></b>
attr VPWaldorf room Schule

setstate VPWaldorf 2022-01-13 21:01:32 reading01 Vertretungsplan 18. Schulwoche

Hier siehst du dann im reading01 den Text: Vertretungsplan 18. Schulwoche

Auf der Seite *ttps://regex101.com/ kannst du zum testen den html-code deiner Seite einfügen und "regexen" damit du weisst wie es geht.
Du müsstest "nur" ein / mit einem \ escapen damit das regex funktioniert. fhem ist da lockerer. Bsp: <\/font>
Den Backslash musst du aber dann in fhem wieder rausnehmen.
Für andere Hinweise bin ich auch offen...

LG mr_petz

Edit: Hier ist auch ein Beispiel wie man es aufbauen kann:
https://forum.fhem.de/index.php/topic,78553.msg724733.html#msg724733
Aber wie gesagt es gibt bei deiner Seite keine id="" oder spezielle Ansetzpunkte um einzelne Sachen rauszufiltern....

OdfFhem

@Aekschn

Geht es um einen Stundenplan oder wirklich nur um den verlinkten Vertretungsplan ?

Angenommen, man hat jedes Tabellenfeld "erkannt" und in einem eigenen Reading festgehalten; was wäre denn jetzt Dein nächster Schritt bzw. was würdest Du  mit den Readings machen ?

Aekschn

Hallo zusammen,

danke für den ersten Ansatz, bringt mich aber leider so noch nicht weiter da ich gerne ein Reading in dem die Vertretungsplaneinträge für die 1. Klasse hervorgehen.
@OdfFhem
Ich möchte das Reading dann verwenden um mich entsprechend via Telegram informieren zu lassen wenn es Einträge gibt.

Gruß
Florian

OdfFhem

@Aekschn

Klingt so ähnlich wie bei den (vielen) HTTPMOD-Devices, die regelmäßig auf Updates prüfen.
Dort wird zunächst die "Quelle" auseinandergenommen und in vielen Einzelreadings abgelegt.
Zum Abschluss wird aus den vielen Einzelreadings EIN spezielles Reading generiert.

Der_Tom

#5
Zitat von: Aekschn am 16 Januar 2022, 10:02:45
Hallo zusammen,

danke für den ersten Ansatz, bringt mich aber leider so noch nicht weiter da ich gerne ein Reading in dem die Vertretungsplaneinträge für die 1. Klasse hervorgehen.
@OdfFhem
Ich möchte das Reading dann verwenden um mich entsprechend via Telegram informieren zu lassen wenn es Einträge gibt.

Gruß
Florian

wie mr_petz schon sagte , macht es das fehlen eindeutiger Ansatzpunkte im HTML echt ätzend.
Ist denn das Layout der seite IMMER gleich ? d.H werden nur dieInhalte der Zellen ersetzt ?

Dann könnte man schon etwas basteln , wenn man immer weiss , in welcher tabellenzelle ( z.B von oben nach unten gezählt ) welche Information steht.

READINGS:
     2022-01-16 11:55:46   BLOCK           no match
     2022-01-16 11:55:46   Next_Timer      no_timer
     2022-01-16 11:55:46   Stunde          no match
     2022-01-16 12:00:02   ZELLE           Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,4 Cagri,Kein Eintrag,Kein Eintrag,4 Thomas,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag
     2022-01-16 12:00:02   ZELLE_0         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_1         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_10        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_11        4 Thomas
     2022-01-16 12:00:02   ZELLE_12        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_13        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_14        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_15        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_16        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_17        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_18        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_19        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_2         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_20        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_21        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_22        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_23        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_24        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_25        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_26        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_27        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_28        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_29        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_3         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_30        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_31        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_32        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_4         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_5         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_6         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_7         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_8         4 Cagri
     2022-01-16 12:00:02   ZELLE_9         Kein Eintrag
     2022-01-16 12:00:02   last_ID         match


gruss Thomas



attr testdevice MSwitch_ExtraktfromHTTP ZELLE-><td style="border-.*: .px solid #000000; border-.*: 3px solid #000000.*><font face="Liberation Serif" size=3>(.*)</font></td>\
\
\

attr testdevice MSwitch_ExtraktHTTPMapping \<br\>->Kein Eintrag\



edit1: regex geändert - trifft aber noch nicht ALLE relevanten zellen , da müsste man nochmal schauen inwiefern sich die fehlenden htmlteile unterscheiden

yersinia

viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

Aekschn

Zitat von: Der_Tom am 16 Januar 2022, 11:35:07
wie mr_petz schon sagte , macht es das fehlen eindeutiger Ansatzpunkte im HTML echt ätzend.
Ist denn das Layout der seite IMMER gleich ? d.H werden nur dieInhalte der Zellen ersetzt ?

Dann könnte man schon etwas basteln , wenn man immer weiss , in welcher tabellenzelle ( z.B von oben nach unten gezählt ) welche Information steht.

READINGS:
     2022-01-16 11:55:46   BLOCK           no match
     2022-01-16 11:55:46   Next_Timer      no_timer
     2022-01-16 11:55:46   Stunde          no match
     2022-01-16 12:00:02   ZELLE           Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,4 Cagri,Kein Eintrag,Kein Eintrag,4 Thomas,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag,Kein Eintrag
     2022-01-16 12:00:02   ZELLE_0         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_1         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_10        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_11        4 Thomas
     2022-01-16 12:00:02   ZELLE_12        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_13        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_14        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_15        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_16        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_17        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_18        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_19        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_2         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_20        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_21        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_22        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_23        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_24        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_25        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_26        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_27        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_28        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_29        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_3         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_30        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_31        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_32        Kein Eintrag
     2022-01-16 12:00:02   ZELLE_4         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_5         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_6         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_7         Kein Eintrag
     2022-01-16 12:00:02   ZELLE_8         4 Cagri
     2022-01-16 12:00:02   ZELLE_9         Kein Eintrag
     2022-01-16 12:00:02   last_ID         match


gruss Thomas



attr testdevice MSwitch_ExtraktfromHTTP ZELLE-><td style="border-.*: .px solid #000000; border-.*: 3px solid #000000.*><font face="Liberation Serif" size=3>(.*)</font></td>\
\
\

attr testdevice MSwitch_ExtraktHTTPMapping \<br\>->Kein Eintrag\



edit1: regex geändert - trifft aber noch nicht ALLE relevanten zellen , da müsste man nochmal schauen inwiefern sich die fehlenden htmlteile unterscheiden

Hallo Thomas,

Nach Rücksprache soll das Layout immer gleich sein. Kannst du mir den define Code für dein Testdevice schicken? Ich finde das Attribut MSwitch_Extract ... nirgends.

Danke vorab Grüße
Florian

mr_petz


CoolTux


#!/usr/bin/perl -w
###############################################################################
#
# Developed with VSCodium and richterger perl plugin.
#
#  (c) 2022 Copyright: Marko Oldenburg (development@cooltux.net)
#  All rights reserved
#
#
#  This script is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  any later version.
#
#  The GNU General Public License can be found at
#  http://www.gnu.org/copyleft/gpl.html.
#  A copy is found in the textfile GPL.txt and important notices to the license
#  from the author is found in LICENSE.txt distributed with these scripts.
#
#  This script is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#
###############################################################################
use strict;
use warnings;

use Carp;
use feature qw (say);
use Encode qw(decode encode);

use HTTP::Tiny;            # apt install libhttp-tiny-perl
use HTML::TableExtract;    # apt install libhtml-tableextract-perl

# use experimental qw(switch);

use Readonly;              # apt install libreadonly-perl

#
### config
Readonly my $URL => 'http://www.zille-schule.de/vertretungsplan-sp-1045441587';

### Script
# instantiating the HTTP variable
my $httpVariable = HTTP::Tiny->new;

# storing the response using the get
# method
my $response = $httpVariable->get($URL);

# checking if the code returned successful
if ( $response->{success} ) {

    # my $te =
    #   HTML::TableExtract->new(
    #     headers => [qw(Stunde Klasse Lehrkraft Bemerkung)] );

    my $te = HTML::TableExtract->new( depth => 0, count => 1 );

    $te->parse( decode( 'UTF-8', $response->{content} ) );

    foreach my $ts ( $te->tables ) {
        foreach my $row ( $ts->rows ) {
            if ( $row->[1] ) {
                say 'Klasse: '
                  . encode( 'UTF-8', $row->[1] )
                  . ' | Stunde: '
                  . encode( 'UTF-8', $row->[0] )
                  . ' | Lehrer: '
                  . encode( 'UTF-8', $row->[2] )
                  . ' | Bemerkung: '
                  . encode( 'UTF-8', $row->[3] )
                  if ( grep { /^\d[a-d]/x } $row->[1] );
            }
        }
    }
}

# logic for when the code is
# unsuccessful
else {

    # displating the reason for failed
    # request
    say 'Failed to establish connection: '
      . $response->{status}
      . $response->{reasons};
}

exit(0)


Zum rumspielen. Einfach als test.pl unter Linux abspeichern. Dann die URL anpassen und ganz wichtig depth und count anpassen. wenn es 2 oder mehr Tabellen sind. Musst auch schauen wie viele Spalten und wie die heißen damit die Ausgabe richtig ist.
Ist aber nur zum rumspielen und ausschließlich für HTML Tabellen.
Bitte auch beachten welche zusätzlichen Module noch benötigt werden.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net