Bagaimana cara mengirim permintaan POST sebagai JSON?

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

Saya ingin mengirim permintaan POST, tetapi salah satu bidang harus berupa daftar nomor. Bagaimana saya bisa melakukan itu? (JSON?)

TIMEX
sumber
1
Bukankah itu sudah daftar angka?
Waynn Lue
Ini tidak dapat dijawab tanpa mengetahui jenis input yang diharapkan API.
Niklas B.
1
@WaynnLue server API mendapatkan itu sebagai string, bukan daftar.
TIMEX
1
Apakah saya harus menyetel header sebagai "application / json" atau semacamnya?
TIMEX

Jawaban:

154

Jika server Anda mengharapkan permintaan POST menjadi json, maka Anda perlu menambahkan header, dan juga membuat serial data untuk permintaan Anda ...

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


Jika Anda tidak menentukan header, itu akan menjadi application/x-www-form-urlencodedtipe default .

jdi
sumber
Saya punya pertanyaan. apakah mungkin untuk menambahkan beberapa item di header ... seperti tipe konten & client-id ... @jdi
Omar Jandali
@OmarJandali, panggil saja add_header()lagi, untuk setiap header yang ingin Anda tambahkan.
jdi
saya memiliki kode berikut tetapi tidak mencetak apa pun. itu seharusnya untuk mencetak url dan tajuk tetapi tidak ada yang dicetak ... 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 tidak dikenali jadi saya hanya menggunakan urllib. saya juga mendapatkan kesalahan dengan permintaan tersebut. The view tab.views.profileSetup didn't return an HttpResponse object. It returned None instead. @jdi
Omar Jandali
@OmarJandali, harap diingat bahwa jawaban ini awalnya diberikan pada tahun 2012, dengan python 2.x. Anda menggunakan Python3 sehingga impornya akan berbeda. Sekarang akan menjadi import urllib.requestdan urllib.request.Request(). Selain itu, mencetak objek req tidak menarik. Anda dapat dengan jelas melihat header telah ditambahkan dengan mencetak req.headers. Selain itu, saya tidak yakin mengapa ini tidak berfungsi di aplikasi Anda.
jdi
113

Saya merekomendasikan menggunakan requestsmodul yang luar biasa .

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
sumber
Ini memberi sayaTypeError: post() takes from 1 to 2 positional arguments but 3 were given
zakdances
66

untuk python 3.4.2 Saya menemukan yang berikut ini akan berfungsi:

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)
mikrofon emas
sumber
1
Python3.6.2 ini berhasil. Hanya menambahkan header dengan req.add_header (...) yang berhasil untuk saya.
Shalin LK
18

Ini berfungsi sempurna untuk Python 3.5, jika URL berisi nilai String / Parameter Kueri,

URL Permintaan = https://bah2.com/ws/rest/v1/concept/
Nilai parameter = 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)
MAKS
sumber
7
di snipper kode Anda, variabel header tetap tidak digunakan
goyangkan
4

Anda harus menambahkan header, atau Anda akan mendapatkan error http 400. Kode berfungsi dengan baik di python2.6, centos5.4

kode:

    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
sumber
2

Berikut adalah contoh cara menggunakan objek urllib.request dari pustaka standar 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)
Vlad Bezden
sumber
1

Dalam paket permintaan terbaru, Anda dapat menggunakan jsonparameter in requests.post()method untuk mengirim json dict, dan Content-Typeheader in akan disetel ke application/json. Tidak perlu menentukan header secara eksplisit.

import requests

payload = {'key': 'value'}

requests.post(url, json=payload)
jdhao
sumber
Perhatikan bahwa ini akan menghasilkan POSTed json dengan tanda kutip tunggal, yang secara teknis tidak valid.
Yitro
@Jethro Pernahkah Anda mengamati kesalahan saat menggunakan tanda kutip tunggal? Itu valid untuk menggunakan tanda kutip tunggal dengan Python. Secara pribadi, saya belum menemui masalah apa pun tentang ini.
jdhao
Aah maaf saya salah, saya pikir server saya menerima JSON yang dikutip tunggal tetapi ternyata menjadi masalah terpisah dan beberapa debugging yang menyesatkan. Cheers, ini jauh lebih rapi daripada harus menentukan header secara manual!
Yitro
0

Yang ini bekerja dengan baik untuk saya dengan api

import requests

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