Wie sende ich eine POST-Anfrage als JSON?

105
data = {
        'ids': [12, 3, 4, 5, 6 , ...]
    }
    urllib2.urlopen("http://abc.com/api/posts/create",urllib.urlencode(data))

Ich möchte eine POST-Anfrage senden, aber eines der Felder sollte eine Liste von Nummern sein. Wie kann ich das machen ? (JSON?)

TIMEX
quelle
1
Ist das nicht schon eine Liste von Zahlen?
Waynn Lue
Dies kann nicht beantwortet werden, ohne zu wissen, welche Art von Eingabe die API erwartet.
Niklas B.
1
@WaynnLue Der API-Server erhält das als Zeichenfolge, nicht als Liste.
TIMEX
1
Muss ich Header als "application / json" oder so setzen?
TIMEX

Antworten:

153

Wenn Ihr Server erwartet, dass die POST-Anforderung json ist, müssen Sie einen Header hinzufügen und die Daten für Ihre Anforderung serialisieren ...

Python 2.x.

import json
import urllib2

data = {
        'ids': [12, 3, 4, 5, 6]
}

req = urllib2.Request('http://example.com/api/posts/create')
req.add_header('Content-Type', 'application/json')

response = urllib2.urlopen(req, json.dumps(data))

Python 3.x.

https://stackoverflow.com/a/26876308/496445


Wenn Sie den Header nicht angeben, ist dies der Standardtyp application/x-www-form-urlencoded.

jdi
quelle
Ich habe eine Frage. ist es möglich, mehrere Elemente in der Kopfzeile hinzuzufügen ... wie Inhaltstyp & Client-ID ... @jdi
Omar Jandali
@OmarJandali, rufen add_header()Sie einfach erneut an, für jeden Header, den Sie hinzufügen möchten.
JDI
Ich habe die folgenden codiert, aber es druckt nichts. Es sollte die URL und die Überschriften drucken, aber es wurde nichts gedruckt ... req = urllib.Request('http://uat-api.synapsefi.com') req.add_header('X-SP-GATEWAY', 'client_id_asdfeavea561va9685e1gre5ara|client_secret_4651av5sa1edgvawegv1a6we1v5a6s51gv') req.add_header('X-SP-USER-IP', '127.0.0.1') req.add_header('X-SP-USER', '| ge85a41v8e16v1a618gea164g65') req.add_header('Content-Type', 'application/json') print(req)...
Omar Jandali
urllib2 wurde nicht erkannt, also habe ich nur urllib verwendet. Ich erhalte auch eine Fehlermeldung mit der Anfrage. The view tab.views.profileSetup didn't return an HttpResponse object. It returned None instead. @jdi
Omar Jandali
@OmarJandali, bitte denken Sie daran, dass diese Antwort ursprünglich im Jahr 2012 unter Python 2.x gegeben wurde. Sie verwenden Python3, sodass die Importe unterschiedlich sind. Es wäre jetzt import urllib.requestund urllib.request.Request(). Darüber hinaus ist das Drucken des req-Objekts nicht interessant. Sie können deutlich sehen, dass die Überschriften durch Drucken hinzugefügt wurden req.headers. Darüber hinaus bin ich mir nicht sicher, warum es in Ihrer Anwendung nicht funktioniert.
JDI
113

Ich empfehle das unglaubliche requestsModul.

http://docs.python-requests.org/en/v0.10.7/user/quickstart/#custom-headers

url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}

response = requests.post(url, data=json.dumps(payload), headers=headers)
FogleBird
quelle
Dies gibt mirTypeError: post() takes from 1 to 2 positional arguments but 3 were given
zakdances
66

Für Python 3.4.2 habe ich festgestellt, dass Folgendes funktioniert:

import urllib.request
import json      

body = {'ids': [12, 14, 50]}  

myurl = "http://www.testmycode.com"
req = urllib.request.Request(myurl)
req.add_header('Content-Type', 'application/json; charset=utf-8')
jsondata = json.dumps(body)
jsondataasbytes = jsondata.encode('utf-8')   # needs to be bytes
req.add_header('Content-Length', len(jsondataasbytes))
print (jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
Mike Gold
quelle
1
Python3.6.2 das hat funktioniert. Nur das Hinzufügen eines Headers mit req.add_header (...) hat bei mir funktioniert.
Shalin LK
18

Dies funktioniert perfekt Python 3.5, wenn die URL den Wert "Abfragezeichenfolge / Parameter" enthält.

Anforderungs-URL = https://bah2.com/ws/rest/v1/concept/
Parameterwert = 21f6bb43-98a1-419d-8f0c-8133669e40ca

import requests

url = 'https://bahbah2.com/ws/rest/v1/concept/21f6bb43-98a1-419d-8f0c-8133669e40ca'
data = {"name": "Value"}
r = requests.post(url, auth=('username', 'password'), verify=False, json=data)
print(r.status_code)
MAX
quelle
7
In Ihrem Code-Snipper bleibt die Header-Variable unbenutzt
Shookees
4

Sie müssen einen Header hinzufügen, sonst wird der Fehler http 400 angezeigt. Der Code funktioniert gut unter Python2.6, Centos5.4

Code:

    import urllib2,json

    url = 'http://www.google.com/someservice'
    postdata = {'key':'value'}

    req = urllib2.Request(url)
    req.add_header('Content-Type','application/json')
    data = json.dumps(postdata)

    response = urllib2.urlopen(req,data)
YuanYe
quelle
2

Hier ist ein Beispiel für die Verwendung des Objekts urllib.request aus der Python-Standardbibliothek.

import urllib.request
import json
from pprint import pprint

url = "https://app.close.com/hackwithus/3d63efa04a08a9e0/"

values = {
    "first_name": "Vlad",
    "last_name": "Bezden",
    "urls": [
        "https://twitter.com/VladBezden",
        "https://github.com/vlad-bezden",
    ],
}


headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
}

data = json.dumps(values).encode("utf-8")
pprint(data)

try:
    req = urllib.request.Request(url, data, headers)
    with urllib.request.urlopen(req) as f:
        res = f.read()
    pprint(res.decode())
except Exception as e:
    pprint(e)
Vlad Bezden
quelle
1

Im Paket mit den letzten Anforderungen können Sie den jsonParameter in requests.post()method verwenden, um ein JSON-Diktat zu senden, und der Content-TypeIn-Header wird auf gesetzt application/json. Es ist nicht erforderlich, den Header explizit anzugeben.

import requests

payload = {'key': 'value'}

requests.post(url, json=payload)
jdhao
quelle
Beachten Sie, dass dies zu POSTed json mit einfachen Anführungszeichen führt, was technisch ungültig ist.
Jethro
@Jethro Haben Sie Fehler bei der Verwendung von einfachen Anführungszeichen beobachtet? Es ist gültig, in Python einfache Anführungszeichen zu verwenden. Persönlich habe ich diesbezüglich keine Probleme festgestellt.
jdhao
Aah entschuldigt, ich habe mich geirrt, ich dachte, mein Server empfängt JSON in einfachen Anführungszeichen, aber es stellte sich heraus, dass es sich um ein separates Problem und ein irreführendes Debugging handelte. Prost, das ist viel aufgeräumter, als den Header manuell angeben zu müssen!
Jethro
0

Dieser funktioniert gut für mich mit Apis

import requests

data={'Id':id ,'name': name}
r = requests.post( url = 'https://apiurllink', data = data)
Sudhir G.
quelle