Pegelonline/pomodules/urlreader.py

128 lines
4.3 KiB
Python

import json
from gzip import GzipFile
from os.path import basename, join
from urllib.error import URLError
from urllib.parse import urlparse
from urllib.request import Request, urlopen
class UrlReader(object):
def __init__(self, _url):
"""
Erzeugt einen neuen UrlReader für gegebene url
:param _url: zu öffnende URL
"""
self.url = _url
def openUrl(self):
"""
Öffnet eine URL-Verbindung, fragt GZIP-Kompression an und gibt das Response-Objekt zurück
:return: Response-Objekt oder None im Fehlerfall
"""
print("openURL: url: \"%s\"" % (self.url,))
try:
request = Request(self.url)
request.add_header('Accept-Encoding', 'gzip')
response = urlopen(request)
print("openURL: Verbindung hergestellt")
return response
except URLError as e: # auch HTTPError
print("openURL: FEHLER: " + str(e))
return None # Fehler
def getDataResponse(self):
"""
Benutzt openUrl und gibt die (entpackten) Daten zurück.
:return: (entpackte) Daten oder None im Fehlerfall
"""
print("getDataResponse: url: \"%s\"" % (self.url,))
response = self.openUrl()
if response is None:
print("getDataResponse: FEHLER: Kein Response-Objekt erhalten")
return None
try:
if response.headers['Content-Encoding'] == 'gzip':
print("getDataResponse: Empfange GZIP Daten...")
daten = GzipFile(fileobj=response).read()
else:
print("getDataResponse: Empfange unkomprimierte Daten...")
daten = response.read()
print("getDataResponse: Daten empfangen")
return daten
except OSError as e:
print("getDataResponse: FEHLER: " + str(e))
return None # Kein Erfolg
def getJsonResponse(self):
"""
Benutzt getDataResponse zum Herunterladen, interpretiert die Daten als JSON und gibt das Ergebnis zurück.
:return: Geparste JSON Daten oder None im Fehlerfall
"""
print("getJsonResponse: url=" + self.url)
daten = self.getDataResponse()
if daten is None:
print("getJsonResponse: FEHLER: Keine Daten erhalten")
return None
try:
print("getJsonResponse: Lese JSON...")
parsed = json.loads(daten)
print("getJsonResponse: JSON gelesen")
return parsed
except ValueError as e: # JSONDecodeError
print("getJsonResponse: ValueError: " + str(e))
except TypeError as e: # JSONDecodeError
print("getJsonResponse: TypeError: " + str(e))
return None # Kein Erfolg
def _dateiname_von_url(self):
result = urlparse(self.url)
dateiname = basename(result.path)
return dateiname
def getFileResponse(self, pfad):
"""
Benutzt getDataResponse zum Herunterladen, schreibt die Daten in eine Datei und gibt ihren Pfad zurück (gegebenes Verzeichnis + basename des URL-Pfades).
:param pfad: Verzeichnis in dem die Datei gespeichert werden soll.
:return: Pfad der erzeugten Datei oder None im Fehlerfall
"""
print("getFileResponse: url: \"%s\"" % (self.url,))
print("getFileResponse: pfad: \"%s\"" % (pfad,))
daten = self.getDataResponse()
if daten is None:
print("getFileResponse: FEHLER: Keine Daten erhalten")
return None
dateiname = self._dateiname_von_url()
print("getFileResponse: dateiname: \"%s\"" % (dateiname,))
dateipfad = join(pfad, dateiname)
print("getFileResponse: dateipfad: \"%s\"" % (dateipfad,))
try:
print("getFileResponse: Schreibe Datei...")
with open(dateipfad, 'wb') as datei:
datei.write(daten)
print("getFileResponse: Datei geschrieben")
return dateipfad
except OSError as e:
print("getFilesResponse: FEHLER: " + str(e))
return None
if __name__ == '__main__':
url = "https://ia800302.us.archive.org/8/items/BennyGoodmanQuartetAndTrio/BodySoul-BennyGoodmanGeneKrupaTeddyWilsoncarnegieHall1938_64kb.mp3"
print(UrlReader(url).getFileResponse(""))