Hilfe bei Webseite auslesen

Begonnen von Marko1976, 07 Dezember 2025, 22:19:12

Vorheriges Thema - Nächstes Thema

Marko1976

Hallo, ich bräuchte mal wieder Hilfe beim Auslesen einer Webseite.
Dachte eigentlich das ich das Thema langsam verstanden hätte, aber bei dem Seitenquellcode weiß ich nicht mehr weiter.

Hier erst mal ein List des Device, das als Grundlage einer alten Version mit anderer Quelle dient (leider ändert sich jedesjahr die url weshalb ich jedesmal alles anpassen musste):
Internals:
   BUSY       0
   DEF        https://www.haie.de/saison/tabelle/ 86400
   FUUID      671e62d1-f33f-7706-01ec-89182b86d32be66e
   FVERSION   98_HTTPMOD.pm:0.291590/2024-09-23
   Interval   86400
   MainURL    https://www.haie.de/saison/tabelle/
   ModuleVersion 4.2.0 - 11.8.2023
   NAME       DEL_table
   NOTIFYDEV  global
   NR         404
   NTFY_ORDER 50-DEL_table
   STATE      name-1
   TYPE       HTTPMOD
   eventCount 2
   value     
   CompiledRegexes:
   HTTPCookieHash:
     PHPSESSID;/:
       Name       PHPSESSID
       Options    path=/; HttpOnly
       Path       /
       Value      7sqhm4ld377n963fpk8dp7lpv6
   HttpUtils:
     NAME       
     addr       https://www.haie.de:443
     auth       0
     buf       
     code       200
     compress   1
     conn       
     data       
     displayurl https://www.haie.de/saison/tabelle/
     header     Cookie: PHPSESSID=7sqhm4ld377n963fpk8dp7lpv6
     host       www.haie.de
     httpheader HTTP/1.1 200 OK
Server: nginx
Date: Sun, 07 Dec 2025 21:10:09 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 15182
Connection: close
vary: X-Forwarded-Proto,Accept-Encoding
last-modified: Sun, 07 Dec 2025 21:02:50 GMT
etag: "3b4e-6456300595dd4"
referrer-policy: no-referrer-when-downgrade
content-encoding: gzip
X-Varnish: 22137547 22786412
Age: 38
Via: 1.1 haie00 (Varnish/7.7)
Accept-Ranges: bytes
x-cache: hit cached
Strict-Transport-Security: max-age=31536000
     httpversion 1.0
     hu_blocking 0
     hu_filecount 1
     hu_port    443
     hu_portSfx
     ignoreredirects 1
     loglevel   4
     path       /saison/tabelle/
     protocol   https
     redirects  0
     timeout    30
     url        https://www.haie.de/saison/tabelle/
     sslargs:
   OLDREADINGS:
   QUEUE:
   READINGS:
   REQUEST:
     context    reading
     data       
     header     
     ignoreredirects 0
     num        unknown
     retryCount 0
     type       update
     url        https://www.haie.de/saison/tabelle/
Attributes:
   alias      DEL Tabelle
   enableControlSet 1
   group      Eishockey
   icon       Wunderlist
   preProcessRegex s/<thead>.*<\/thead>//s
   reading01Name name
   reading01RegOpt g
   reading01Regex <tr class=""><td><div class="data-table__index-column"></div></td><td>(.*)</td></tr>
   reading02Name matches
   reading02RegOpt g
   reading02Regex <tr class=""><td><div class="data-table__index-column"></div></td><td>(.*)</td><td>(.*)</td></tr>
   reading03Name points
   reading03RegOpt g
   reading03Regex <span title="PUNKTE">(.*)<\/span>
   reading04Name goals
   reading04RegOpt g
   reading04Regex <span title="TORE">(.*)<\/span>
   reading05Name goalsDiff
   reading05RegOpt g
   reading05Regex <span title="DIFF">(.*)<\/span>
   reading06Name platz
   reading06RegOpt g
   reading06Regex <td  data-headline="PLATZ" style=".*">(.*)<\/td>
   reading07Name logo
   reading07RegOpt g
   reading07Regex <div  style="height: 4rem;background: (.*) no-repeat center center / contain"><\/div>
   readingOExpr $val =~ s/<[\d\D]+>//;;$val
   room       Information->Sport
   stateFormat name-1
   timeout    30
   userattr   .*
   verbose    0

Habe schon mal angefangen bei Name und Matches, doch glaube nicht das das korrekt ist.

Hier der Seitenquelltext um den es geht (Auszug für einen Verein):
<tr class="">
<td>
<div class="data-table__index-column">
<div class="data-table__index">2.</div>
<div class="team-icon" data-tippy-content="ERC Ingolstadt"><img loading="lazy" decoding="async" src="https://www.haie.de/wp-content/themes/haie/dist/img/del-teams/ing.svg?version=2023-09" alt="Logo ERC Ingolstadt" width="48" height="48"></div>
</div>
</td>
<td>
ERC Ingolstadt
</td>
<td>
26
</td>
<td class="hidden-desktop">
19
</td>
<td class="hidden-desktop">
7
</td>
<td class="hidden-mobile">
16
</td>
<td class="hidden-mobile">
3
</td>
<td class="hidden-mobile">
0
</td>
<td class="hidden-mobile">
7
</td>
<td>
41
</td>
<td>
54
</td>
</tr>

