Erster Post, Anfängerfrage: requests.request

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
realHans
User
Beiträge: 2
Registriert: Montag 29. Mai 2023, 18:28

Hallo,
mein erster Post :*)

Zu mir:
Bis vor etwa 5 Jahren habe ich 10 Jahre lang mein Geld mit Programmieren verdient, VB6 mit Visual Studio 6 und PL/SQL. Python ist mir neu und auch alles etwas eingerostet ... Das Visual Studio Code finde ich übrigens Klasse :)

Auf dieser Webseite wird erklärt, wie ich mit JSON Daten von einem Solar-Überwachungsgerät (einem Solar-Log base) holen kann.
https://www.matusz.ch/blog/2020/08/09/s ... ansteuern/

Die IP Adresse habe ich auf mich angepasst, so hole ich erfolgreich die Daten ab:

Code: Alles auswählen

import requests
url = "http://192.168.178.34/getjp"
payload = "{\"801\":{\"170\":null}}"
headers = {'content-type': 'application/json'}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
Das was zurückkommt (über print(response.text)) schaut gut aus:

Code: Alles auswählen

{"801":{"170":{"100":"29.05.23 19:17:30","101":1992,"102":1923,"103":0,"104":498,"105":47509,"106":48920,"107":911094,"108":2764322,"109":36609031,"110":2094,"111":14719,"112":40185,"113":443068,"114":2461296,"115":17747228,"116":15000}}}
Jetz will ich aber auf [801][170][110] zugreifen mit

Code: Alles auswählen

verbrauch = float(response["801"]["170"]["110"])
Das geht aber nicht. Fehlermeldung: "TypeError: 'Response' object is not subscriptable"

Siehe Screenshot. Warum geht das nicht?

Danke + MfG
der hans



Link: https://drive.google.com/file/d/16G2bNS ... sp=sharing
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Du willst auf das Response-Objekt zugreifen, welches gar keine Keys hat. Wandle die Antwort mit .json() um:

Code: Alles auswählen

print(response.json())
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@realHans: `response` ist was anderes als `response.text`. Und auch wenn `response.text` gut aussieht — das ist Text, also eine Zeichenkette.

`requests.request()` ist eher ungewöhnlich weil die verschiedenen HTTP-Methoden eigene Funktionen haben. Also in diesem Fall `requests.post()`.

Bei dem `payload` hätte man sich die \ sparen können, wenn man die gesamte Zeichenkette in ' eingefasst hätte, statt da auch " zu verwenden. Aber ich würde das gar nicht selbst von Hand kodieren, sondern beim Aufruf das `json`-Argument mit einer Datenstruktur verwenden. Dann braucht man auch den Content-Type nicht selbst zu setzen.

Bei `requests`-Antworten ist es immer eine gute Idee darauf zu reagieren ob die überhaupt eine Antwort geliefert haben die OK ist, und nicht eine Seite mit Fehlertext.

Mit Zahlen als Schlüssel wirst Du einen `KeyError` bekommen, denn die Schlüssel in JSON sind grundsätzlich Zeichenketten.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import requests


def main():
    response = requests.post(
        "http://192.168.178.34/getjp",
        json={"801": {"170": None}},
        timeout=None,
    )
    response.raise_for_status()
    print(response.json()["801"]["170"]["110"])


if __name__ == "__main__":
    main()
Edit: Der `float()`-Aufruf macht nicht wirklich Sinn, denn im Gegensatz zu den Schlüsseln sind die Werte in dem gezeigten Ergebnis ja bereits Zahlen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
realHans
User
Beiträge: 2
Registriert: Montag 29. Mai 2023, 18:28

Hallo Tobi und Jack,
response.json() war die Antwort. Danke schön.

Dieses

Code: Alles auswählen

if __name__ == "__main__":
    main()
ist wohl "good practice" ... dann werde ich meine Programme in Zukunft auch so starten.

Dieser Header

Code: Alles auswählen

#!/usr/bin/env python3
vermute ich mal, ist wohl eher für Linux und beschreibt den vorgesehenen Interpreter nehme ich an ... kann wohl nicht Schaden ...

Vielen Dank für den Support, ich habe was gelernt.

MfG
der hans
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Die erste Zeile (Fachbegriff für dieses Muster ist „She-Bang“) ist in der Tat etwas was man unter Unix-Systemen braucht damit das System weiss womit die Datei ausgeführt werden soll. Unter Windows macht man das über die Dateinamensendung die mit einem Programm verknüpft wird. Für Python-Programme kann das eine feste ``python.exe`` sein, aber auch eine ``py.exe`` und letztere schaut auch unter Windows auf die erste Zeile im Skript um zu entscheiden womit die Datei ausgeführt werden soll. Damit man auch unter Windows mehrere Python-Installationen haben kann und nicht alle *.py-Dateien fest mit nur einer davon verknüpft sind. Also macht diese Zeile auch unter Windows Sinn.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten