BeautifulSoup, Spritpreis abfragen

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
wusa
User
Beiträge: 40
Registriert: Dienstag 18. Februar 2014, 11:08

Hallo Zusammen,

ich möchte mir ein Skript bauen, dass mir den aktuellen Spritpreis anzeigt.
Ich weiß, ich könnte auf diverse Internetseiten gehen, und mir den aktuellen Preis ansehen. Ich will aber später das ganze automatisieren und mir per Telegram auf mein Handy schicken lassen. So habe ich meine Tankstellen zu den Zeiten an denen ich nach Hause fahre direkt auf meine Handy.

Folgendes habe ich bisher gemacht:

Code: Alles auswählen

#!/usr/bin/python3

import bs4
from urllib.request import urlopen as req
from bs4 import BeautifulSoup as soup

my_url = 'https://mehr-tanken.de/tankstelle/68ee1276/agip-josephspitalstrasse-12-80331-muenchen'
data = req(my_url)
page_html = data.read()
data.close()

page_soup = soup(page_html, "html.parser")
containers = page_soup.findAll("div", {"class":"PriceList PriceList__fuelList Card Card__inset no-margin-top"})
contain = page_soup.findAll("span", {"class":"PriceList__itemPrice h1"})
superbenzin = contain[2].text
#superbenzin.replace('\n',' ')
#superbenzin = superbenzin.rstrip()
print(superbenzin)
Meine Ausgabe sieht wir folgt aus:

1.48

9


In der Ausgabe habe ich sehr viele Leerzeichen, die ich nicht weg bringe.
Ich habe schon mit replace und rstrip versucht allerdings bringt es keinerlei Besserung.

Welche Möglichkeiten würde es noch geben, den Preis sauber auszugeben. Die "9" bräuchte ich nicht. Für mich wäre nur der direkte Preis wichtig.

Danke
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@wusa: warum nennst Du den schönen Funktionsnamen urlopen in die schwer lesbare Abkürzung `req` um? Genauso mit BeautifulSoup, das eine Klasse ist, in `soup` wo man den Nutzen und Klassencharacter nicht mehr sehen kann.

Die Methodennamen von BeautifulSoup mit Großbuchstaben sind als veraltet anzusehen, weil sie sich nicht an die Namenskonvention halten, nimm z.B. statt dessen find_all. containers wird nirgends benutzt. Dass Du das zweite Element von `contain`, nimmst, ist nicht robust. Was passiert, wenn sich die Reihenfolge der Benzinarten ändert? Die Zeile mit `rstrip` hast Du auskommentiert, obwohl man damit Leerzeichen löschen kann, aber halt nicht die, die zwischen den Zahlen. Daher wäre split dein Freund.

Die Seite liefert aber die Daten in einem viel schöneren Format, ohne raten zu müssen, an welcher Stelle was steht:

Code: Alles auswählen

data = json.loads(page_soup.find('chart')['station-data'])
prices = {p['label']: p['pivot']['price'] for p in data['prices']}
print(prices)
wusa
User
Beiträge: 40
Registriert: Dienstag 18. Februar 2014, 11:08

Ich habe mit BeautifulSoup noch nicht wirklich viel gemacht. Ich tue mich auch hart, es an meine Bedürfnisse anzupassen, das im Internet immer nur andere Beispiele sind. Daher habe ich versucht, aus den ganzen Beispielen im Internet das richtige für mich zusammen zu bauen.

json kenne ich überhaupt nicht und habe ich auch noch nie verwendet. Ich habe es aber dennoch versucht in mein Skript einzubauen.

Code: Alles auswählen

#!/usr/bin/python3

import json
import bs4
from urllib.request import urlopen as req
from bs4 import BeautifulSoup as soup

my_url = 'https://mehr-tanken.de/tankstelle/68ee1276/agip-josephspitalstrasse-12-80331-muenchen'
data = req(my_url)
page_html = data.read()
data.close()

page_soup = soup(page_html, "html.parser")

data = json.loads(page_soup.find('chart')['station-data'])
prices = {p['label']: p['pivot']['price'] for p in data['prices']}
print(prices)
Die Ausgabe sieht jetzt wie folgt aus:
{'Diesel': 1.259, 'Super (E10)': 1.409, 'Super Plus': 1.509, 'Super (E5)': 1.429}
Wie das ganze allerdings zustande kommt, bzw. wie du es gemacht hast, und wie ich die Struktur raus "lesen" kann ist mir nicht klar.

Vielleicht kannst du mir kurz erklären wie du es gemacht hast?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Was verstehst Du daran konkret nicht? `find` hast Du schon benutzt. Was json ist, kannst Du nachlesen.
wusa
User
Beiträge: 40
Registriert: Dienstag 18. Februar 2014, 11:08

Wie bist du durch den ganzen Code, der auf der Webseite ausgegeben wird, auf diese Werte gekommen?
('chart')['station-data'])
{p['label']: p['pivot']['price'] for p in data['prices']

Ich bin da div für div durchgegangen,dass ich zu den Werten kommen.
Du hattest das innerhalb weniger Minuten?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Das war Zufall. Man schaut sich die Seite an, sieht, dass die Zahlen auch graphisch aufbereitet werden, schaut dann, ob die auch in maschinenlesbarer Form abliegen und findet dann schnell das <chart>-Tag mit dem JSON-Attribut.
Antworten