ubuntuusers.de

Json von www.strassen.gr.ch in Python benutzen

Status: Ungelöst | Ubuntu-Version: Ubuntu 24.10 (Oracular Oriole)
Antworten |

holger56779

Anmeldungsdatum:
14. Februar 2018

Beiträge: 46

Guten Abend zusammen,

für mein Hobby!!! am Abend

Ich möchte gerne in Python die Json Daten aus der Karte von https://www.strassen.gr.ch benutzen,aber ich finde den Fehler nicht. Die json Daten sind die original Werte direkt von der website

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import json

# some JSON:
x = """[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Abzw. Fuorns und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n16.12.24 15:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 18:17\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Susch.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nReschenstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Kajetansbr&#xFC;cke und Nauders.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nWegen baulicher Massnahmen. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n01.10.24 08:06\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]"""

# parse x:
y = json.loads(str(x))

# the result is a Python dictionary:
print(y)

Die ausgegebene Fehlermeldung ist

1
2
3
4
5
6
7
8
9
Traceback (most recent call last):
  File "./prog.py", line 7, in <module>
  File "/usr/lib/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.8/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 74 (char 73)

Über Tipps, was ich machen muss damit es geht, freue ich mich. Danke

#Ich will damit künftig auf dem Raspberry Pi eine LCD Ausgabe machen

shiro

Anmeldungsdatum:
20. Juli 2020

Beiträge: 1214

Über Tipps, was ich machen muss damit es geht, freue ich mich.

Versuche mal dein Tüddel-Escape zu doppeln. also

# statt
x = """[{"MsgTim":"2024-12-16","MsgHtml":"<div class=\"msg-tst\">"}]"""

# besser
x = """[{"MsgTim":"2024-12-16","MsgHtml":"<div class=\\"msg-tst\\">"}]"""

Mylin

Avatar von Mylin

Anmeldungsdatum:
23. Juli 2024

Beiträge: 230

Doppelgetüddelt und ent- \r\n -t

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import json

# some JSON:
x = """[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Lukmanierstrasse:</div><div class=\\"state\\">Schneebedeckt zwischen Abzw. Fuorns und Campra (TI).</div><div class=\\"msg-time\\">16.12.24 15:59</div></div>","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Albulastrasse:</div><div class=\\"state\\">Wintersperre zwischen Berg&#xFC;n und La Punt.</div><div class=\\"msg-time\\">15.12.24 19:20</div></div>","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Autoverlad Vereinatunnel:</div><div class=\\"state\\">Offen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.</div><div class=\\"msg-time\\">15.12.24 18:17</div></div>","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Forcola-di-Livigno-Strasse:</div><div class=\\"state\\">Wintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.</div><div class=\\"msg-time\\">29.11.24 23:59</div></div>","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Spl&#xFC;genpass-Strasse:</div><div class=\\"state\\">Wintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.</div><div class=\\"msg-time\\">22.11.24 12:33</div></div>","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Fl&#xFC;elastrasse:</div><div class=\\"state\\">Schneebedeckt zwischen Davos Dorf und Susch.</div><div class=\\"msg-time\\">20.11.24 04:09</div></div>","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Oberalpstrasse:</div><div class=\\"state\\">Wintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.</div><div class=\\"msg-time\\">18.11.24 12:25</div></div>","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Umbrailstrasse:</div><div class=\\"state\\">Wintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.</div><div class=\\"msg-time\\">18.11.24 11:56</div></div>","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Brienzerstrasse:</div><div class=\\"state\\">Gesperrt zwischen Brienz und Belfortbr&#xFC;cke.</div><div class=\\"additional-info\\"><div class=\\"cause-measure\\">Aus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.</div><div class=\\"hint\\"><p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p></div><div class=\\"next-information\\">N&#xE4;chste Information: 31.03.25 13:00</div></div><div class=\\"msg-time\\">17.11.24 16:53</div></div>","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Italienische Strasse:</div><div class=\\"state\\">Wintersperre zwischen Hinterrhein und San Bernardino.</div><div class=\\"msg-time\\">15.11.24 14:41</div></div>","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Brienzerstrasse:</div><div class=\\"state\\">Gesperrt zwischen Lantsch/Lenz und Brienz.</div><div class=\\"additional-info\\"><div class=\\"cause-measure\\">Aus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.</div><div class=\\"hint\\"><p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p></div></div><div class=\\"msg-time\\">12.11.24 12:49</div></div>","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\\"msg-roadcondition\\"><div class=\\"road\\">Reschenstrasse:</div><div class=\\"state\\">Gesperrt zwischen Kajetansbr&#xFC;cke und Nauders.</div><div class=\\"additional-info\\"><div class=\\"cause-measure\\">Wegen baulicher Massnahmen. Umleitung signalisiert.</div><div class=\\"hint\\"><p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p></div></div><div class=\\"msg-time\\">01.10.24 08:06</div></div>","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\\"msg-roadevent\\"><div class=\\"road\\">Italienische Strasse:</div><div class=\\"state\\">Information zu Abschnitt Lostallo bis AS Roveredo.</div><div class=\\"additional-info\\"><div class=\\"cause-measure\\">Aus Sicherheitsgr&#xFC;nden. Keine Umleitung.</div><div class=\\"hint\\"><p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p></div></div><div class=\\"msg-time\\">09.09.24 09:31</div></div>","IconFile":"~/images/states/info.svg"}]"""

# parse x:
y = json.loads(str(x))

# the result is a Python dictionary:
print(y)

sieht das eigentlich ganz nett aus.

