Wert zwischen/nach bestimmter Zeichenkette ausgeben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Mammert
User
Beiträge: 1
Registriert: Dienstag 17. Dezember 2019, 18:58

Hallo,
ich versuche mich gerade ein wenig an Python. Ich habe Python 2.7.17 auf meinem Laptop und eine Datei (xxx.html) aus der ich gerne bestimmte Daten ausgeben lassen würde. Es gibt in der Datei bspw. Zeilen in dieser Art:

Code: Alles auswählen

<span id="line12"></span>    </span><span>&lt;<span class="start-tag">title</span>&gt;</span><span>Wagen | XXX <span class="entity"><span>&amp;</span>gt;</span><span class="entity"><span>&amp;</span>gt;</span> befindet sich zurzeit am Standort YYY</span><span>&lt;/<span class="end-tag">title</span>&gt;</span><span>
Dort würde ich mir nun gerne XXX und YYY ausgeben lassen. Bis auf die line-Angabe ist das ansonsten auch immer gleich aufgebaut.
Oder diese zwei Zeilen, die bis auf die line-Angabe auch immer gleich aufgebaut ist, bis eben auf die zwei Werte die ich gerne extrahieren würde, Gewicht und der entsprechende Wert dazu:

Code: Alles auswählen

<span id="line740"></span>          </span><span>&lt;<span class="start-tag">div</span> <span class="attribute-name">class</span>="<a class="attribute-value">pcbc-user-data-line-left</a>"&gt;</span><span>Gewicht</span><span>&lt;/<span class="end-tag">div</span>&gt;</span><span>
<span id="line741"></span>          </span><span>&lt;<span class="start-tag">div</span> <span class="attribute-name">class</span>="<a class="attribute-value">pcbc-user-data-line-right-divided</a>"&gt;</span><span>15 t</span><span>&lt;/<span class="end-tag">div</span>&gt;</span><span>
Am Ende soll dann eine Ausgabe stehen wie:

Code: Alles auswählen

XXX in YYY
Gewicht: 15 t
Nun habe ich die Datei mal eingelesen mit:

Code: Alles auswählen

datei = open("xxx.html", "r")
x = datei.read()
datei.close()
Aber für weiteres fehlt mir irgendwie der Ansatz. Ich kann ja irgendwie damit arbeiten, dass ich sage, dass er mir den Wert zwischen dieser und jener Zeichenkette ausgeben soll. Bspw. gib mir den Wert bis zum Leerzeichen der nach "<span>Wagen | " kommt. Aber wie mache ich das? Muss ich dafür irgendwie mit regulären Ausdrücken arbeiten? Eigentlich dachte ich, dass sich da einiges im Internet finden lassen sollte, aber entweder suche ich falsch oder ich kann das gefundene irgendwie nicht auf mein Problem adaptieren. Hoffe nun, dass ich hier auf die richtige Fährte komme...
nezzcarth
User
Beiträge: 1764
Registriert: Samstag 16. April 2011, 12:47

Das löst du am besten mit einer HTML Parsing-Bibliothek wie zum Beispiel BeautifulSoup. (Und Dateien öffnet man übrigens innerhalb eines with … Ausdrucks, statt sie explizit zu öffnen und zu schließen).
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Und du möchtest auf eine neuere Version von Python updaten.
Python 2.x wird noch exakt 14 Tage unterstützt.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mammert: Python 2 ist in weniger als einem halben Monat am Ende seines Lebens angekommen. Es gibt keinen Grund noch irgendetwas neues in Python 2 anzufangen. Dateimodus zum öffnen sollte dann binär sein.

Und wo kommen die Daten denn her? Das sieht nach HTML aus das ein HTML-Dokument darstellt. WTF‽
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mal den letzten Punkt noch mal konkreter: Wenn man die drei Zeilen um ein paar Tags erweitert damit da ein HTML-Dokument draus wird mit jeweils öffnenden und schliessenden Tags:

Code: Alles auswählen

<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<pre>
<span><span id="line12"></span>    </span><span>&lt;<span class="start-tag">title</span>&gt;</span><span>Wagen | XXX <span class="entity"><span>&amp;</span>gt;</span><span class="entity"><span>&amp;</span>gt;</span> befindet sich zurzeit am Standort YYY</span><span>&lt;/<span class="end-tag">title</span>&gt;</span><span>
...
<span id="line740"></span>          </span><span>&lt;<span class="start-tag">div</span> <span class="attribute-name">class</span>="<a class="attribute-value">pcbc-user-data-line-left</a>"&gt;</span><span>Gewicht</span><span>&lt;/<span class="end-tag">div</span>&gt;</span><span>
<span id="line741"></span>          </span><span>&lt;<span class="start-tag">div</span> <span class="attribute-name">class</span>="<a class="attribute-value">pcbc-user-data-line-right-divided</a>"&gt;</span><span>15 t</span><span>&lt;/<span class="end-tag">div</span>&gt;</span>
</pre>
</body>
</html>
Dann wird folgendes im Browser angezeigt:

Code: Alles auswählen

    <title>Wagen | XXX &gt;&gt; befindet sich zurzeit am Standort YYY</title>
...
          <div class="pcbc-user-data-line-left">Gewicht</div>
          <div class="pcbc-user-data-line-right-divided">15 t</div>
Das ist also tatsächlich ein HTML-Dokument das ein HTML-Dokument anzeigt. Der erste Schritt wäre also die Datei zu parsen und das HTML-Dokument aus dem HTML-Dokument zu holen, und *das* dann auch zu parsen. Oder vielleicht wäre der erste Schritt auch zu prüfen warum das so komisch ist und ob man nicht gleich das enthaltene Dokument bekommen kann.

Dann besteht ein HTML-Dokument nicht aus Zeilen. Klar hat die Datei als Textdatei gesehen Zeilen, aber die Struktur einer HTML-Datei wird nicht durch die Zeilenenden sondern durch die Tags/Elemente beschrieben. Bei den <div>s mit dem Text Gewicht und den "15 t" sieht man beispielsweise an der Einrückung das die ziemlich sicher in anderen Elementen verschachtelt sind, an denen man sich orientieren kann/sollte. An den Text im Titel kommt man beispielsweise ziemlich eindeutig über den Pfad "html/head/title" heran, und es gibt wahrscheinlich auch auf dem Weg von der Wurzel zu dem <div> mit dem "15 t"-Text noch Merkmale mit denen sich das robust(er) ansteuern lässt, als über den Text im vorherigen Geschwisterknoten. Wobei man da die Klasse(n) noch mit als Kriterium angeben kann.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten