Como envio uma solicitação POST como JSON?


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

Quero enviar uma solicitação POST, mas um dos campos deve ser uma lista de números. Como eu posso fazer isso ? (JSON?)


1
Mas já não é uma lista de números?
Waynn Lue

Isso não pode ser respondido sem saber que tipo de entrada a API espera.
Niklas B.

1
@WaynnLue o servidor API está recebendo isso como uma string, não uma lista.
TIMEX

1
Devo definir cabeçalhos como "application / json" ou algo assim?
TIMEX

Respostas:


154

Se o seu servidor espera que a solicitação POST seja json, você precisará adicionar um cabeçalho e também serializar os dados para sua solicitação ...

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


Se você não especificar o cabeçalho, ele será o application/x-www-form-urlencodedtipo padrão .


Eu tenho uma pergunta. é possível adicionar vários itens no cabeçalho ... como tipo de conteúdo e id do cliente ... @jdi
Omar Jandali

@OmarJandali, basta chamar add_header()novamente, para cada cabeçalho que você deseja adicionar.
jdi

eu tenho o seguinte codificado, mas não está imprimindo nada. era para imprimir o url e os cabeçalhos, mas nada foi impresso ... 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

O urllib2 não foi reconhecido, então usei apenas o urllib. Também estou recebendo um erro com a solicitação. The view tab.views.profileSetup didn't return an HttpResponse object. It returned None instead. @jdi
Omar Jandali

@OmarJandali, lembre-se de que esta resposta foi dada originalmente em 2012, em python 2.x. Você está usando Python3, então as importações serão diferentes. Agora seria import urllib.requeste urllib.request.Request(). Além disso, imprimir o objeto req não faz nada de interessante. Você pode ver claramente que os cabeçalhos foram adicionados ao imprimir req.headers. Além disso, não tenho certeza por que não está funcionando em seu aplicativo.
jdi


66

para python 3.4.2 descobri que o seguinte funcionará:

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)

1
Python3.6.2 isso funcionou. Apenas adicionar cabeçalho com req.add_header (...) funcionou para mim.
Shalin LK

18

Isso funciona perfeitamente para Python 3.5, se o URL contiver valor de string / parâmetro de consulta,

URL de solicitação = https://bah2.com/ws/rest/v1/concept/
Valor do parâmetro = 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)

7
em seu snipper de código, a variável headers permanece sem uso
atira em

4

Você precisa adicionar o cabeçalho ou obterá o erro http 400. O código funciona bem em python2.6, centos5.4

código:

    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)

2

Aqui está um exemplo de como usar o objeto urllib.request da biblioteca padrão do Python.

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)

1

No último pacote de solicitações, você pode usar o jsonparâmetro no requests.post()método para enviar um dict json, e o Content-Typecabeçalho in será definido como application/json. Não há necessidade de especificar o cabeçalho explicitamente.

import requests

payload = {'key': 'value'}

requests.post(url, json=payload)

Observe que isso resultará em JSON POSTADO com aspas simples, o que é tecnicamente inválido.
Jethro

@Jethro Você observou erros ao usar aspas simples? É válido usar aspas simples em Python. Pessoalmente, não encontrei nenhum problema em relação a isso.
jdhao

Aah desculpas, eu estava enganado, pensei que meu servidor estava recebendo JSON com aspas simples, mas acabou sendo um problema separado e alguma depuração enganosa. Saudações, isso é muito mais organizado do que especificar o cabeçalho manualmente!
Jethro

0

Este funciona bem para mim com apis

import requests

data={'Id':id ,'name': name}
r = requests.post( url = 'https://apiurllink', data = data)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.