1
2
3
sh-5.2$ /bin/python3 /home/mario/Scripte/Test.py
[{'MessageTime': '2024-12-16T15:59:36.4333333', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Lukmanierstrasse:</div><div class="state">Schneebedeckt zwischen Abzw. Fuorns und Campra (TI).</div><div class="msg-time">16.12.24 15:59</div></div>', 'IconFile': '~/images/states/schneebedeckt.svg'}, {'MessageTime': '2024-12-15T19:20:27.3066667', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Albulastrasse:</div><div class="state">Wintersperre zwischen Berg&#xFC;n und La Punt.</div><div class="msg-time">15.12.24 19:20</div></div>', 'IconFile': '~/images/states/wintersperre.svg'}, {'MessageTime': '2024-12-15T18:17:34.1866667', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Autoverlad Vereinatunnel:</div><div class="state">Offen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.</div><div class="msg-time">15.12.24 18:17</div></div>', 'IconFile': '~/images/states/vereina_normal.svg'}, {'MessageTime': '2024-11-29T23:59:09.49', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Forcola-di-Livigno-Strasse:</div><div class="state">Wintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.</div><div class="msg-time">29.11.24 23:59</div></div>', 'IconFile': '~/images/states/wintersperre.svg'}, {'MessageTime': '2024-11-22T12:33:25.33', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Spl&#xFC;genpass-Strasse:</div><div class="state">Wintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.</div><div class="msg-time">22.11.24 12:33</div></div>', 'IconFile': '~/images/states/wintersperre.svg'}, {'MessageTime': '2024-11-20T04:09:06.8733333', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Fl&#xFC;elastrasse:</div><div class="state">Schneebedeckt zwischen Davos Dorf und Susch.</div><div class="msg-time">20.11.24 04:09</div></div>', 'IconFile': '~/images/states/schneebedeckt.svg'}, {'MessageTime': '2024-11-18T12:25:15.5833333', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Oberalpstrasse:</div><div class="state">Wintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.</div><div class="msg-time">18.11.24 12:25</div></div>', 'IconFile': '~/images/states/wintersperre.svg'}, {'MessageTime': '2024-11-18T11:56:22.5266667', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Umbrailstrasse:</div><div class="state">Wintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.</div><div class="msg-time">18.11.24 11:56</div></div>', 'IconFile': '~/images/states/wintersperre.svg'}, {'MessageTime': '2024-11-17T16:53:01.1633333', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Brienzerstrasse:</div><div class="state">Gesperrt zwischen Brienz und Belfortbr&#xFC;cke.</div><div class="additional-info"><div class="cause-measure">Aus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.</div><div class="hint"><p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p></div><div class="next-information">N&#xE4;chste Information: 31.03.25 13:00</div></div><div class="msg-time">17.11.24 16:53</div></div>', 'IconFile': '~/images/states/gesperrt.svg'}, {'MessageTime': '2024-11-15T14:41:41.0866667', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Italienische Strasse:</div><div class="state">Wintersperre zwischen Hinterrhein und San Bernardino.</div><div class="msg-time">15.11.24 14:41</div></div>', 'IconFile': '~/images/states/wintersperre.svg'}, {'MessageTime': '2024-11-12T12:49:30.6866667', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Brienzerstrasse:</div><div class="state">Gesperrt zwischen Lantsch/Lenz und Brienz.</div><div class="additional-info"><div class="cause-measure">Aus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.</div><div class="hint"><p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p></div></div><div class="msg-time">12.11.24 12:49</div></div>', 'IconFile': '~/images/states/gesperrt.svg'}, {'MessageTime': '2024-10-01T08:06:21.6433333', 'MessageHtml': '<div class="msg-roadcondition"><div class="road">Reschenstrasse:</div><div class="state">Gesperrt zwischen Kajetansbr&#xFC;cke und Nauders.</div><div class="additional-info"><div class="cause-measure">Wegen baulicher Massnahmen. Umleitung signalisiert.</div><div class="hint"><p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p></div></div><div class="msg-time">01.10.24 08:06</div></div>', 'IconFile': '~/images/states/gesperrt.svg'}, {'MessageTime': '2024-09-09T09:31:09.7733333', 'MessageHtml': '<div class="msg-roadevent"><div class="road">Italienische Strasse:</div><div class="state">Information zu Abschnitt Lostallo bis AS Roveredo.</div><div class="additional-info"><div class="cause-measure">Aus Sicherheitsgr&#xFC;nden. Keine Umleitung.</div><div class="hint"><p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p></div></div><div class="msg-time">09.09.24 09:31</div></div>', 'IconFile': '~/images/states/info.svg'}]
sh-5.2$ 

holger56779

(Themenstarter)

Anmeldungsdatum:
14. Februar 2018

Beiträge: 46

Vielen herzlichen Dank für die gewinnbringenden Antworten. Mein Stand ist jetzt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import json
import re

# some JSON:
x = '[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Abzw. Fuorns und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n16.12.24 15:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 18:17\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Susch.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nReschenstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Kajetansbr&#xFC;cke und Nauders.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nWegen baulicher Massnahmen. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n01.10.24 08:06\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]'
#https://stackoverflow.com/questions/9662346/python-code-to-remove-html-tags-from-a-string
x=re.sub(re.compile('\r'), '', x)
x=re.sub(re.compile('\n'), '', x)
x=re.sub(re.compile('<.*?>'), '', x)
# parse x:
y = json.loads(str(x))

# the result is a Python dictionary:
print(y)

und

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import json
import re

# some JSON:
x = '[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Abzw. Fuorns und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n16.12.24 15:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 18:17\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Susch.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nReschenstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Kajetansbr&#xFC;cke und Nauders.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nWegen baulicher Massnahmen. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n01.10.24 08:06\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]'
#https://stackoverflow.com/questions/9662346/python-code-to-remove-html-tags-from-a-string
x=re.sub(re.compile('\r'), '', x)
x=re.sub(re.compile('\n'), '', x)
x=re.sub(re.compile('<.*?>'), '', x)
# parse x:
y = json.loads(str(x))

# the result is a Python dictionary:
print(y[1]["MessageTime"])
print(y[1]["MessageHtml"])
print(y[1]["IconFile"])

jetzt kommt als nächster Schritt ein Http request dazu

Mylin

Avatar von Mylin

Anmeldungsdatum:
23. Juli 2024

Beiträge: 230

Aus

1
2
3
x=re.sub(re.compile('\r'), '', x)
x=re.sub(re.compile('\n'), '', x)
x=re.sub(re.compile('<.*?>'), '', x)

kannst du

1
x = re.sub(r'[\r\n]|<.*?>', '', x)

machen.

holger56779

(Themenstarter)

Anmeldungsdatum:
14. Februar 2018

Beiträge: 46

Gute Morgen zusammen,

an den Weihnachtsfeiertagen habe ich weiter programmiert, alles Hobby

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#strassen Graubünden
import json
import re

# some JSON:
x = """[{"MessageTime":"2024-12-27T13:55:25.6533333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga Wartezeit 60 Minuten. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n27.12.24 13:55\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-12-27T09:13:12.7666667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Tschuggen und Susch.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Offen ab 16:00.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 27.12.24 16:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n27.12.24 09:13\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-12-24T14:08:18.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Disentis//Must&#xE9;r und Tschamut.\r\n</div>\r\n<div class=\"msg-time\">\r\n24.12.24 14:08\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-23T16:22:57.4766667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Disentis/Must&#xE9;r und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n23.12.24 16:22\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-22T07:23:12.4566667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSamnaunerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Vinadi und Samnaun.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.12.24 07:23\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Tschuggen.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]"""

x=re.sub(re.compile('\r'), '', x)
x=re.sub(re.compile('\n'), '', x)
x=re.sub(re.compile('<.*?>'), '', x)
# parse x:
y = json.loads(str(x))
# print(y)
# the result is a Python dictionary:
merken = []


# Auswertung Strassen zu einem bestimmten Zustand 
def gibStrassenZustand(zustand:str):
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find(zustand)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken

#Ausprobieren zustand="schneebedeckt"
#zustand="wintersperre" oder "gesperrt" "info"
print(gibStrassenZustand("schneebedeckt"))
print(gibStrassenZustand("wintersperre"))
print(gibStrassenZustand("gesperrt"))
print(gibStrassenZustand("info"))




#Anzahl Meldungen
def zaehleStrassenZustand(zustand:str):
  return len(gibStrassenZustand(zustand))

def freieZustandStrasse(zustand:str):
  if zaehleStrassenZustand(zustand) < 1:
    return True
  else:
    return False


# print(len(merken))
print(zaehleStrassenZustand("schneebedeckt"))
print(zaehleStrassenZustand("wintersperre"))
print(zaehleStrassenZustand("gesperrt"))
print(zaehleStrassenZustand("info"))


# Auswertung Strassen zu einem bestimmten Dorf oder Stadt
def gibStrassenOrt(ort:str):
  merken.clear()
  for zeile in y:
    if(zeile["MessageHtml"].find(ort)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken

#Anzahl Meldungen
def zaehleStrassenOrt(ort:str):
  return len(gibStrassenOrt(ort))

def freieZufahrtOrt(ort:str):
  if zaehleStrassenOrt(ort) < 1:
    return True
  else:
    return False
    
print(freieZufahrtOrt("Davos"))
print(freieZufahrtOrt("Klosters"))

#ort="Davos"
# ort="Bergün" "Hinterrhein"
print(gibStrassenOrt("Davos"))
print(gibStrassenOrt("Brienz"))
print(gibStrassenOrt("Hinterrhein"))

print(zaehleStrassenOrt("Davos"))
print(zaehleStrassenOrt("Brienz"))
print(zaehleStrassenOrt("Hinterrhein"))



def gibStrassenName(name:str):
  merken.clear()
  for zeile in y:
    if(zeile["MessageHtml"].find(name)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken

#Anzahl Meldungen
def zaehleStrassenName(name:str):
  return len(gibStrassenName(name))


def freieStrasse(name:str):
  if zaehleStrassenName(name) < 1:
    return True
  else:
    return False

#strassenname="Flüelastrasse"
#strassenname="Oberalpstrasse" "Brienzerstrasse" "Albulastrasse"
print(gibStrassenName("Flüelastrasse"))
print(gibStrassenName("Oberalpstrasse"))
print(gibStrassenName("Albulastrasse"))

print(zaehleStrassenName("Flüelastrasse"))
print(zaehleStrassenName("Oberalpstrasse"))
print(zaehleStrassenName("Albulastrasse"))


def gibStrassenNamen(strassenname:str):
  merken.clear()
  for zeile in y:
    if(zeile["MessageHtml"].find(strassenname)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken
#Anzahl Meldungen
def zaehleStrassenNamen(strassenname:str):
  return len(gibStrassenOrt(strassenname)
#strassenname="Flüelastrasse"
#strassenname="Oberalpstrasse" "Brienzerstrasse" "Albulastrasse"
print(gibStrassenOrt("Flüelastrasse"))
print(gibStrassenOrt("Oberalpstrasse"))
print(gibStrassenOrt("Albulastrasse"))

print(zaehleStrassenOrt("Flüelastrasse"))
print(zaehleStrassenOrt("Oberalpstrasse"))
print(zaehleStrassenOrt("Albulastrasse"))

#Autoverlad Vereinatunnel:Offen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.25.12.24 16:29
def IstVereinaTextOffen():
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find("vereina")>=0):
      if(zeile["MessageHtml"].find("Offen")>=0):
        print(zeile["MessageHtml"])
        return True
      else:
        return False
  
print(IstVereinaTextOffen())

def gibSelfrangaKomplett():
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find("vereina")>=0):
        start=zeile["MessageHtml"].find("Selfranga")
        ende=zeile["MessageHtml"].find("Sagliains", start+1)
        print(zeile["MessageHtml"])
        return zeile["MessageHtml"][start:ende]

def gibSelfranga():
        return gibSelfrangaKomplett()[10:]
print(gibSelfranga())

def ohneWartezeitSelfranga():
  if gibSelfranga().find("keine") >= 0:
    return True
  else:
    return False
    
print(ohneWartezeitSelfranga())


def gibSagliainsKomplett():
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find("vereina")>=0):
        start=zeile["MessageHtml"].find("Sagliains")
        ende=zeile["MessageHtml"].find(".", start+1)
        print(zeile["MessageHtml"])
        return zeile["MessageHtml"][start:ende]

def gibSagliains():
        return gibSagliainsKomplett()[10:]
print(gibSagliains())

def ohneWartezeitSagliains():
  if gibSagliains().find("keine") >= 0:
    return True
  else:
    return False
    
print(ohneWartezeitSagliains())


def ohneWartezeitVereina():
  return ohneWartezeitSelfranga() and ohneWartezeitSagliains()
  
print(ohneWartezeitVereina())

def sammelAlleUhrzeiten():
  merken.clear()
  for zeile in y:
        #print(str(zeile["MessageTime"]))
        merken.append(str(zeile["MessageTime"]))
  return merken
  
def neusteMeldungUhrzeit():
  zeiten = sammelAlleUhrzeiten()
  zeiten.sort(reverse=True)
  return zeiten.pop(0)
print(neusteMeldungUhrzeit())

def aeltesteMeldungUhrzeit():
  zeiten = sammelAlleUhrzeiten()
  zeiten.sort(reverse=False)
  return zeiten.pop(0)
print(aeltesteMeldungUhrzeit())



def gibNeusteMeldung():
  uhrzeit=neusteMeldungUhrzeit()
  for zeile in y:
    if(str(zeile["MessageTime"]).find(uhrzeit) >=0):    
        #print(str(zeile["MessageHtml"]))
        #print(str(zeile["MessageTime"]))
        return str(zeile["MessageHtml"])
        
print(gibNeusteMeldung())


def gibAeltesteMeldung():
  uhrzeit=aeltesteMeldungUhrzeit()
  for zeile in y:
    if(str(zeile["MessageTime"]).find(uhrzeit) >=0):    
        #print(str(zeile["MessageHtml"]))
        #print(str(zeile["MessageTime"]))
        return str(zeile["MessageHtml"])

print(gibAeltesteMeldung())

Ich möchte die Json Datei weiter ausquetschen. Gerne könnt Ihr Vorschläge und Ideen schreiben, mir macht es Spaß

holger56779

(Themenstarter)

Anmeldungsdatum:
14. Februar 2018

Beiträge: 46

Gute Morgen zusammen,

ein paar Methoden habe ich weiter programmiert, alles Hobby

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#weiter, siehe oben

#https://stackoverflow.com/questions/9662346/python-code-to-remove-html-tags-from-a-string
x=re.sub(re.compile('\r'), '', x)
x=re.sub(re.compile('\n'), '', x)
x=re.sub(re.compile('<.*?>'), '', x)
# parse x:
y = json.loads(str(x))
# print(y)
# the result is a Python dictionary:
merken = []


# Auswertung Strassen zu einem bestimmten Zustand 
def gibStrassenZustand(zustand:str):
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find(zustand)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken

#Ausprobieren zustand="schneebedeckt"
#zustand="wintersperre" oder "gesperrt" "info"
print(gibStrassenZustand("schneebedeckt"))
print(gibStrassenZustand("wintersperre"))
print(gibStrassenZustand("gesperrt"))
print(gibStrassenZustand("info"))




#Anzahl Meldungen
def zaehleStrassenZustand(zustand:str):
  return len(gibStrassenZustand(zustand))

def freieZustandStrasse(zustand:str):
  if zaehleStrassenZustand(zustand) < 1:
    return True
  else:
    return False


# print(len(merken))
print(zaehleStrassenZustand("schneebedeckt"))
print(zaehleStrassenZustand("wintersperre"))
print(zaehleStrassenZustand("gesperrt"))
print(zaehleStrassenZustand("info"))

def gibNurStrassennamenZustand(zustand:str):
  strassennamen = []
  text = gibStrassenZustand(zustand)
  for zeile in text:
    positionDoppelpunkt=zeile.find(":")
    strassennamen.append(str(zeile[0:positionDoppelpunkt]))
  return strassennamen

#Ausprobieren zustand="schneebedeckt"
#zustand="wintersperre" oder "gesperrt" "info"
print(gibNurStrassennamenZustand("schneebedeckt"))
print(gibNurStrassennamenZustand("wintersperre"))
print(gibNurStrassennamenZustand("gesperrt"))
print(gibNurStrassennamenZustand("info"))


# Auswertung Strassen zu einem bestimmten Dorf oder Stadt
def gibStrassenOrt(ort:str):
  merken.clear()
  for zeile in y:
    if(zeile["MessageHtml"].find(ort)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken
# Auswertung nur die Namen der Strassen zu einem bestimmten Dorf oder Stadt
def gibNurStrassennamenOrt(ort:str):
  strassennamen = []
  text = gibStrassenOrt(ort)
  for zeile in text:
    positionDoppelpunkt=zeile.find(":")
    strassennamen.append(str(zeile[0:positionDoppelpunkt]))
  return strassennamen

print(gibNurStrassennamenOrt("Davos"))
print(gibNurStrassennamenOrt("Brienz"))
print(gibNurStrassennamenOrt("Hinterrhein"))

#Anzahl Meldungen
def zaehleStrassenOrt(ort:str):
  return len(gibStrassenOrt(ort))

def freieZufahrtOrt(ort:str):
  if zaehleStrassenOrt(ort) < 1:
    return True
  else:
    return False
    
print(freieZufahrtOrt("Davos"))
print(freieZufahrtOrt("Klosters"))

#ort="Davos"
# ort="Bergün" "Hinterrhein"
print(gibStrassenOrt("Davos"))
print(gibStrassenOrt("Brienz"))
print(gibStrassenOrt("Hinterrhein"))

print(zaehleStrassenOrt("Davos"))
print(zaehleStrassenOrt("Brienz"))
print(zaehleStrassenOrt("Hinterrhein"))



def gibStrassenName(name:str):
  merken.clear()
  for zeile in y:
    if(zeile["MessageHtml"].find(name)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken

#Anzahl Meldungen
def zaehleStrassenName(name:str):
  return len(gibStrassenName(name))

#Welche Pässe kommen in den Meldungen vor
def sammelPassMeldungen():
  return gibStrassenName("pass")

#Wie viele Meldumgen gibt's mit Passen
def zaehlePassMeldungen():
  return len(sammelPassMeldungen())
  
print(sammelPassMeldungen())
print(zaehlePassMeldungen())

def freieStrasse(name:str):
  if zaehleStrassenName(name) < 1:
    return True
  else:
    return False
def allePassOffen():
  if zaehlePassMeldungen() < 1:
    return True
  else:
    return False

#Analysiere die Passe in Graubünden
print(sammelPassMeldungen())
print(zaehlePassMeldungen())

print(allePassOffen())

#strassenname="Flüelastrasse"
#strassenname="Oberalpstrasse" "Brienzerstrasse" "Albulastrasse"
print(gibStrassenName("Flüelastrasse"))
print(gibStrassenName("Oberalpstrasse"))
print(gibStrassenName("Albulastrasse"))

print(zaehleStrassenName("Flüelastrasse"))
print(zaehleStrassenName("Oberalpstrasse"))
print(zaehleStrassenName("Albulastrasse"))


def gibStrassenNamen(strassenname:str):
  merken.clear()
  for zeile in y:
    if(zeile["MessageHtml"].find(strassenname)>=0):
      merken.append(str(zeile["MessageHtml"]))
  return merken
#Anzahl Meldungen
def zaehleStrassenNamen(strassenname:str):
  return len(gibStrassenOrt(strassenname)
#strassenname="Flüelastrasse"
#strassenname="Oberalpstrasse" "Brienzerstrasse" "Albulastrasse"
print(gibStrassenOrt("Flüelastrasse"))
print(gibStrassenOrt("Oberalpstrasse"))
print(gibStrassenOrt("Albulastrasse"))

print(zaehleStrassenOrt("Flüelastrasse"))
print(zaehleStrassenOrt("Oberalpstrasse"))
print(zaehleStrassenOrt("Albulastrasse"))

#Autoverlad Vereinatunnel:Offen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.25.12.24 16:29
def IstVereinaTextOffen():
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find("vereina")>=0):
      if(zeile["MessageHtml"].find("Offen")>=0):
        print(zeile["MessageHtml"])
        return True
      else:
        return False
  
print(IstVereinaTextOffen())

def gibSelfrangaKomplett():
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find("vereina")>=0):
        start=zeile["MessageHtml"].find("Selfranga")
        ende=zeile["MessageHtml"].find("Sagliains", start+1)
        print(zeile["MessageHtml"])
        return zeile["MessageHtml"][start:ende]

def gibSelfranga():
        return gibSelfrangaKomplett()[10:]
print(gibSelfranga())

def ohneWartezeitSelfranga():
  if gibSelfranga().find("keine") >= 0:
    return True
  else:
    return False
    
print(ohneWartezeitSelfranga())


def gibSagliainsKomplett():
  merken.clear()
  for zeile in y:
    if(zeile["IconFile"].find("vereina")>=0):
        start=zeile["MessageHtml"].find("Sagliains")
        ende=zeile["MessageHtml"].find(".", start+1)
        print(zeile["MessageHtml"])
        return zeile["MessageHtml"][start:ende]

def gibSagliains():
        return gibSagliainsKomplett()[10:]
print(gibSagliains())

def ohneWartezeitSagliains():
  if gibSagliains().find("keine") >= 0:
    return True
  else:
    return False
    
print(ohneWartezeitSagliains())


def ohneWartezeitVereina():
  return ohneWartezeitSelfranga() and ohneWartezeitSagliains()
  
print(ohneWartezeitVereina())

def sammelAlleUhrzeiten():
  merken.clear()
  for zeile in y:
        #print(str(zeile["MessageTime"]))
        merken.append(str(zeile["MessageTime"]))
  return merken
  
def neusteMeldungUhrzeit():
  zeiten = sammelAlleUhrzeiten()
  zeiten.sort(reverse=True)
  return zeiten.pop(0)
print(neusteMeldungUhrzeit())

def aeltesteMeldungUhrzeit():
  zeiten = sammelAlleUhrzeiten()
  zeiten.sort(reverse=False)
  return zeiten.pop(0)
print(aeltesteMeldungUhrzeit())



def gibNeusteMeldung():
  uhrzeit=neusteMeldungUhrzeit()
  for zeile in y:
    if(str(zeile["MessageTime"]).find(uhrzeit) >=0):    
        #print(str(zeile["MessageHtml"]))
        #print(str(zeile["MessageTime"]))
        return str(zeile["MessageHtml"])
        
print(gibNeusteMeldung())


def gibAeltesteMeldung():
  uhrzeit=aeltesteMeldungUhrzeit()
  for zeile in y:
    if(str(zeile["MessageTime"]).find(uhrzeit) >=0):    
        #print(str(zeile["MessageHtml"]))
        #print(str(zeile["MessageTime"]))
        return str(zeile["MessageHtml"])

print(gibAeltesteMeldung())

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

@holger56779 Zum ersten Beitrag: Statt an den Daten etwas zu verändern hätte man einfach durch voranstellen eines R eine ”rohes” Zeichenketten literal daraus machen können, wo der \ keine besondere Bedeutung mehr hat.

x ist bereits eine Zeichenkette, da macht es keinen Sinn str() mit aufzurufen. Tatsächlich sind alle str()-Aufrufe in dem gezeigten Quelltext sinnfrei, weil es sich immer bereits um Zeichenketten handelt.

Für den weiteren Verlauf: Man sollte nicht auf dem JSON-Quelltext herumoperieren um Sachen aus bestimmten Werten aus dem JSON zu entfernen, sondern das nach dem Parsen des JSON gezielt nur auf den betroffenen Werten machen.

re.compile() ist überflüssig wenn man das Ergebnis davon dann doch nur ein einziges mal an re.sub() übergibt. Überhaupt ist es komisch re.sub() das zu übergeben, statt die sub()-Methode vom re.compile()-Ergebnis zu verwenden.

Zum weiteren Code: Der kommt nicht am Compiler vorbei, weil da eine schliessende Klammer fehlt.

Eingerückt wird per Konvention 4 Leerzeichen pro Ebene.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Nach dem Kommentar # the result is a Python dictionary: wird eine Liste definiert und an den nichtssagenden Namen merken gebunden, wobei diese Liste dann in Funktionen immer wieder mal geleert und dann als Ergebnis zurückgegeben wird. Das ist ganz übel eine globale Variable so zu benutzen als Rückgabewert für alle Funktionen. Das ist total undurchsichtig und fehleranfällig und es kann dann nie Funktionen geben die eine andere Funktion aufruft die diese globale Liste dann auch verwendet.

x und y sind gute Namen für Koordinatenwerte aber sicher nicht für eine Zeichenkette mit JSON-Quelltext oder gar eine komplexere Datenstruktur. Zudem sollte y keine globale Variable sein und in allen möglichen Funktionen einfach so magisch existieren. Das macht Code unübersichtlich und schwerer zu testen und damit fehleranfälliger. Funktionen (und Methoden) bekommen alles ausser Konstanten als Argument(e) übergeben.

zeile wird sehr oft als Name für eine Datenstruktur verwendet die eine Meldung repräsentiert, das ist also gar keine Zeile.

Dann gibt es an zwei Stellen text das gar nicht an *einen* Text gebunden wird, sondern an eine Liste mit Texten. Das ist verwirrend.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die main() heisst. Funktionen definieren und dann dazwischen Code verstreuen der die benutzt, ist unübersichtlich. Ausserdem sollte man ein Modul importieren können, ohne das da ein Hauptprogramm oder Teile davon ablaufen.

Das verteilen zwischen den Funktionen macht es beispielsweise schwerer zu sehen, dass sammelPassMeldungen() und zaehlePassMeldungen() zweimal aufgerufen wird.

if ist keine Funktion, das sollte man also auch nicht mit Klammern so schreiben als wäre es eine.

Die find()-Methode auf Zeichenketten sollte man nicht verwenden. Wenn man das Egrebnis nur auf -1 testet, dann wollte man eigentlich den in-Operator, falls man tatsächlich den Indexwert verwenden will, sollte man die index()-Methode verwenden. Denn -1 ist ja auch ein gültiger Index und da arbeitet man dann leicht mal mit falschen Werten weiter wenn man das nicht berücksichtigt, dass man diese -1 dann sowohl bei Indexzugriffen als auch bleim ”slicen” verwenden kann, aber in den meisten Fällen dabei dann kein sinnvolles Ergebnis bekommt.

In vielen Funktionen dort werden Listen per Schleife und append() aufgebaut, die man einfach als „list comprehension“ schreiben könnte.

Einen Vergleich bei einer Anzahl/Sequenzlänge als < 1 zu formulieren ist, äh, kreativ. An der Stelle will man ja eigentlich wissen ob der Wert gleich 0 ist, denn das ist ja die Einzige Anzahl/Länge die kleiner als 1 ist. Es gibt da ja keine Listen mit einem halben Element oder so.

Code nach dem Muster

1
2
3
4
    if bedingung:
        return True
    else:
        return False

ist ganz einfach nur return bool(bedingung) oder nur noch return bedingung wenn da schon ein Wahrheitswert als Ergebnis heraus kommt.

IstVereinaTextOffen(), gibSelfrangaKomplett(), und gibSagliainsKomplett() fehlt Code für den Fall, dass die Schleife ohne Suchtreffer durchlaufen wird. Ich nehme mal an das sollte eine Ausnahme auslösen wenn es für diese Abfragen kein Ergebnis gibt.

Um die neueste und älteste Uhrzeit zu ermitteln braucht man die Meldungen nicht aufwändig zu sortieren, das kann man mit den Funktionen min() und max() machen.

Das ermitteln der neuesten und ältesten Meldung ist auch noch mal eine Stufe umständlicher wenn erst alle Meldungen durchgeht um die neueste/älteste Zeit zu finden, und dann noch mal alle Meldungen durchgeht um die Meldung mit dieser Zeit zu finden.

gibStrassenOrt(), gibStrassenName(), und gibStrassenNamen() machen alle drei exakt das selbe. Das sollten keine unterschiedlichen Funktionen sein, wenn die genau das selbe machen.

Dementsprechend machen auch die dazugehörigen zaehle*-Funktionen das selbe und sollten nicht mehrfach existieren. Und daran hängen dann noch mal jeweils Funktionen die nach dem gleichen Muster die Länge des Ergebnisses auf 0 testen. Das sind alles unnötige Funktionen, wo man den jeweiligen Test oder die Abfrage der Länge einfach direkt an der Aufrufstelle machen würde.

Bei den Tests wäre der Code auch deutlich kompatker wenn man nicht für jeden Namen einen eigenen Aufruf schreiben würde, sondern eine Schleife über die Namen und dann für jeden Namen einen Aufruf der jeweiligen Funktion.

Nur den Strassennamen von Meldungen auszulesen steht auch zweimal im Code. Und beide male kombiniert mit der Suche der Meldungen.

Das mit den Wartezeiten bei Selfranga und Selfraina ist so komisch asymmetrisch gelöst. Einmal Text von Ortsname zu Ortsname und das andere mal von Ortsname zum Punkt, wo doch aber beide Angaben vom Ortsnamen zu einem Punkt gehen würden, man also den gleichen Code mit dem Ortsnamen der einen interessiert als Parameter verwenden könnte.

Zwischenstand:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#!/usr/bin/env python3
import json
import re

JSON = R"""[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Abzw. Fuorns und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n16.12.24 15:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 18:17\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Susch.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nReschenstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Kajetansbr&#xFC;cke und Nauders.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nWegen baulicher Massnahmen. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n01.10.24 08:06\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]"""


def dursuche_meldungen(meldungen, schluessel, suchbegriff):
    return [
        meldung["MessageHtml"]
        for meldung in meldungen
        if suchbegriff in meldung[schluessel]
    ]


def durchsuche_texte(meldungen, suchbegriff):
    return dursuche_meldungen(meldungen, "MessageHtml", suchbegriff)


def durchsuche_strassenzustand(meldungen, suchbegriff):
    return dursuche_meldungen(meldungen, "IconFile", suchbegriff)


def sammel_pass_meldungen(meldungen):
    return durchsuche_texte(meldungen, "pass")


def hole_vereina_text(meldungen):
    texte = durchsuche_strassenzustand(meldungen, "vereina")
    if len(texte) != 1:
        raise ValueError(f"{len(texte)} Meldungen für Vereina")
    return texte[0]


def parse_wartezeit_text(text, ort):
    start = text.index(ort)
    ende = text.index(".", start + 1)
    return text[start + len(ort) + 1 : ende]


def hole_uhrzeiten(meldungen):
    return [meldung["MessageTime"] for meldung in meldungen]


def _hole_meldung_nach_zeit(function, meldungen):
    meldung = function(meldungen, key=lambda meldung: meldung["MessageTime"])
    return meldung["MessageHtml"]


def hole_neueste_meldung(meldungen):
    return _hole_meldung_nach_zeit(max, meldungen)


def hole_aelteste_meldung(meldungen):
    return _hole_meldung_nach_zeit(min, meldungen)


def main():
    #
    # FIXME Die Textverarbeitung für HTML-Teile sollte nicht auf dem
    #       JSON-Quelltext stattfinden, sondern nur auf den HTML-Quelltexten.
    #
    alle_meldungen = json.loads(re.sub(r"\\r|\\n|<.*?>", "", JSON))

    for zustand in ["schneebedeckt", "wintersperre", "gesperrt", "info"]:
        texte = durchsuche_strassenzustand(alle_meldungen, zustand)
        print(f"Zustand {zustand!r} ({len(texte)}): {texte}")

    for kategorie, namen in [
        ("Ort", ["Davos", "Brienz", "Hinterrhein", "Klosters"]),
        ("Strasse", ["Flüelastrasse", "Oberalpstrasse", "Albulastrasse"]),
    ]:
        for name in namen:
            texte = durchsuche_texte(alle_meldungen, name)
            print(f"{kategorie}: {name} ({len(texte)}) {texte}")

    texte = sammel_pass_meldungen(alle_meldungen)
    print(f"Passmeldungen: ({len(texte)}) {texte}")

    text = hole_vereina_text(alle_meldungen)
    print("ist Verine offen?", "Offen" in text)
    endpunkte = ["Selfranga", "Sagliains"]
    wartezeit_texte = [
        parse_wartezeit_text(text, endpunkt) for endpunkt in endpunkte
    ]
    for endpunkt, wartezeit_text in zip(endpunkte, wartezeit_texte):
        print(f"{endpunkt}: {wartezeit_text} ({'keine' in wartezeit_text})")

    hat_vereina_wartezeit = all(
        "keine" in wartezeit_text for wartezeit_text in wartezeit_texte
    )
    print(f"Keine Wartezeit Vereina: {hat_vereina_wartezeit}")

    uhrzeiten = hole_uhrzeiten(alle_meldungen)
    print(f"Zeitraum {min(uhrzeiten)} bis {max(uhrzeiten)}")

    print(hole_neueste_meldung(alle_meldungen))
    print(hole_aelteste_meldung(alle_meldungen))


if __name__ == "__main__":
    main()

Wörterbücher die immer den gleichen Satz an Zeichenketten als Schlüssel haben, sind eigentlich Objekte. Das JSON sollte also in eine Sequenz von Objekten überführt werden. Da könnte man dann auch mehr als die drei Werte pro Meldung haben, in dem man beispielsweise den Strassennamen vom Rest des Meldungstextes trennt. Man hätte auch nicht mehr einen Schlüssel der "MessageHtml" heisst, hinter dem aber gar kein HTML mehr steht, sondern nur noch Text.

Auch sollten Such- und Filtefunktionen die Meldungen selber als Ergebnis haben, und nicht nur die Texte. Dann hat man a) mehr Information als nur den Text, und ist b) flexibler in der Weiterverabeitung. Man könnte dann beispielsweise suchen auf Suchergebnissen machen.

Das HTML sollte man nicht mit Textoperationen verarbeiten. HTML ist ja kein unstruktirierter Text. Das würde auch das Problem von HTML-Entities lösen, denn ""Spl&#xFC;genpass-Strasse" ist ja nicht wirklich schön und man möchte das ja in einer Suche nicht so schreiben müssen. Zumal sich das an der Datenquelle jederzeit ändern kann welche Zeichen die da als HTML-Entity und welche einfach als Zeichen ausliefern. Das Ergebnis enthält auch jetzt schon normale Umlaute.

holger56779

(Themenstarter)

Anmeldungsdatum:
14. Februar 2018

Beiträge: 46

Guten Morgen @Marc_BlackJack_Rintsch

großes Danke für Deine Verbesserung. Wie Du leicht erkennen konntest bin ich ein Anfänger. Das mit dem HTML in Json Datei ist eben in der Quelle, www.strassen.gr.ch ⇒ Json Datei zur Landkarte anklicken, so vorgegeben. (Um kein Ärger mit dem GR Straßenamt zu bekommen, habe den direkten Hyperlink hier nicht veröffentlicht.)

Für mich (privat) werden die neusten Daten über ein http request geholt, daher frage ich mich, ob das mit dem

1
JSON = R"""....

in einem http request noch funktioniert.

den neuen Code muss ich verstehen, dafür brauch ich erstmal Zeit.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

@holger56779: Das mit dem HTML im JSON ist mir schon klar, aber der Code arbeitet ja auf dem JSON-Quelltext als wäre es komplett HTML-Quelltext bevor das JSON überhaupt geparst wird. Dabei enthält ja immer nur ein Wert von dreien in jeder Meldung tatsächlich HTML-Quelltext. Und das im JSON-Quelltext auch noch als Zeichenkette in JSON kodiert. Die Verarbeitungsreihenfolge müsste also statt „HTML-Tags aus JSON-Quelltext entfernen → JSON-Quelltext parsen“ korrekter „JSON-Quelltext parsen → aus jeder Meldung beim "MessageHtml"-Wert die HTML-Tags entfernen“ sein. Also statt:

1
    alle_meldungen = json.loads(re.sub(r"\\r|\\n|<.*?>", "", JSON))

dann

1
2
3
4
5
6
7
8
    alle_meldungen = [
        {
            "zeit": meldungs_daten["MessageTime"],
            "text": re.sub(r"\r|\n|<.*?>", "", meldungs_daten["MessageHtml"]),
            "icon_dateiname": meldungs_daten["IconFile"],
        }
        for meldungs_daten in json.loads(JSON)
    ]

Man sieht hier auch schon eine Änderung am regulären Ausdruck: man hat jetzt tatsächliche Wagenrücklauf- und Zeilenende-Zeichen und nicht mehr die Kodierung als JSON von diesen Zeichen. Und man kann die Schlüssel passend umbenennen, also beispielsweise hier "text" für den Text ohne die HTML-Tags, statt das irreführenderweise immer noch unter dem Namen MessageHtml zu haben.

Wenn man schon dabei ist, kann man auch die anderen beiden Felder verarbeiten. Den Zeitstempel zu einem datetime.datetime-Objekt und aus dem Icon-Dateinamen kann man den Dateinamen ohne Endung als "zustand" heraus holen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    alle_meldungen = [
        {
            #
            # TODO Wörterbuch mit festen Satz an Schlüsseln → Klasse.
            #
            "zeit": DateTime.fromisoformat(
                #
                # Die Zeitangaben sind grundsätzlich in einem ISO 8601-Format
                # mit gebrochenen Sekunden.  Die sind aber teilweise mit mehr
                # oder weniger als sechs Dezimalstellen angegeben, darum wird
                # hier sowohl auf die volle Stellenanzahl mit 0en aufgefüllt,
                # als auch sichergestellt, dass die Maximallänge nicht
                # überschritten wird.
                #
                meldungs_daten["MessageTime"].ljust(26, "0")[:26]
            ),
            #
            # TODO Das HTML mit einem HTML-Parser verarbeiten und in einzelne
            #      Teile (Strasse, Text, Zeitstempel) aufteilen.  Zeitstempel
            #      gegen den "MesssageTime"-Wert prüfen und ggf. Warnung oder
            #      Fehler.
            #
            "text": re.sub(r"\r|\n|<.*?>", "", meldungs_daten["MessageHtml"]),
            #
            # TODO Gegen bekannte Werte prüfen und warnen falls neue Werte
            #      auftauchen, die im Programm eventuell besonders
            #      berücksichtigt werden sollten.
            #
            "zustand": PosixPath(meldungs_daten["IconFile"]).stem,
        }
        for meldungs_daten in json.loads(JSON)
    ]

Einzelne Meldungen sehen dann so aus:

1
2
3
4
5
{
    "zeit": datetime.datetime(2024, 10, 1, 8, 6, 21, 643333),
    "text": "Reschenstrasse:Gesperrt zwischen Kajetansbr&#xFC;cke und Nauders.Wegen baulicher Massnahmen. Umleitung signalisiert.Sperre ab 08.10.2024 bis 20.12.2024.KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.01.10.24 08:06",
    "zustand": "gesperrt",
}

Jetzt kann man beim Zustand mit == vergleichen, statt mit in irgendwo in einem Dateinamen mit Pfad und Dateiendung zu suchen. Und man kann die Zeiten nicht nur vergleichen, sondern auch mit ihnen rechnen. Also beispielsweise die Zeitspanne zwischen der ältesten und neuesten Meldung ermitteln, oder die Differenz zur aktuellen Zeit, also das Alter der Meldung.

Überarbeitete Fassung:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python3
import json
import re
from datetime import datetime as DateTime
from pathlib import PosixPath

JSON = R"""[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Abzw. Fuorns und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n16.12.24 15:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 18:17\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Susch.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nReschenstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Kajetansbr&#xFC;cke und Nauders.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nWegen baulicher Massnahmen. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n01.10.24 08:06\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]"""


def durchsuche_texte(meldungen, suchbegriff):
    return [
        meldung["text"]
        for meldung in meldungen
        if suchbegriff in meldung["text"]
    ]


def durchsuche_strassenzustand(meldungen, suchbegriff):
    return [
        meldung["text"]
        for meldung in meldungen
        if meldung["zustand"] == suchbegriff
    ]


def sammel_pass_meldungen(meldungen):
    return durchsuche_texte(meldungen, "pass")


def hole_vereina_text(meldungen):
    texte = [
        meldung["text"]
        for meldung in meldungen
        if meldung["zustand"].startswith("vereina")
    ]
    if len(texte) != 1:
        raise ValueError(f"{len(texte)} Meldungen für Vereina")
    return texte[0]


def parse_wartezeit_text(text, ort):
    start = text.index(ort)
    ende = text.index(".", start + 1)
    return text[start + len(ort) + 1 : ende]


def hole_uhrzeiten(meldungen):
    return [meldung["zeit"] for meldung in meldungen]


def _hole_meldung_nach_zeit(function, meldungen):
    meldung = function(meldungen, key=lambda meldung: meldung["zeit"])
    return meldung["text"]


def hole_neueste_meldung(meldungen):
    return _hole_meldung_nach_zeit(max, meldungen)


def hole_aelteste_meldung(meldungen):
    return _hole_meldung_nach_zeit(min, meldungen)


def main():
    alle_meldungen = [
        {
            #
            # TODO Wörterbuch mit festen Satz an Schlüsseln → Klasse.
            #
            "zeit": DateTime.fromisoformat(
                #
                # Die Zeitangaben sind grundsätzlich in einem ISO 8601-Format
                # mit gebrochenen Sekunden.  Die sind aber teilweise mit mehr
                # oder weniger als sechs Dezimalstellen angegeben, darum wird
                # hier sowohl auf die volle Stellenanzahl mit 0en aufgefüllt,
                # als auch sichergestellt, dass die Maximallänge nicht
                # überschritten wird.
                #
                meldungs_daten["MessageTime"].ljust(26, "0")[:26]
            ),
            #
            # TODO Das HTML mit einem HTML-Parser verarbeiten und in einzelne
            #      Teile (Strasse, Text, Zeitstempel) aufteilen.  Zeitstempel
            #      gegen den "MesssageTime"-Wert prüfen und ggf. Warnung oder
            #      Fehler.
            #
            "text": re.sub(r"\r|\n|<.*?>", "", meldungs_daten["MessageHtml"]),
            #
            # TODO Gegen bekannte Werte prüfen und warnen falls neue Werte
            #      auftauchen, die im Programm eventuell besonders
            #      berücksichtigt werden sollten.
            #
            "zustand": PosixPath(meldungs_daten["IconFile"]).stem,
        }
        for meldungs_daten in json.loads(JSON)
    ]

    for zustand in ["schneebedeckt", "wintersperre", "gesperrt", "info"]:
        texte = durchsuche_strassenzustand(alle_meldungen, zustand)
        print(f"Zustand {zustand!r} ({len(texte)}): {texte}")

    for kategorie, namen in [
        ("Ort", ["Davos", "Brienz", "Hinterrhein", "Klosters"]),
        ("Strasse", ["Flüelastrasse", "Oberalpstrasse", "Albulastrasse"]),
    ]:
        for name in namen:
            texte = durchsuche_texte(alle_meldungen, name)
            print(f"{kategorie}: {name} ({len(texte)}) {texte}")

    texte = sammel_pass_meldungen(alle_meldungen)
    print(f"Passmeldungen: ({len(texte)}) {texte}")
    #
    # TODO Für Vereina eine extra Klasse.
    #
    text = hole_vereina_text(alle_meldungen)
    print("ist Vereina offen?", "Offen" in text)
    endpunkte = ["Selfranga", "Sagliains"]
    wartezeit_texte = [
        parse_wartezeit_text(text, endpunkt) for endpunkt in endpunkte
    ]
    for endpunkt, wartezeit_text in zip(endpunkte, wartezeit_texte):
        print(f"{endpunkt}: {wartezeit_text} ({'keine' in wartezeit_text})")

    hat_vereina_wartezeit = all(
        "keine" in wartezeit_text for wartezeit_text in wartezeit_texte
    )
    print(f"Keine Wartezeit Vereina: {hat_vereina_wartezeit}")

    uhrzeiten = hole_uhrzeiten(alle_meldungen)
    print(
        f"Zeitraum {min(uhrzeiten)} bis {max(uhrzeiten)}"
        f" = {max(uhrzeiten) - min(uhrzeiten)}"
    )

    print(hole_neueste_meldung(alle_meldungen))
    print(hole_aelteste_meldung(alle_meldungen))


if __name__ == "__main__":
    main()

Was meinst Du mit ob JSON = R"""… bei einer HTML-Anfrage noch funktioniert? Von einer HTML-Anfrage bekommt man JSON-Quelltext zurück. Den verarbeitet man dann. Der wird ja nicht in Python-Quelltext eingefügt, also hat dieses Code-Schnippsel da überhaupt nichts mit zu tun.

holger56779

(Themenstarter)

Anmeldungsdatum:
14. Februar 2018

Beiträge: 46

Guten Nachmittag @Marc_BlackJack_Rintsch und alle weiteren

ich habe mich in die List Comprehension eingelesen und versucht eine OO- Klasse daraus zu machen Mein aktueller Stand ist:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
import json
import re
from datetime import datetime as DateTime
from pathlib import PosixPath

class Verkehr:
    def __init__(self):
        self.JSON = R"""[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Abzw. Fuorns und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n16.12.24 15:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 18:17\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Susch.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nReschenstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Kajetansbr&#xFC;cke und Nauders.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nWegen baulicher Massnahmen. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n01.10.24 08:06\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]"""
        self.alle_meldungen = [
            {
            #
            # TODO Wörterbuch mit festen Satz an Schlüsseln → Klasse.
            #
                "zeit": DateTime.fromisoformat(
                #
                # Die Zeitangaben sind grundsätzlich in einem ISO 8601-Format
                # mit gebrochenen Sekunden.  Die sind aber teilweise mit mehr
                # oder weniger als sechs Dezimalstellen angegeben, darum wird
                # hier sowohl auf die volle Stellenanzahl mit 0en aufgefüllt,
                # als auch sichergestellt, dass die Maximallänge nicht
                # überschritten wird.
                #
                meldungs_daten["MessageTime"].ljust(26, "0")[:26]
                ),
            #
            # TODO Das HTML mit einem HTML-Parser verarbeiten und in einzelne
            #      Teile (Strasse, Text, Zeitstempel) aufteilen.  Zeitstempel
            #      gegen den "MesssageTime"-Wert prüfen und ggf. Warnung oder
            #      Fehler.
            #
                "text": re.sub(r"\r|\n|<.*?>", "", meldungs_daten["MessageHtml"]),
            #
            # TODO Gegen bekannte Werte prüfen und warnen falls neue Werte
            #      auftauchen, die im Programm eventuell besonders
            #      berücksichtigt werden sollten.
            #
                "zustand": PosixPath(meldungs_daten["IconFile"]).stem,
            }
            for meldungs_daten in json.loads(self.JSON)
        ]



    def durchsuche_texte(self, meldungen, suchbegriff):
        return [
            meldung["text"] #sammel, dh fuege jeweils nur die Textteile (Zeile) in die neu generierte Liste ein 
            for meldung in meldungen #durchlaufe die gesamte Json Datei,  eine Meldung bzw ein Meldungsblock nach der anderen - das entspricht der bisherigen for Wiederholung
            if suchbegriff in meldung["text"] #nimm nur die Meldungen (Zeilen) der Json Datei, in denen der uebergebene Suchbegriff ueberhaupt vorkommt dh gefunden wird - das entspricht der bisherigen if Bedingung
        ]


    def durchsuche_strassenzustand(self, meldungen, suchbegriff):
        return [
            meldung["text"] #siehe oben 
            for meldung in meldungen #siehe oben- durchlaufe die gesamte Datei
            if meldung["zustand"] == suchbegriff #nimm nur die Meldungen (Zeilen) der Json Datei, in denen der uebergebene Suchbegriff in der Icon Datei / Zustand Zeile ueberhaupt vorkommt dh jeweils gefunden wird
        ]


    def sammel_pass_meldungen(self, meldungen):
        return durchsuche_texte(meldungen, "pass") #rufe die obere Methode auf und Suche alle Meldungen (Zeilen) in denen was mit "Pass" vorkommt


    def hole_vereina_text(self, meldungen):
        texte = [
            meldung["text"] #siehe oben
            for meldung in meldungen #siehe oben- durchlaufe die gesamte Datei
            if meldung["zustand"].startswith("vereina") #füge nur die Meldung und Zeile mit Vereina ein, finde die Infos zum Vereinatunnel
        ]
        if len(texte) != 1: #pruefe dass die Anzahl nur eine einzelne Meldung ist, sonst gibt es einen Fehler
            raise ValueError(f"{len(texte)} Meldungen für Vereina")
        return texte[0]


    def parse_wartezeit_text(self, text, ort):
        start = text.index(ort) #Finde die Position in der Zeile, an der der Ort beginnt
        ende = text.index(".", start + 1) #Finde die Position in der Zeile, an der der nachfolgende Punkt kommt
        return text[start + len(ort) + 1 : ende] #Schneide den Teilsatz, der nach dem Ort vorkommt heraus und gib ihn zurueck


    def hole_uhrzeiten(self, meldungen):
        return [meldung["zeit"] for meldung in meldungen] #erzeuge eine neue Liste, die nur die Uhrzeiten (Zeilen) jeder Meldung bzw jedes Meldungsblocks enthält


    def _hole_meldung_nach_zeit(self, function, meldungen):
        meldung = function(meldungen, key=lambda meldung: meldung["zeit"])
        return meldung["text"] #wende die uebergebene Funktion "function" auf die Liste mit allen uebergebenen Meldungen an- weiter siehe min und max Funktion unten


    def hole_neueste_meldung(self, meldungen):
        return _hole_meldung_nach_zeit(max, meldungen) #suche die neuste Meldung, die mit der groessten Zeitangabe und gib sie zurück


    def hole_aelteste_meldung(self, meldungen):
        return _hole_meldung_nach_zeit(min, meldungen) #suche die alteste Meldung, die mit der kleinsten Zeitangabe und gib sie zurück

    
    def ausgeben(self):
        print(self.hole_uhrzeiten(self.alle_meldungen))
        print(self.hole_vereina_text(self.alle_meldungen))

v=Verkehr()
v.ausgeben()

1. Ich habe an jede Zeile geschrieben, wie ich verstanden habe, dass die List Comprehension funktionieren. Stimmt das so, wie ich das im Buch nachgekesen habe? 2. self.JSON und self.alle_meldungen sollen dann zwei Attribute der Klasse Verkehr sein, mit denen ich später die weiteren Methoden ausführen kann 3. Aus einem Buch, habe ich, dass in Python bei jeder Methode self in runden Klammern dabei stehen muss, sonst findet er das Objekt nicht

Marc_BlackJack_Rintsch schrieb:

Was meinst Du mit ob JSON = R"""… bei einer HTML-Anfrage noch funktioniert? Von einer HTML-Anfrage bekommt man JSON-Quelltext zurück. Den verarbeitet man dann. Der wird ja nicht in Python-Quelltext eingefügt, also hat dieses Code-Schnippsel da überhaupt nichts mit zu tun.

Miit einem http request will ich ja die neuste json Datei vom gr.ch webserver holen und dort steht ja jeweils immernoch das ursprüngliche Zeug drin, das dem Compiler Ärger macht. Das will ich ja nicht jedes Mal von Hand verbessern.

Passt das JSON = R"""… mit einem http-Request zusammen, der funktioniert?

1
JSON = R"""+requests.get('https://...')+"""

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

@holger56779: Die Klasse macht keinen Sinn. Wenn eine Methode das self-Argument nicht verwendet dann ist es keine Methode sondern einfach eine Funktion. Eine Klasse entsteht nicht einfach dadurch das man alle Funktionen einfach einrückt und class … davor schreibt. Was soll das bringen? Der Code ist ein bisschen komplexer geworden, ohne das man irgendwas davon hat.

Konstanten in einer Funktion oder Methode zu definieren macht keinen Sinn. Konstanten werden am Anfang eines Moduls definiert, oder in selteneren Fällen auch mal auf Klassen, aber nicht als lokale Namen.

Die Kommentare zu den „list comprehensions“ gehören nicht in den Quelltext. Faustregel: Kommentare beschreiben nicht was der Code macht, denn das steht da ja bereits als Code, sondern warum er das so macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in der Regel alles was in der Dokumentation der Sprache steht und in der Dokumentation der verwendeten Bibliotheken. Sonst würde man ja ständig Teile aus der Dokumentation noch mal in Programme schreiben.

Mit dem JSON das Du von der Webseite abfragst musst Du gar nichts spezielles machen. Das kopierst Du ja nicht von Hand in den Python-Quelltext, wo es am Python-Compiler vorbei muss. Nur im Python-Quelltext muss das so stehen das es, naja eben gültiger Python-Quelltext ist.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

Das ganze mal mit einer Klasse für einzelne Meldungen und mit BeautifulSoup 4 als externe Abhängigkeit und das HTML ein bischen systematischer zu verarbeiten. Das ist ja nicht nur einfach Text, sondern hat auch Struktur. Beispiel-HTML für eine einzelne Meldung:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<div class="msg-roadevent">
  <div class="road">Italienische Strasse:</div>
  <div class="state">Information zu Abschnitt Lostallo bis AS Roveredo.</div>
  <div class="additional-info">
    <div class="cause-measure">
      Aus Sicherheitsgr&#xFC;nden. Keine Umleitung.
    </div>
    <div class="hint">
      <p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>
    </div>
  </div>
  <div class="msg-time">09.09.24 09:31</div>
</div>

Die <div>-Elemente mit den Klassen "road" und "msg-time" sind beispielsweise in jedem HTML-Fragmen enthalten. Erstere kann man als eigenen Wert dort heraus ziehen, und die Zeitangabe ist redundant und kann entfernt werden. Und beim einlesen kann man prüfen ob die beiden Zeitangaben in jeder Meldung zusammenpassen.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python3
import json
import logging
from datetime import datetime as DateTime
from pathlib import PosixPath

import bs4

JSON = R"""[{"MessageTime":"2024-12-16T15:59:36.4333333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nLukmanierstrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Abzw. Fuorns und Campra (TI).\r\n</div>\r\n<div class=\"msg-time\">\r\n16.12.24 15:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-12-15T19:20:27.3066667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAlbulastrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Berg&#xFC;n und La Punt.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 19:20\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-12-15T18:17:34.1866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nAutoverlad Vereinatunnel:\r\n</div>\r\n<div class=\"state\">\r\nOffen. Selfranga keine Wartezeit. Sagliains keine Wartezeit.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.12.24 18:17\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/vereina_normal.svg"},{"MessageTime":"2024-11-29T23:59:09.49","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nForcola-di-Livigno-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen La Motta und Forcola di Livigno, Landesgrenze CH/I.\r\n</div>\r\n<div class=\"msg-time\">\r\n29.11.24 23:59\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-22T12:33:25.33","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nSpl&#xFC;genpass-Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Spl&#xFC;gen und Landesgrenze CH/I Spl&#xFC;genpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n22.11.24 12:33\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-20T04:09:06.8733333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nFl&#xFC;elastrasse:\r\n</div>\r\n<div class=\"state\">\r\nSchneebedeckt zwischen Davos Dorf und Susch.\r\n</div>\r\n<div class=\"msg-time\">\r\n20.11.24 04:09\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/schneebedeckt.svg"},{"MessageTime":"2024-11-18T12:25:15.5833333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nOberalpstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Tschamut und Kantonsgrenze GR/UR Oberalppass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 12:25\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-18T11:56:22.5266667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nUmbrailstrasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Sta. Maria und Landesgrenze CH/I Umbrailpass.\r\n</div>\r\n<div class=\"msg-time\">\r\n18.11.24 11:56\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-17T16:53:01.1633333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Brienz und Belfortbr&#xFC;cke.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Zufahrt bis Parkplatz Ruine Belfort gestattet.</p>\r\n</div>\r\n<div class=\"next-information\">\r\nN&#xE4;chste Information: 31.03.25 13:00\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n17.11.24 16:53\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-11-15T14:41:41.0866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nWintersperre zwischen Hinterrhein und San Bernardino.\r\n</div>\r\n<div class=\"msg-time\">\r\n15.11.24 14:41\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/wintersperre.svg"},{"MessageTime":"2024-11-12T12:49:30.6866667","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nBrienzerstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Lantsch/Lenz und Brienz.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Die Brienzerstrasse ist zwischen Lantsch/Lenz und Brienz/Brinzauls bis auf Weiteres gesperrt. </p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n12.11.24 12:49\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-10-01T08:06:21.6433333","MessageHtml":"<div class=\"msg-roadcondition\">\r\n<div class=\"road\">\r\nReschenstrasse:\r\n</div>\r\n<div class=\"state\">\r\nGesperrt zwischen Kajetansbr&#xFC;cke und Nauders.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nWegen baulicher Massnahmen. Umleitung signalisiert.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Sperre ab 08.10.2024 bis 20.12.2024.</p><p>KFZ-AH über 6.5m und Busse über 13m grossräumig umfahren.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n01.10.24 08:06\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/gesperrt.svg"},{"MessageTime":"2024-09-09T09:31:09.7733333","MessageHtml":"<div class=\"msg-roadevent\">\r\n<div class=\"road\">\r\nItalienische Strasse:\r\n</div>\r\n<div class=\"state\">\r\nInformation zu Abschnitt Lostallo bis AS Roveredo.\r\n</div>\r\n<div class=\"additional-info\">\r\n<div class=\"cause-measure\">\r\nAus Sicherheitsgr&#xFC;nden. Keine Umleitung.\r\n</div>\r\n<div class=\"hint\">\r\n<p>Eröffnung der Kantonsstrasse H13 zwischen Lostallo und Cama. Die Strasse ist derzeit normal zweispurig befahrbar. Das Tiefbauamt Graubünden behält sich vor, die Strasse bei starken Regenfällen vorsorglich zu sperren, um die Sicherheit der Verkehrsteilnehmer zu gewährleisten.</p>\r\n</div>\r\n</div>\r\n<div class=\"msg-time\">\r\n09.09.24 09:31\r\n</div>\r\n</div>\r\n","IconFile":"~/images/states/info.svg"}]"""


class Meldung:
    ZEITFORMAT = "%d.%m.%y %H:%M"
    ZUSTAENDE = {
        "gesperrt",
        "info",
        "schneebedeckt",
        "vereina_normal",
        "wintersperre",
    }

    def __init__(self, zeitstempel, strasse, class_zu_text, zustand):
        self.zeitstempel = zeitstempel
        self.strasse = strasse
        self.class_zu_text = class_zu_text
        self.zustand = zustand

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.zeitstempel!r},"
            f" {self.strasse!r}, {self.class_zu_text!r}, {self.zustand!r})"
        )

    def __str__(self):
        return (
            f"{self.strasse}: {self.text} {self.zeitstempel:{self.ZEITFORMAT}}"
        )

    @property
    def text(self):
        return " ".join(text for text in self.class_zu_text.values())

    @property
    def ist_vereina_meldung(self):
        return self.zustand.startswith("vereina")

    @classmethod
    def from_json_data(cls, data):
        zeitstempel = DateTime.fromisoformat(
            #
            # Die Zeitangaben sind grundsätzlich in einem ISO 8601-Format mit
            # gebrochenen Sekunden.  Die sind aber teilweise mit mehr oder
            # weniger als sechs Dezimalstellen angegeben, darum wird hier sowohl
            # auf die volle Stellenanzahl mit 0en aufgefüllt, als auch
            # sichergestellt, dass die Maximallänge nicht überschritten wird.
            #
            data["MessageTime"].ljust(26, "0")[:26]
        )

        class_zu_text = {
            node.get("class")[0]: node.text.strip()
            for node in (
                bs4.BeautifulSoup(data["MessageHtml"], "html.parser")
                .find("div")
                .find_all("div", recursive=False)
            )
        }

        strasse = class_zu_text.pop("road").removesuffix(":")
        zeitstempel_text = class_zu_text.pop("msg-time")

        erwarteter_zeitstempel = zeitstempel.replace(second=0, microsecond=0)
        if erwarteter_zeitstempel != DateTime.strptime(
            zeitstempel_text, cls.ZEITFORMAT
        ):
            logging.warning(
                "zeiten stimmen nicht überein %r != %r",
                erwarteter_zeitstempel,
                zeitstempel,
            )

        zustand = PosixPath(data["IconFile"]).stem
        if zustand not in cls.ZUSTAENDE:
            logging.warning("bisher unbekannter Zustand %r", zustand)

        return cls(zeitstempel, strasse, class_zu_text, zustand)


def durchsuche_texte(meldungen, suchbegriff):
    return [meldung for meldung in meldungen if suchbegriff in str(meldung)]


def durchsuche_strassenzustand(meldungen, suchbegriff):
    return [meldung for meldung in meldungen if meldung.zustand == suchbegriff]


def sammel_pass_meldungen(meldungen):
    return durchsuche_texte(meldungen, "pass")


def hole_vereina_meldung(meldungen):
    vereina_meldungen = [
        meldung for meldung in meldungen if meldung.ist_vereina_meldung
    ]
    if len(vereina_meldungen) != 1:
        raise ValueError(f"{len(vereina_meldungen)} Meldungen für Vereina")

    return vereina_meldungen[0]


def parse_wartezeit_text(text, ort):
    start = text.index(ort)
    ende = text.index(".", start + 1)
    return text[start + len(ort) + 1 : ende]


def hole_uhrzeiten(meldungen):
    return [meldung.zeitstempel for meldung in meldungen]


def _hole_meldung_nach_zeit(function, meldungen):
    return function(meldungen, key=lambda meldung: meldung.zeitstempel)


def hole_neueste_meldung(meldungen):
    return _hole_meldung_nach_zeit(max, meldungen)


def hole_aelteste_meldung(meldungen):
    return _hole_meldung_nach_zeit(min, meldungen)


def main():
    alle_meldungen = list(map(Meldung.from_json_data, json.loads(JSON)))
    print(hole_uhrzeiten(alle_meldungen))
    print(repr(hole_vereina_meldung(alle_meldungen)))
    print(hole_vereina_meldung(alle_meldungen))


if __name__ == "__main__":
    main()
Antworten |