Seite 1 von 2
Brotli
Verfasst: Donnerstag 9. Juli 2020, 18:02
von Kusja
Hallo zusammen. Ich muss für die Hochschule folgende Aufgabe lösen:
'Senden Sie eine GET Request an
http://httpbin.org/brotli. Sehen Sie sich die Eigenschaftcontent Ihrer Response an und finden Sie einen Weg, den Inhalt von content in Plain Text zuübersetzen.'
Mein Code sieht wie folgt aus:
Code: Alles auswählen
import requests, brotli
response = requests.get('http://httpbin.org/brotli')
print('Response-----------------------------------')
print(response.content)
print('-------------------------------------------')
data = brotli.decompress(response.content)
print('Meaning: ')
print(data)
Die Konsolo spuckt mir hierbei einen error.:
brotli.error: BrotliDecompress failed
Für eure Hilfe bin ich sehr dankbar

.
Liebe Grüße
Kusja
Re: Brotli
Verfasst: Donnerstag 9. Juli 2020, 18:38
von nezzcarth
Dein Ansatz ist denke ich falsch. Wenn die brotli Bibliothek installiert ist, kümmert sich requests alleine darum, das zu dekodieren. Von dir wird denke ich etwas anderes verlangt; requests hat dafür eine eingebaute Methode. Schau dir "content" mal genauer an. Das ist ja der Sinn von 'content', dass da bereits die Dekodierung stattgefunden hat.
Re: Brotli
Verfasst: Donnerstag 9. Juli 2020, 19:34
von __blackjack__
@nezzcarth: Also bei mir kümmert sich `requests` da nicht drum. Bei mir funktioniert dann aber auch was der OP da macht ohne eine Ausnahme.
Code: Alles auswählen
In [209]: response = requests.get('http://httpbin.org/brotli')
In [210]: print(brotli.decompress(response.content).decode())
{
"brotli": true,
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5f0762d2-e96b31fc0c98f90a69c586ae"
},
"method": "GET",
"origin": "79.230.157.192"
}
Re: Brotli
Verfasst: Donnerstag 9. Juli 2020, 19:42
von nezzcarth
__blackjack__ hat geschrieben: Donnerstag 9. Juli 2020, 19:34
@nezzcarth: Also bei mir kümmert sich `requests` da nicht drum.
Vielleicht ist das ein Versionsunterschied?
Code: Alles auswählen
Python 3.8.3 (default, May 17 2020, 18:15:42)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import requests
In [2]: response = requests.get('http://httpbin.org/brotli')
In [3]: response.content
Out[3]: b'{\n "brotli": true, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/xxxx", \n "X-Amzn-Trace-Id": "Root=xxx\n }, \n "method": "GET", \n "origin": "xxx.xxx.xxx.xxx"\n}\n'
Re: Brotli
Verfasst: Donnerstag 9. Juli 2020, 20:31
von __blackjack__
qnezzcarth: Ja, das scheint ein Unterschied bei `urllib3` zu sein. Vorher urllib3-1.22, jetzt urllib3-1.25.9. Bei letzterer geht's dann auch automagisch.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 07:53
von Kusja
Ich muss ja den content in einen Plain Text umcordieren. Und laut der Dozenten geht es mit brotli. Nur wie man dort den richtigen Code schreibt ist mir schleierhaft. Im Internet finde ich zwar Beiträge zu diesem Thema aber keine Erklärung wie das geschrieben wird.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 08:24
von sparrow
Wie sieht denn dein Content aus?
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 09:54
von Kusja
Der content ist vom Typ json.
Code: Alles auswählen
b'{\n "brotli": true, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.24.0", \n "X-Amzn-Trace-Id": "Root=1-5f082ba9-3c73cc09eaf15846ad6cec54"\n }, \n "method": "GET", \n "origin": "87.123.198.239"\n}\n'
Verstehe nicht ganz was er mit Plain Text meint. Meiner Auffassung würde ich dies einfach in json umcodieren.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 09:57
von Kusja
@__blackjack__ ich verstehe nicht warum dein Code den Content in json formatiert und bei mir immer wieder der selbe error kommt.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 10:02
von sparrow
Ich befürchte, da hat die Realität deinen Dozenten überholt.
requests hat den Content bereits dekodiert. Scheint, wie __blackjack__ ja oben gezeigt hat, nicht immer so gewesen zu sein.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 10:07
von Kusja
Wenn ich es auf diese Weise mache funktioniert das.
Code: Alles auswählen
import requests
response = requests.get('http://httpbin.org/brotli')
print(response.text)
Ausgabe :
Code: Alles auswählen
{
"brotli": true,
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5f082f95-9cb5d254252a4b7e17227442"
},
"method": "GET",
"origin": "87.123.198.239"
}
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 10:51
von nezzcarth
Ausgeben ist kein Dekodieren für mich. Ich würde das JSON noch parsen (lassen). Dafür hat requests, wie bereits gesagt, eine eingebaute Methode.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 11:03
von __blackjack__
@nezzcarth: Das ist aber nicht die Aufgabe. Die Aufgabe ist „finden Sie einen Weg, den Inhalt von content in Plain Text zuübersetzen.“
Und das ist einfach das `text`-Attribut wenn `requests` beziehungsweise `urllib3` das Entpacken bereits übernimmt.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 11:07
von nezzcarth
Dann ist die Aufgabe meiner Meinung nach aber nicht lösbar, denn - das mag jetzt Erbsenzählerei sein - streng genommen ist Json ja nun mal Json und kein Plain Text.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 12:07
von Sirius3
@nezzcarth: Plain Text wird hier als Objekt des Typs str verstanden. response.content sind Bytes und response.text eben Text.
Re: Brotli
Verfasst: Freitag 10. Juli 2020, 13:20
von __blackjack__
@nezzcarth: Es ist doch egal was es letztlich ist, die Aufgabe ist ja `contents`, also Bytes in Text zu ”übersetzen” und *das* geht. Völlig unabhängig davon ob man den Text dann noch als BASIC-Quelltext, CSV, JSON, XML, oder sonst was interpretieren könnte.
Re: Brotli
Verfasst: Dienstag 14. Juli 2020, 14:36
von Kusja
Ich hätte da noch eine Frage. Ich habe eine json Datei (clients.json):
Code: Alles auswählen
[
{
"id": "d6317eca-bb8d-47a2-871a-80eea6ca39b3",
"data": {
"name": "Fox Richardson",
"contact": {
"digital": {
"email": "foxrichardson@aquasure.com"
},
"real": {
"city": "Ezel",
"street": "Locust Avenue"
}
}
}
},
{
"id": "2bb7d904-3b76-4cc2-97b6-f2670697482c",
"data": {
"name": "Gabrielle Fields",
"contact": {
"digital": {
"email": "gabriellefields@aquasure.com"
},
"real": {
"city": "Barstow",
"street": "Veterans Avenue"
}
}
}
},
{
"id": "7bef15ff-adfe-4371-af0d-79438a42728b",
"data": {
"name": "Hess Sweeney",
"contact": {
"digital": {
"email": "hesssweeney@aquasure.com"
},
"real": {
"city": "Loretto",
"street": "Gem Street"
}
}
}
}
]
Und hierbei möchte ich mir den Namen, die Email und den Wohnort ausgeben lassen.
Mein Code:
Code: Alles auswählen
import json
# import os.path
# print(os.path.exists('clients.json'))
f = open('clients.json', 'r')
y = json.load(f)
for row in y:
print('Mein Name ist', row['data']['name'], 'und ich bin unter der E-Mail: ',
row['data']['contact']['digital']['email'],
'erreichbar und wohne in', row['real']['city'])
Error: KeyError : 'real'
Wenn ich nur den Namen und die Email auslesen funktioniert es. Sobald ich aber 'real' 'city' einfüge kommt der oben genannte Fehler.
Hat jemand eine Lösung für mich.
Json ist neu für mich und ich weiß nicht genau wie man dort den Wohnort auslist.
Und könnte mir einer den wesentlichen Unterschied zwischen
load & loads und dump & dumps erläutern? Ich komme jedes mal durcheinander.
MfG
Kusja
Re: Brotli
Verfasst: Dienstag 14. Juli 2020, 14:52
von noisefloor
Hallo,
Json ist neu für mich und ich weiß nicht genau wie man dort den Wohnort auslist.
Das praktische (für Python-Programmierer) ist, dass sich eine JSON-Struktur sehr gut als Python Datenstruktur abbilden lässt. Ein JSON-Object ist wie ein Python Dict und ein JSON Array wie eine Python Liste.
Im gegebenen Bespiel: du hast eine Liste mit drei Dicts, die wiederum Dicts enthalten.
load & loads und dump & dumps erläutern? Ich komme jedes mal durcheinander.
load und dump erwarten ein "file-like objekt", um daraus zu Lesen bzw. dahin zu schreiben, loads und dumps eine String (oder Bytes oder Bytearray). Eselsbrücke: das "s" bei loads und dumps steht für "String".
Gruß, noisefloor
Re: Brotli
Verfasst: Dienstag 14. Juli 2020, 18:49
von Kusja
Danke erst mal für die schnelle Antwort. Ich sitze gerade ziemlich auf dem Schlauch. Ich greife im Code ja so auf den Wert zu wie auch im dict. Nur leider kommt jedes mal der KeyError... Ich weiß auch nicht was ich dort falsch mache.
ACH, Vielen Dank! Mit dem 'S' ist echt eine gute Eselsbrücke

:
Re: Brotli
Verfasst: Dienstag 14. Juli 2020, 19:28
von noisefloor
Hallo,
das Dict ist auch anders verschachtelt. Im Zweifelsfall hilft immer: Klammer zählen
Code: Alles auswählen
>>> row = {
... "id": "7bef15ff-adfe-4371-af0d-79438a42728b",
... "data": {
... "name": "Hess Sweeney",
... "contact": {
... "digital": {
... "email": "hesssweeney@aquasure.com"
... },
... "real": {
... "city": "Loretto",
... "street": "Gem Street"
... }
... }
... }
... }
>>> row
{'id': '7bef15ff-adfe-4371-af0d-79438a42728b', 'data': {'name': 'Hess Sweeney', 'contact': {'digital': {'email': 'hesssweeney@aquasure.com'}, 'real': {'city': 'Loretto', 'street': 'Gem Street'}}}}
>>> row['data']['contact']['real']['city']
'Loretto'
>>>
Gruß, noisefloor