Как отправить запрос POST в формате JSON?


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

Я хочу отправить запрос POST, но в одном из полей должен быть список чисел. Как я могу это сделать ? (JSON?)


1
Но разве это не список чисел?
Waynn Lue

На этот вопрос нельзя ответить, не зная, какой ввод ожидает API.
Никлас Б.

1
@WaynnLue сервер API получает это как строку, а не список.
TIMEX

1
Должен ли я установить заголовки как «application / json» или что-то в этом роде?
TIMEX

Ответы:


154

Если ваш сервер ожидает, что запрос POST будет json, вам нужно будет добавить заголовок, а также сериализовать данные для вашего запроса ...

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


Если вы не укажете заголовок, это будет application/x-www-form-urlencodedтип по умолчанию .


У меня есть вопрос. можно ли добавить несколько элементов в заголовок ... например, тип контента и идентификатор клиента ... @jdi
Омар Джандали

@OmarJandali, просто позвоните еще add_header()раз для каждого заголовка, который хотите добавить.
jdi 05

У меня есть следующий код, но он ничего не печатает. предполагалось напечатать URL-адрес и заголовки, но ничего не было напечатано ... 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)...
Омар Джандали

urllib2 не был распознан, поэтому я просто использовал urllib. Я также получаю сообщение об ошибке с запросом. The view tab.views.profileSetup didn't return an HttpResponse object. It returned None instead. @jdi
Омар Джандали

@OmarJandali, имейте в виду, что этот ответ был первоначально дан в 2012 году под python 2.x. Вы используете Python3, поэтому импорт будет другим. Было бы сейчас import urllib.requestи urllib.request.Request(). Кроме того, печать объекта req ничего интересного не делает. Вы можете ясно видеть, что заголовки были добавлены при печати req.headers. Кроме того, я не понимаю, почему это не работает в вашем приложении.
jdi 05

114

Рекомендую использовать невероятный requestsмодуль.

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)

Это дает мнеTypeError: post() takes from 1 to 2 positional arguments but 3 were given
zakdances

66

для python 3.4.2 я обнаружил, что будет работать следующее:

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)

1
Python3.6.2 это сработало. У меня работало только добавление заголовка с req.add_header (...).
Шалин Л.К.

18

Это идеально подходит Python 3.5, если URL-адрес содержит значение строки запроса / параметра,

URL запроса = https://bah2.com/ws/rest/v1/concept/
Значение параметра = 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
в вашем фрагменте кода переменная заголовков остается неиспользованной
потрясает

4

Вам нужно добавить заголовок, иначе вы получите ошибку http 400. Код хорошо работает на python2.6, centos5.4

код:

    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

Вот пример того, как использовать объект urllib.request из стандартной библиотеки 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

В пакете последних запросов вы можете использовать jsonпараметр в requests.post()методе для отправки json dict, а для Content-Typeзаголовка in будет установлено значение application/json. Нет необходимости явно указывать заголовок.

import requests

payload = {'key': 'value'}

requests.post(url, json=payload)

Обратите внимание, что это приведет к POSTed json с одинарными кавычками, что технически недействительно.
Джетро,

@Jethro Наблюдали ли вы ошибки при использовании одинарных кавычек? В Python допустимо использовать одинарные кавычки. Лично я не встречал никаких проблем по этому поводу.
jdhao

Извините, я ошибся, я думал, что мой сервер получает JSON в одинарных кавычках, но оказалось, что это отдельная проблема и некоторая вводящая в заблуждение отладка. Ура, это намного аккуратнее, чем указывать заголовок вручную!
Джетро,

0

Это отлично работает для меня с apis

import requests

data={'Id':id ,'name': name}
r = requests.post( url = 'https://apiurllink', data = data)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.