Mein Problem sind in erster Linie die fehlenden Tags und der quasi immer gleiche Codeblock. Muss dann bei der Regex tatsächlich etliche Male das <td></td> eingefügt werden?

passibe

Würde mir das Leben nicht schwer machen und das von der Sportschau beziehen, die labeln die Elemente mit der entsprechenden class und der Bereich ist im Quellcode sogar entsprechend eingegrenzt, dass man sich easy mit preprocess den relevanten Teil der Seite vorab rausfiltern kann.

Mal als Beispiel:
defmod eishockey_test HTTPMOD https://www.sportschau.de/live-und-ergebnisse/eishockey/deutschland-del/tabelle
attr eishockey_test preProcessRegex <!--start module standing-->(.*)<!--end module standing-->
attr eishockey_test reading01Name team
attr eishockey_test reading01RegOpt g
attr eishockey_test reading01Regex <td class="team-shortname team-shortname-"><a href=".*?">(.*?)<\/a>
attr eishockey_test reading02Name spiele
attr eishockey_test reading02RegOpt g
attr eishockey_test reading02Regex <td class="standing-games_played">(\d+)
Habe jetzt nicht alles implementiert, der Rest ist nur noch Fleißarbeit, das kannst du dir selbst zusammenstellen.
Bitte Tools wie regex101.com und ChatGPT o.ä. nutzen. Hab dir den relevanten Teil des Quellcodes, weil ich ihn sowieso in der Zwischenablage hatte, mal angehängt. Den kannst du as-is in regex101.com einfügen und die entsprechenden regexes erstellen.

Natürlich im Browser auch Rechtsklick->Element untersuchen nicht vergessen.

(Vermutlich kannst du sogar einfach den ganzen Quellcode in ChatGPT kopieren, ihm sagen, welche Elemente du alle haben willst und das erstellt dir sämtliche Regexes ...)

passibe

Zitat von: passibe am 07 Dezember 2025, 23:49:18(Vermutlich kannst du sogar einfach den ganzen Quellcode in ChatGPT kopieren, ihm sagen, welche Elemente du alle haben willst und das erstellt dir sämtliche Regexes ...)
War neugierig, ob das klappt. Und ja, es klappt tatsächlich:

Prompt:
Kannst du das für mich erstellen? Habe in einem Forum gefragt und folgende Antwort bekommen:

Würde mir das Leben nicht schwer machen und das von der Sportschau beziehen, die labeln die Elemente mit der entsprechenden class und der Bereich ist im Quellcode sogar entsprechend eingegrenzt, dass man sich easy mit preprocess den relevanten Teil der Seite vorab rausfiltern kann.

Mal als Beispiel:
```
defmod eishockey_test HTTPMOD https://www.sportschau.de/live-und-ergebnisse/eishockey/deutschland-del/tabelle
attr eishockey_test preProcessRegex <!--start module standing-->(.*)<!--end module standing-->
attr eishockey_test reading01Name team
attr eishockey_test reading01RegOpt g
attr eishockey_test reading01Regex <td class="team-shortname team-shortname-"><a href=".*?">(.*?)<\/a>
attr eishockey_test reading02Name spiele
attr eishockey_test reading02RegOpt g
attr eishockey_test reading02Regex <td class="standing-games_played">(\d+)
```
Habe jetzt nicht alles implementiert, der Rest ist nur noch Fleißarbeit, das kannst du dir selbst zusammenstellen.
Bitte Tools wie regex101.com und ChatGPT o.ä. nutzen. Hab dir den relevanten Teil des Quellcodes, weil ich ihn sowieso in der Zwischenablage hatte, mal angehängt. Den kannst du as-is in regex101.com einfügen und die entsprechenden regexes erstellen.

Natürlich im Browser auch Rechtsklick->Element untersuchen nicht vergessen.

(Vermutlich kannst du sogar einfach den ganzen Quellcode in ChatGPT kopieren, ihm sagen, welche Elemente du alle haben willst und das erstellt dir sämtliche Regexes ...)

---

Hier noch der Code aus dem Anhang:
[...]

Antwort:
Alles klar — ich baue dir das **fertige FHEM‐HTTPMOD-Modul** daraus, sodass du folgende Werte bekommst:

| Wert     | Spalte              |
| -------- | ------------------- |
| rank     | Platz               |
| team     | Team-Kurzname       |
| games    | Spiele              |
| win_reg  | Siege regulär       |
| win_ot   | Siege OT            |
| win_pen  | Siege Penalty       |
| lost_reg | Niederlagen regulär |
| lost_ot  | Niederlagen OT      |
| lost_pen | Niederlagen Penalty |
| goals    | Tore z.B. 91:50     |
| diff     | Tor-Differenz       |
| points   | Punkte              |

---

### **➡ FERTIGER HTTPMOD-CODE FÜR FHEM**

