urrllib und apis mit Python

urrllib und apis mit Python Titelbild

Gerade wenn 2 verschiedene Programme oder Computer mit einander Daten austauschen ist es wichtig das sie gleiche Sprechen und die Daten, welche sie austauschen das gleiche Format haben. Sonst hättest du jemanden der versucht dir mit Chinesischen Schriftzeichen zu sagen wie warm es, du aber nur die Lateinischen Buchstaben kennst und deswegen nichts was er sagt verstehst.

Für soetwas gibt es standardisierte Datenformate und eins davon wird JSON genannt. Dieses Format kommt nicht von Python sondern ist von JavaScript inspieriert, lässt sich aber generell überall Verwenden. Damit alle auch wirklich das gleiche Format verwenden und nichts durch einander kommt gibt es dazu auch eine Spezifizirung [rfc7159 ](http://tools.ietf.org/html/rfc7159.html ). Darin wird genau festgelegt wie so ein JSON aussehen darf.

Hier einmal ein kleines Beispiel:

{
  "Produkt": "Jugend Programmiert Starterkit",
  "Artikel Nummer": "JP00001",
  "Deckung": 2e+6,
  "Waehrung": "EURO",
  "Inhaber": {
    "Name": "Krake",
    "Vorname": "JP",
    "Krake": true,
    "Hobbys": [ "LEDs Essen", "Python", "Raspberry Pi" ],
    "Alter": 1,
    "Kinder": false,
    "Partner": null
  }
}

Tipp: Es kommt manchmal vor das du mit deinem Webbrowser auf eine Website gehst und die Website dir nicht HTML ausgibt sondern ein JSON Objekt. Das sieht dann ein wenig komisch aus aber mit einem Browser Plugin kannst du es so anzeigen wie oben.

JSONView Erweiterung für den Google Chrome Browser

JSONView Erweiterung für den Firefox Browser

Damit du JSON in Python benutzen kannst musst du natürlich erst noch eine Libary Importieren.

import json

Erst einmal was ist die Private IP Adresse? Für die Kommunikation in deinem Netzwerk, kommt meisten von einem Router, bekommst du eine Private IP Adresse. Ip Adressen besehen aus 4 Zahlen von 0 bis 255 die durch einen Punkt getrennt sind. Mit dem Befehl ifconfigkannst du die Private IP Herausfinden.

Die Private IP Adresse ist zum Beispiel allem wichtig wenn du dich per ssh auf dein Pi verbinden möchtest. Weitere Beispiele sind Webserver die du auf deinen Pi/Computer laufen lässt. Es gibt in Python keine eingebaute Lösung dafür, aber es gibt eine Libary die wir installieren können: netifaces

sudo pip-3.2 install netifaces

Bevor wir weitermachen ist noch wichtig zu wissen das dein Computer auch mehrere Private IP Adressen in deinem Netzwerk haben kann, wenn du z.B. mit LAN und WLAN verbunden bist.

Hier einfach mal ein kleines Beispielprogramm:

import netifaces
interfaces = netifaces.interfaces()
print(interfaces)

In Zeile 1 Importieren wir unsere Libary. In Zeile 2 Rufen wir die Funktion interfaces() auf speichern das in der Variable interfaces . Diese geben wir dann in der nächsten Zeile aus. Bei mir sieht das den so aus:

['lo', 'eth0', 'wlan0']

Jetzt haben wir aber nicht die Private IP Adresse sondern erstmal nur eine Übersicht der Netzwerk Schnittstellen. Im nächsten Schritt werde ich die Private IP von meiner wlan0 Schnitstelle auslesen, das kann bei euch natürlich auch anders sein.

import netifaces

local_ip = netifaces.ifaddresses('wlan0')[netifaces.AF_INET][0]['addr']

print(local_ip)

Die größte Änderung liegt in Zeile 2. Wir benutzten die Funktion ifaddresses() und übergeben noch den Parameter wlan0. Diese Funktion liefert ein ein dictionary zurück. Um ein Dictionary auszulesen musst du den richtigen Wert in Eckigen Klammern direkt hinter das Ditionary schreiben.. Wichtig ist nur das netifaces.AFINET für uns schon die Informationen raussucht welche Wichtig sind für die Daten von der Privaten IP Adresse. Mit dem 0 danach geben wir an welchen Wert wird haben wollen. Dieser sollte bei euch in 99,9 der Fälle immer nur 0 sein. Also das erste Gerät. Solltet ihr mehrere Private IP Adressen über eine Schnittstelle haben, dann müsstet ihr diesen Wert ändern. Am Ende sagen wir mit ['addr']_ das wir auch wirklich die Private IP Adresse haben wollen. Die IP speichern wir dann in der Variable _localip

War doch gar nicht mal so schwer wenn du weißt, wie du etwas machen willst.

  • Was passiert wenn du einfach nur netifaces.ifaddresses('wlan0')</ ausgibst? Und danach die Werte in den Eckigen Klammern anpasst? *

Du will jeden Tag um 13:37 ein bestimmte Sache machen? Das ist mit Cronjobs kein Problem. Z.B. könnten wir damit alle 5 Minuten ein Python Programmieren ausführen das eine LED anschaltet oder Daten ausmist.

crontab -e

Mit diesem Befehl im Terminal kannst du einen neuen Cronjob anlegen. Daraufhin öffnet sich in Nano die Crontab Datei.

211.png

Dort steht auf English erst eine kleine Erklärung. Am Ende der Datei könnt ihr dann ein neuen Cronjob Anlegen. Ein Crobjob ist dabei immer so aufgebaut:

* * * * * * Dein_Befehl/

Dabei steht jeder Stern für eine Zeiteinheit:

1 2 3 4 5
Nach dem Neutart Minuten 0-60 Stunden 0-24 Tag eim Monat 0-31 Monate 0-12

Ihr könnt auch anstatt einer Zahl einfach ein * Stern schreiben und damit sagen das der Befehl jede Minute/Stunde/Tag/Monat ausgeführt werden soll.

Jeden Tag um 7:05 Geweckt werden:

5 7 * * * sudo python3 /home/pi/Wecker.py

Dieser Progamm wird jeden Tag um 7:05 aufgerufen und wenn in Wecker.py ein Wecker versteckt ist, wirst du sogar geweckt.

Am 01.01 Frohes Neues Wünschen

0 0 1 1 * python3 /home/pi/FrohesNeuesJahr.py

Am 1. Tag des 1. Monats wird jetzt immer dieses Programm ausgeführt. Gar nicht mal so schwierig oder?

Also mit den ersten 5 Werten legt ihr Zeit fest und danach dann den Befehl welchen ihr in dem Zeitlichen Rahmen ausführen wollt. Das müssen nicht nur Python Dateien sein.

crontab -l

Mit diesem Befehl könnt ihr euch alle erstellen Crontabs ansehen.

Falls ihr euch mal nicht sicher seit ob ein Crontab ausgeführt wurde könnt ihr das mit dem folgenden Befehl nach verfolgen:

grep CRON /var/log/syslog
212.png

Falls es zu Problemen kommt sollte ihr auch Kontrollieren ob ihr die richtige Zeit eingestellt habt.

Mit dem deinem Browser kannst du einfach durch das World Wide Web Surfen aber würdest du mir glauben das es noch eine andere Seite gibt. Den nicht nur Menschen Surfen durchs Webs und rufen Daten ab erstellen neue sondern auch Computer Programme. Es gibt für Computer Programme auch besondere Dienste mit den Maschinenlesbar Informationen gespeichert werden können. Diese werden auch API genannt.

Vorraussetzung:

  • Du hast eine Internet Verbindung
  • Hast Motivation aktiviert

Für diese Aufrufe benutzen wir die urllib Libary. Deswegen lass uns doch einmal anfangen:

nano urllib_einfach.py
import urllib.request

website = urllib.request.urlopen('http://codetrainer.de')
print(website.read())

Wenn ihr euer Programm dann ausführt sollte ihr so einen Salat bei euch im Terminal sehen:

206.png

Aber was haben wir überhaupt gemacht?

In Zeile 1 haben wir die Libary urllib eingebunden. Diese hat mehrere Komponenten deswegen müssen wir sagen das wir die urllib.request Komponente brauchen. In Zeile 3 öffnen wir unsere Wunsch URL. Ich habe einfach mal den codetrainer.de ausgewählt. Die Funktion heißt dabei urlopen. Den gesamten Inhalt speichern wir dann in der Variable website. In Zeile 4 "lesen" wir dann den Gesamten Inhalt der Website. Diesen ganzen Text den du jetzt in deiner Konsole siehst, sollte ungefähr so aussehen wie auf dem Bild, ist der Inhalt den dein Webbrowser in die Visuelle Form umwandelst, welches dein Browser ausgibt. Dies wird auch html genannt.

Wie du vielleicht bemerkst hast, ist es nett das mal zu sehen, aber hierbei handelt es sich nicht um eine API den unser Computer Programm kann nicht wirklich etwas mit dem html-Salat anfangen.

In unserem nächsten Beispiel/Einheit werden wir uns nützlichere Daten mit unserem Programm auslesen.

Jetzt bist du dran: Sieht es anders aus wenn du die URL auf andere Webseiten änderst? Z.B. Google.de, etc...[/alert]

Es gibt verschiedene Arten der Daten übermittlung im Internet. Wir haben in der letzten Einheit ein get-Aufruf gemacht [get = bekommen]. Wir haben noch keine Daten übergeben, denn das kommt jetzt! Vielleicht ist dir schon einmal aufgefallen das oben in der URL noch mehr als nur die Adresse steht. Z.B. wenn du etwas bei Google suchst:

https://www.google.de/?q=dein_suchbegriff

Mit dem ?q=dein_suchbegriff wird an Google übergeben das nach dein_suchbegriff gesucht werden soll. (Oder Googelt ihr etwa etwas anderes?!?!). Über diese Art und weise können wir aber noch mehr Parameter übergeben:

https://www.google.de/?q=dein_suchbegriff&lieblingsessen=leds&farbe=grün

Du kannst dir das übergeben der Werte wie bei der Variable vorstellen, zuerst kommt der Name und nach dem Gleich dann der Wert. Wenn ihr jetzt diese URL in euren Browswer eingibt werdet ihr bemerken das dieses Eingeben der Variablen nicht wirklich das Suchergebnis verändert. Das liegt daran das, dass Google Programm nicht weiß was es mit diesen Daten machen soll. Deswegen ignoriert das Programm diesen Daten einfach. Alles was aber bei q= steht verwendet es um nach dem Inhalt zu suchen.

Deine erste richtige API

Wolltest du nicht schon immer mal wissen wann die Sonne untergeht? Dann warte bis zum ende des Kurzes und dort wirst du das vielleicht herausfinden! Erstmal wollen wir uns mit einer wirklichen Simplen API vom Codetrainer beschäftigen. Mit dieser API kannst du dir anzeigen lassen wie viele Kurse es in den verschiedenen Kategorien gibt. (Es wird interessanter, versprochen!)

import urllib.request
import json

website = urllib.request.urlopen('http://api.codetrainer.de/data?topic=python')
websiteString = website.read().decode('utf-8')
data = json.loads(websiteString)

if data['status'] == True:
        print(data['units'])
else:
        print('Es gab ein Fehler')

Bevor du dich jetzt wunderst was wir alles machen erst einmal eine Erklärung. In Zeile 1-2 importiere wir wieder die Libaries. In Zeile 3 Öffnen wir die Website. In der URL übergeben wir den Parameter das topic gleich python ist. Das öffnen der Website wird dann in der Variable website gespeichert. Dann speichern wir in Zeile 4 in die Variable websiteString die Website aber zuerst lesen wir sie aus mit .read() und dann Verwandeln wir diesen Inhalt noch in ein String mit .decode('utf-8') . Davor haben wir nämlich kein Text bekommen sondern einen Response Type und das wird in der nächsten Zeile Wichtig.

In Zeile 6 nehmen wir das JSON und wandeln es zu einem Python Dictionary um. Das heißt wir dann in der Variable data die Daten von der Website in einem Format das wir es ganz einfach benutzen können. Doch damit wir die Funktion json.loads() benutzten konnten brauchten wir dafür zuerst das JSON Objekt in der form eines Strings.

In Zeile 8 kontrollieren wir dann ob der Status True ist, sollte das der Fall sein geben wir dann die Anzahl der Kurse in diesem Themenbereich aus. Sollte es ein Fehler geben, geben wir dann in der else Anweisung eine kleiner Fehlermeldung aus.

Das war jetzt alles ein wenig kompliziert, aber jetzt verstehst du vermutlich, warum es wichtig ist das ein String nicht auf einmal ein Int wird. Die Libaries können immer nur mit bestimmen Formaten arbeiten.

Noch Fragen oder Feedback?

Bevor du eine Frage stellen kannst musst du dich zuerst Anmelden oder Regestrieren!