Webseiten importieren

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
haidi
User
Beiträge: 20
Registriert: Montag 28. Dezember 2015, 23:03

Die Seite http://wetter.orf.at/niederoesterreich/melk/ veröffentlicht die Wetterdaten von einer offiziellen Wetterstation. So eine steht auch in unserem Nachbargarten steht. Ich möchte vorerst die Temperatur anzeigen (und später vielleicht noch andere Daten).

Ich habe das Modul urllib gefunden, mit der Funktion urlopen() kann man ganz einfach die komplette Webseite in eine string-Variable laden und von dieser weiter arbeiten.

Mein Code dazu (in diesem Zusammenhang: wie kann man hier den Code mit Zeilennummern veröffentlichen?):

Code: Alles auswählen

#!/usr/bin/python
# coding="utf-8"

# auslesen der Temperatur und Messzeit von Melk
from urllib import urlopen

content = urlopen("http://wetter.orf.at/niederprint "\n\n"
print "*"+Temperatur+"*"oesterreich/melk/").read()
Temperatur =  content[content.find("Temperatur")+62:content.find("Temperatur")+73]
Zeit = content[content.find("Messwerte von"):content.find("Messwerte von")+23]

# die folgenden Korrekturen benötige ich, weil die Temperatur nicht immer am gleichen Platz steht.
# Wenn sie negativ ist, dann ist im Code vorher "§minus", 
# außerdem werden einstellige Temperaturen nicht mit führender 0 angeführt
# sodass dann ein nachfolgendes Zeichen in der Variable "Tempteratur" steht.

if "&minus" in Temperatur:
	Temperatur = Temperatur[7:]
else:
	Temperatur = Temperatur[:4]
if "&" in Temperatur:
	Temperatur = Temperatur[:3]

print Temperatur
print Zeit
Allerdings möchte ich diese Abfrage in einem anderen Programm mitlaufen lassen, das aber unter Python3 läuft.

Ich habe auch noch diese Möglichkeit gefunden:

Code: Alles auswählen

import urllib.request

Webseite = "http://blog.silvertech.at"
t = urllib.request.urlopen(Webseite)

print(t.read())
Nur schaffe ich es da nicht, mit der VAriablen t bzw. mit t.read() wie oben weiter zu arbeiten.
Der BEfehl print(t.read()[0:100]) gibt b'' zurück, wenn ich anschließen den Befehl
print(t.read()) absetze, wird auch nur mehr b'' ausgegeben und nicht mehr der Inhalt der Website.

Wie kann ich diese Website in Python einfach bearbeiten?
BlackJack

@haidi: Du kannst auf dem Objekt nur einmal `read()` ausführen. Das ist ein Datenstrom. Wie eine Datei. Wenn Du einmal alles gelesen hast, dann ist das Objekt ”leer” und liefert nur noch ein leeres Bytes-Objekt bei jedem `read()`-Aufruf.

Du solltest nicht versuchen mit Zeichenkettenoperationen Informationen aus strukturierten Dokumenten zu holen. Für HTML gibt es Parser, so dass man sich an der Struktur der Daten orientieren kann, um das gewünschte zu finden. `lxml.html` ist zum Beispiel so ein Parser. Der auch gleich das herunterladen übernehmen kann.
haidi
User
Beiträge: 20
Registriert: Montag 28. Dezember 2015, 23:03

Ich weiß, dass das der korrekte Weg ist, aber meine HTML-Kenntnisse sind mehr oder weniger gleich Null, sodass ich mit den HTML-Parsern nichts anfangen kann. Ich denke auch, dass wenn sich die Darstellung dieser Seite ändert, auch ein mit Parser arbeitendes Programm versagen würde.

Mir wäre es halt lieber, mit Zeichenkettenoperatoren zu arbeiten. Gibt es unter Python 3 wirklich keine Möglichkeit mehr, anders als mit Parsern zu arbeiten?
BlackJack

@haidi: Es kommt auf die Veränderungen an. Wenn man mit der Dokumentstruktur arbeitet, ist das Programm robuster. Deins würde zum Beispiel in dem Moment auf die Nase fallen wenn irgendwo vor der Stelle die Dich interessiert, das Wort „Temperatur“ vorkommt. Und zwar *irgendwo* im Quelltext der Webseite, inklusive CSS, JavaScript, Schlüsselworte in den Metadaten im <head>, oder Kommentaren. Auch die absoluten Versatzangaben können sich leicht ändern, ohne das sich die Struktur des Dokuments ändert. Oder dass ein Minuszeichen als ``&minus;`` kodiert wird, muss nicht sein. Das könnte auch als ``&#8722;`` da stehen und wäre das selbe Zeichen, oder auch direkt als das Zeichen, ohne als HTML-Entity kodiert zu sein. Ein HTML-Parser macht daraus das Zeichen, egal wie es im Quelltext kodiert war.
haidi
User
Beiträge: 20
Registriert: Montag 28. Dezember 2015, 23:03

Danke für deine prompten Antworten.

Ich muss dir ja Recht geben, aber mein Problem ist, dass ich mit dem Parsern nicht zurecht komme.

Nachdem du mir das mit dem Datenstrom erklärt hast, habe ich nach Umleitung der Standardausgabe gesucht und damit eine mögliche Lösung gefunden:

Code: Alles auswählen

import sys
from urllib.request import urlopen

save_stdout = sys.stdout
umleitung_out = open("Temperatur.txt","w")
sys.stdout = umleitung_out

t = urlopen("http://wetter.orf.at/niederoesterreich/melk/")
print(t.read())

sys.stdout = save_stdout
Ich weiß, ist super-suboptimal, aber bis ich mich mit den Parsern auskenne, werde ich es einmal so fahren.
BlackJack

@haidi: Das ist auch ohne Parser völliger Unsinn. Wenn Du den Inhalt in einer Datei haben willst, dann gib ihn halt nicht mit `print()` aus. Wenn Du beides willst, dann binde das Ergebnis von `read()` an einen Namen und mach Ausgabe und Speichern dann mit diesem Wert nacheinander ohne diese völlig unnötige Ausgabeumleitung der Standardausgabe.

Was Du da geschrieben hast ist einfach nur eine sehr umständliche Art etwas in eine Datei zu schreiben (die man danach auch wieder schliessen sollte, entweder explizit oder durch ``with``):

Code: Alles auswählen

from urllib.request import urlopen


def main():
    with open('Temperatur.txt', 'w') as html_file:
        html_file.write(
            urlopen('http://wetter.orf.at/niederoesterreich/melk/').read()
        )

if __name__ == '__main__':
    main()
haidi
User
Beiträge: 20
Registriert: Montag 28. Dezember 2015, 23:03

DAnke Blackjack:
Beim Datei schließen habe ich eine Fehlermeldung bekommen, die wollte ich mir später anschauen

Hast ja vollkommen recht, dass es einfachere Wege gibt, nur ist Python eine immens umfangreiche Sprache, sodass es vor allem als Anfänger verdammt schwer ist, den optimalen Weg zu finden, da geht man halt oft Umwege. In meinem Alter gehts auch nicht mehr so einfach.
Antworten