urllib
– Internetseiten auslesen
Über die System-Bibliothek urllib
können Inhalte von Internetseiten ausgelesen werden. Dabei ist die Handhabung sehr einfach, wenn die ausgelesene Internetseiten das Auslesen nicht unterbindet. Schauen wir uns die Handhabung an.
Im Browser gibt man eine URL an, um eine Website abzurufen. Dabei steht URL für „Uniform Resource Locator“ – also übersetzt „einheitlicher Ressourcenzeiger“. Dabei kann die URL viele Informationen enthalten.
Schauen wir es uns am Beispiel von folgender URL an:
https://www.python-lernen.de/search?q=Axel#top
Aufbau URL:
- Protokoll: Am Anfang steht das Protokoll, z.B. https, http, ftp usw.
- Hostname: dann kommt der Hostname, im Beispiel www.python-lernen.de
- Port: manchmal kommt danach ein Doppelpunkt mit einer Nummer danach. Dadurch wird der Port festgelegt. Standardmäßig steht der Port 80 für http und der Port 443 für https – diese müssen nicht angegeben werden. Aussehen würde es sonst so: https://www.python-lernen.de:443/
- Pfad: Wenn nicht dir Startseite angezeigt werden soll, wird der Pfad zur gewünschten Seite mitgegebenen
- Query-String: nach dem Fragezeichen können zusätzlich Daten über dir URL übertragen werden. Im Beispiel wird der Inhalt für die Suchfunktion übertragen
- Sprungmarke: Am Ende kann gekennzeichnet durch die Raute noch eine Sprungmarke innerhalb der Seite mitgegeben werden
Die URLLIB-Bibliothek unterstützt das Erstellen, Herunterladen und Parsing von URLs. Dafür stehen in der Bibliothek 5 Module zur Verfügung, von denen 4 durch den Programmierer eingesetzt werden können:
- request
- response (wird intern von URLLIB genutzt)
- error
- parse
- robotparser
Über request
öffnen wird URLs
Über error
können wir auf Fehler während dem Zugriff etc. reagieren
Mit parse
stehen praktische URL-Funktionen zur Verfügung
Und über robotparser
können wir den Inhalt der robots.txt auswerten.
request-Modul – Laden von Inhalten
Zum Nutzen der URLLIB-Bibliothek müssen wir diese importieren.
import urllib
print(help(urllib))
Über die Help-Funktion sehen wir wieder unsere 5 Module (request, error, parse, …), die wir nutzen können.
Wir wollen im Folgenden das Modul request nutzen:
from urllib import request
Lassen wir uns mit dir
alle Angaben ausgeben, sehen wir die vielen Methoden und Klassen, die uns über das Modul zur Verfügung stehen:
from urllib import request
print(dir(request))
['AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'AbstractHTTPHandler', 'BaseHandler', 'CacheFTPHandler', 'ContentTooShortError', 'DataHandler', 'FTPHandler', 'FancyURLopener', 'FileHandler', 'HTTPBasicAuthHandler', 'HTTPCookieProcessor', 'HTTPDefaultErrorHandler', 'HTTPDigestAuthHandler', 'HTTPError', 'HTTPErrorProcessor', 'HTTPHandler', 'HTTPPasswordMgr', 'HTTPPasswordMgrWithDefaultRealm', 'HTTPPasswordMgrWithPriorAuth', 'HTTPRedirectHandler', 'HTTPSHandler', 'MAXFTPCACHE', 'OpenerDirector', 'ProxyBasicAuthHandler', 'ProxyDigestAuthHandler', 'ProxyHandler', 'Request', 'URLError', 'URLopener', 'UnknownHandler', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_cut_port_re', '_ftperrors', '_get_proxies', '_get_proxy_settings', '_have_ssl', '_localhost', '_noheaders', '_opener', '_parse_proxy', '_proxy_bypass_macosx_sysconf', '_randombytes', '_safe_gethostbyname', '_splitattr', '_splithost', '_splitpasswd', '_splitport', '_splitquery', '_splittag', '_splittype', '_splituser', '_splitvalue', '_thishost', '_to_bytes', '_url_tempfiles', 'addclosehook', 'addinfourl', 'base64', 'bisect', 'build_opener', 'contextlib', 'email', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies', 'getproxies_environment', 'getproxies_macosx_sysconf', 'hashlib', 'http', 'install_opener', 'io', 'localhost', 'noheaders', 'os', 'parse_http_list', 'parse_keqv_list', 'pathname2url', 'posixpath', 'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_macosx_sysconf', 'quote', 're', 'request_host', 'socket', 'ssl', 'string', 'sys', 'tempfile', 'thishost', 'time', 'unquote', 'unquote_to_bytes', 'unwrap', 'url2pathname', 'urlcleanup', 'urljoin', 'urlopen', 'urlparse', 'urlretrieve', 'urlsplit', 'urlunparse', 'warnings']
Wir wollen ein URL laden, daher benötigen wir urlopen(url)
. Zum Testen nutzen wir die Beispielseite www.example.com
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
print(type(rueckgabewert))
Als Rückgabewert erhalten wir ein Response-Objekt (kann man wohl am besten mit Antwort-Objekt übersetzten) – siehe type(rueckgabewert)
.
<class 'http.client.HTTPResponse'>
Dieses Antwort-Objekt stellt und verschiedene Methoden zur Verfügung:
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
print(type(rueckgabewert))
print(dir(rueckgabewert))
Als Ergebnis von dir(rueckgabewert)
erhalten wir:
['__abstractmethods__', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_abc_impl', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_check_close', '_close_conn', '_get_chunk_left', '_method', '_peek_chunked', '_read1_chunked', '_read_and_discard_trailer', '_read_next_chunk_size', '_read_status', '_readall_chunked', '_readinto_chunked', '_safe_read', '_safe_readinto', 'begin', 'chunk_left', 'chunked', 'close', 'closed', 'code', 'debuglevel', 'detach', 'fileno', 'flush', 'fp', 'getcode', 'getheader', 'getheaders', 'geturl', 'headers', 'info', 'isatty', 'isclosed', 'length', 'msg', 'peek', 'read', 'read1', 'readable', 'readinto', 'readinto1', 'readline', 'readlines', 'reason', 'seek', 'seekable', 'status', 'tell', 'truncate', 'url', 'version', 'will_close', 'writable', 'write', 'writelines']
Wir können also den Rückantwort-Code anfragen über .code
:
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
print(rueckgabewert.code)
Hier erhalten wir als Rückgabe den Wert 200
. Dieser sagt uns, dass die Anfrage geklappt hat. Es gibt verschiedene Rückgabewerte, die über Erfolg oder Misserfolg der Aktion uns alles sagen. Diese nennen sich http Status Codes:
- 200: OK
- 400: Bad Request
- 403: Forbidden
- 404: Not Found
Wir können genauso die Größe der „Datei“ über .length
abfragen:
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
print("Dateigröße in Bytes: ", rueckgabewert.length)
Und wir können den Anfang des Inhalts anzeigen lassen über .peek()
:
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
print("Anfang des Inhalts:
", rueckgabewert.peek())
Und hier bekommen wir folgende Rückgabe – wichtig ist der Anfang mit b'
!
b'<!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding
Dieses b'
am Anfang sagt uns, dass es sich um ein Byte-Objekt handelt.
Jetzt können wir die komplette Datei auslesen über die Anweisung rueckantwort.read()
.
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
inhalt = rueckgabewert.read()
print(type(inhalt))
Wir bekommen als Rückantwort die Bestätigung über das Überprüfen des Typs, dass es sich um einen Byte-Strom handelt:
<class 'bytes'>
Den Inhalt können wir umwandeln. Dazu muss das Format bekannt sein. Wir haben bei den ersten Zeilen des Inhalts gesehen, dass es sich um das UTF8-Format handelt.
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
inhalt = rueckgabewert.read()
print(type(inhalt))
inhalt_text = inhalt.decode("UTF-8")
print(type(inhalt_text))
Danach liegt und ein String vor („<class 'str'>“) und wir können dieses ausgeben.
from urllib import request
rueckgabewert = request.urlopen('http://www.example.com/')
inhalt = rueckgabewert.read()
inhalt_text = inhalt.decode("UTF-8")
print(inhalt_text)
<!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> …
Nachdem wir den Inhalt ausgelesen haben, wird die Verbindung automatisch geschlossen. Es kann der Inhalt kein zweites Mal aus dem Byte-Strom ausgelesen werden!
Dazu weitere Information unter:
https://docs.python.org/3/library/urllib.html