Jak wysłać żądanie POST jako JSON?

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

Chcę wysłać żądanie POST, ale jedno z pól powinno być listą liczb. Jak mogę to zrobić ? (JSON?)

TIMEX
źródło
1
Czy to nie jest już lista liczb?
Waynn Lue
Nie można odpowiedzieć na to pytanie, nie wiedząc, jakiego rodzaju danych wejściowych oczekuje interfejs API.
Niklas B.
1
@WaynnLue serwer API pobiera to jako ciąg znaków, a nie listę.
TIMEX
1
Czy muszę ustawić nagłówki jako „application / json” czy coś takiego?
TIMEX

Odpowiedzi:

154

Jeśli twój serwer oczekuje, że żądanie POST będzie json, musisz dodać nagłówek, a także serializować dane dla żądania ...

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


Jeśli nie określisz nagłówka, będzie to application/x-www-form-urlencodedtyp domyślny .

jdi
źródło
Mam pytanie. czy możliwe jest dodanie wielu elementów w nagłówku ... takich jak typ treści i identyfikator klienta ... @jdi
Omar Jandali
@OmarJandali, po prostu zadzwoń add_header()ponownie, dla każdego nagłówka, który chcesz dodać.
jdi,
Mam następujący kod, ale nic nie drukuje. miał wydrukować adres URL i nagłówki, ale nic nie zostało wydrukowane ... 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 nie zostało rozpoznane, więc właśnie użyłem urllib. Otrzymuję również błąd dotyczący żądania. The view tab.views.profileSetup didn't return an HttpResponse object. It returned None instead. @jdi
Omar Jandali
@OmarJandali, pamiętaj, że ta odpowiedź została pierwotnie udzielona w 2012 roku pod pythonem 2.x. Używasz Python3, więc import będzie inny. Teraz będzie import urllib.requesti urllib.request.Request(). Ponadto wydrukowanie obiektu req nie robi nic interesującego. Możesz wyraźnie zobaczyć, że nagłówki zostały dodane przez drukowanie req.headers. Poza tym nie jestem pewien, dlaczego nie działa w Twojej aplikacji.
jdi,
114

Polecam skorzystanie z niesamowitego requestsmodułu.

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
źródło
To daje miTypeError: post() takes from 1 to 2 positional arguments but 3 were given
zakdances
66

dla pythona 3.4.2 stwierdziłem, że będzie działać:

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))
response = urllib.request.urlopen(req, jsondataasbytes)
mike gold
źródło
1
Python3.6.2 to zadziałało. U mnie zadziałało tylko dodanie nagłówka z req.add_header (...).
Shalin LK
18

Działa to idealnie w przypadku Python 3.5, gdy adres URL zawiera ciąg zapytania / wartość parametru,

URL żądania = https://bah2.com/ws/rest/v1/concept/
Wartość parametru = 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
źródło
7
we fragmencie kodu zmienna nagłówków pozostaje nieużywana
shookees
4

Musisz dodać nagłówek lub otrzymasz błąd http 400. Kod działa dobrze na python2.6, centos5.4

kod:

    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
źródło
2

Oto przykład użycia obiektu urllib.request ze standardowej biblioteki Pythona.

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
źródło
1

W najnowszym pakiecie żądań możesz użyć jsonparametru w requests.post()metodzie, aby wysłać dict json, a Content-Typenagłówek in zostanie ustawiony na application/json. Nie ma potrzeby jawnego określania nagłówka.

import requests

payload = {'key': 'value'}

requests.post(url, json=payload)
jdhao
źródło
Zauważ, że spowoduje to POSTed json z pojedynczymi cudzysłowami, co jest technicznie nieprawidłowe.
Jethro
@Jethro Czy zauważyłeś błędy podczas używania apostrofów? W Pythonie można używać pojedynczych cudzysłowów. Osobiście nie napotkałem żadnych problemów z tym związanych.
jdhao
Ach przepraszam, pomyliłem się, myślałem, że mój serwer otrzymuje pojedyncze cudzysłowy JSON, ale okazało się, że to osobny problem i pewne wprowadzające w błąd debugowanie. Pozdrawiam, to znacznie prostsze rozwiązanie niż ręczne określanie nagłówka!
Jethro
0

Ten działa dobrze dla mnie z apis

import requests

data={'Id':id ,'name': name}
r = requests.post( url = 'https://apiurllink', data = data)
Sudhir G
źródło