> Du kannst ihn *so wie er ist* in FHEM einfügen
> (nur `defmod NAME` ggf. anpassen)

```
defmod eishockey_del HTTPMOD https://www.sportschau.de/live-und-ergebnisse/eishockey/deutschland-del/tabelle 300
attr eishockey_del preProcessRegex <!--start module standing-->(.*)<!--end module standing-->

attr eishockey_del reading01Name rank
attr eishockey_del reading01RegOpt g
attr eishockey_del reading01Regex <td class="standing-rank">(\d+)

attr eishockey_del reading02Name team
attr eishockey_del reading02RegOpt g
attr eishockey_del reading02Regex <td class="team-shortname team-shortname-"><a href=".*?">(.*?)<\/a>

attr eishockey_del reading03Name games
attr eishockey_del reading03RegOpt g
attr eishockey_del reading03Regex <td class="standing-games_played">(\d+)

attr eishockey_del reading04Name win_reg
attr eishockey_del reading04RegOpt g
attr eishockey_del reading04Regex <td class="standing-win-regular">(\d+)

attr eishockey_del reading05Name win_ot
attr eishockey_del reading05RegOpt g
attr eishockey_del reading05Regex <td class="standing-win-on-extra-time">(\d+)

attr eishockey_del reading06Name win_pen
attr eishockey_del reading06RegOpt g
attr eishockey_del reading06Regex <td class="standing-win-on-penalty">(\d+)

attr eishockey_del reading07Name lost_reg
attr eishockey_del reading07RegOpt g
attr eishockey_del reading07Regex <td class="standing-lost-regular">(\d+)

attr eishockey_del reading08Name lost_ot
attr eishockey_del reading08RegOpt g
attr eishockey_del reading08Regex <td class="standing-lost-on-extra-time">(\d+)

attr eishockey_del reading09Name lost_pen
attr eishockey_del reading09RegOpt g
attr eishockey_del reading09Regex <td class="standing-lost-on-penalty">(\d+)

attr eishockey_del reading10Name goals
attr eishockey_del reading10RegOpt g
attr eishockey_del reading10Regex <td class="standing-goaldiff">(\d+:\d+)

attr eishockey_del reading11Name diff
attr eishockey_del reading11RegOpt g
attr eishockey_del reading11Regex <td class="standing-difference">(-?\d+)

attr eishockey_del reading12Name points
attr eishockey_del reading12RegOpt g
attr eishockey_del reading12Regex <td class="standing-points">(\d+)
```

---

### Ergebnis

Du bekommst **14 Werte pro Reading-Gruppe** — also `rank_1`, `rank_2`, etc.
Perfekt für:

* Telegram Ausgabe
* DOIF Tabellen
* SVG Display
* MQTT Weitergabe

---

Wenn du möchtest, kann ich dir **eine formattierte Telegram-Tabelle**, **HTML-Tabelle**, **SVG-Visualisierung** oder **MQTT-JSON Export** daraus generieren.

➡ Sag einfach, **wie du die Ergebnisse später anzeigen möchtest** 👍😊

Marko1976

Genau das ist was ich seit Jahren mache. Jedes Jahr eine einfache Quelle suche und alles anpassen.
Doch genau davon möchte ich eigentlich weg.
Ich möchte gerne eine Quelle, die konstant bleibt und nicht ständig url und/oder Quellcode ändert.
Und da ist mir die Homepage der Haie halt aufgefallen, da diese jetzt schon im 3. Jahr nicht geändert wurde.

passibe

Naja, wer sagt dir, dass sie sich nicht im vierten Jahr ändert?

Du hast hier dank ChatGPT ein halbwegs fertiges Modul, ich würde das jetzt einfach nehmen anstatt noch mehr Zeit und Aufwand zu investieren. (Und vielleicht hat sich die Seite der Sportschau in den letzten 3 Jahren ja ebenfalls nicht geändert?)

Marko1976

Leider konnte ich keine Seite finden die über mehrere Jahre nichts geändert hat außer eben der der Haie. Hab es ja wie gesagt Jahr für Jahr vergleichen und angepasst und jedes Jahr nach einer geeigneten Seite gesucht.
Bin aber gerade dabei das ganze auszuprobieren - auch mal mit verschiedenen Webseiten um den Umgang mit Chatgpt zu lernen - ist bisher nicht mein Medium gewesen.

Mal sehen wie weit ich komme  :D

Marko1976

Ich habe das Device jetzt soweit das es mir praktisch für alle gewünschten Spalten etwas ausgibt. Darunter auch "Siege", "Siege in Overtime" und "Siege im Shootout", sowie das Gegenstück für die Niederlagen. Ich würde aber gerne Siege und Niederlagen jeweils als Gesamtwert angeben.

Normalerweise würde ich das per UserReading einfach addieren. Da das Device die Werte für jedes Reading automatisch pro Mannschaft durchnummeriert stellt sich mir die Frage muss ich das dann für jede Mennschaft einzeln machen und 28 Einträge (14 Siege / 14 Niederlagen) bei den UserReadings erstellen oder gibt es da auch eine "Abkürzung" für die es automatisiert?