отправить запрос с вложенным JSON

php curl to python request

Попытка отправки запросов в API для заказа товаров. Кажется, я не могу понять, как на самом деле отправить json-полезную нагрузку с пост-запросом таким образом, чтобы API получал его правильно.

Сервис предоставляет только php-пример:

PHP-пример:

$params = array();
$params['access_token']             = '123abc';
$params['product_total']            = 2;
$params['product_list'] = array(
array(
'product_id' => 111
),
array(
'product_id' => 222
),
);

И это мой код на Python:

import requests

payload = {
"access_token": "123abc",
"product_total": 2,
"product_list":[
{
"product_id": 111,
...
},
{
"product_id": 222,
...
}]
}

r = requests.post(url, data=payload, verify=False)
r.text
> u'{"code":123,"msg":"product_id is empty"}'

Так что что-то не так с тем, как я отправляю product_list,

Я также попробовал:

import json
r = requests.post(url, data=json.dumps(payload), verify=False)
> u'{"code":456,"msg":"access_token is empty"}'

r = requests.post(url, json=json.dumps(payload), verify=False)
> u'{"code":456,"msg":"access_token is empty"}'

Но чем он не может прочитать access_token больше.

я использую python 2.7.9 а также requests 2.18.4,

Обновить:
Также не удается …

r = requests.post(url, json=payloal, verify=False)
> u'{"code":456,"msg":"access_token is empty"}'

Обновление 2:

Я посмотрел глубже в php-примере, который я получил из документации API, и нашел это:

curl_setopt($this->__ch, CURLOPT_URL, $apiUrl );
curl_setopt($this->__ch, CURLOPT_HEADER, 0);
curl_setopt($this->__ch, CURLOPT_USERAGENT, $_SERVER ['HTTP_USER_AGENT']);
curl_setopt($this->__ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($this->__ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->__ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this->__ch, CURLOPT_POST, 1 );
curl_setopt($this->__ch, CURLOPT_POSTFIELDS, http_build_query($this->__params));

Может быть, кто-то может заметить что-то в этих строках, что мне не хватает

Обновление 3:

Я могу запустить php-пример без проблем и создать порядок таким образом. Но все еще не может сделать это с питоном.

0

Решение

Я нашел решение:

payload = {
"access_token": "123abc",
"product_total": 2,
"product_list[0][product_id]": 111,
"product_list[1][product_id]": 222,
}

r = requests.post(url, data=payload, verify=False)

Как я решил это:

Я перестроил последний пост-запрос, который должна иметь функция python, открыв локальный порт и отправив рабочий php-запрос на этот порт, чтобы увидеть его полезную нагрузку.

(mac terminal)
user$ nc -l localhost 11111 # to open port
POST / HTTP/1.1
Host: localhost:11111
Accept: */*
Content-Length: 115
Content-Type: application/x-www-form-urlencoded

access_token=123abc&product_total=2&product_list%5B0%5D%5Bproduct_id%5D=111&product_list%5B1%5D%5Bproduct_id%5D=22

Просто нужно декодировать полезную нагрузку:

from urllib import parse
parse.unquote("access_token=123abc&product_total=2&product_list%5B0%5D%5Bproduct_id%5D=111&product_list%5B1%5D%5Bproduct_id%5D=22")
'access_token=123abc&product_total=2&product_list[0][product_id]=111&product_list[1][product_id]=22'

Теперь структура полезной нагрузки хорошо видна, и ее нужно просто скопировать для запроса на публикацию Python.

И вот как полезная нагрузка выглядела для моего первоначального почтового запроса на python:

'access_token=123abc&product_total=2&product_list=product_id&product_list=product_id'

Вы можете ясно видеть, почему это не сработало …

Если у кого-то есть объяснение почему почтовый запрос с JSON-полезной нагрузкой не работает — я все еще очень заинтересован в этом. Единственная идея, которую я мог придумать, заключается в том, что API просто не поддерживает json-payload?

1

Другие решения

Исходя из опыта предыдущих подобных вопросов, вы должны попытаться преобразовать свой JSON (ну, собственно, ваш список Python) в product_list в строковое представление того же JSON перед публикацией:

import requests
import json

payload = {
"access_token": "123abc",
"product_total": 2,
"product_list": json.dumps([
{
"product_id": 111,
...
},
{
"product_id": 222,
...
}])
}

r = requests.post(url, data=payload, verify=False)
r.text
0

По вопросам рекламы [email protected]