JSON olarak bir POST isteğini nasıl gönderirim?


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

Bir POST isteği göndermek istiyorum, ancak alanlardan biri numara listesi olmalıdır. Bunu nasıl yapabilirim ? (JSON?)


1
Yine de bu zaten bir sayı listesi değil mi?
Waynn Lue

Bu, API'nin ne tür bir girdi beklediğini bilmeden cevaplanamaz.
Niklas B.

1
@WaynnLue API sunucusu bunu bir liste olarak değil bir dizge olarak alıyor.
TIMEX

1
Başlıkları "application / json" veya başka bir şey olarak ayarlamam gerekiyor mu?
TIMEX

Yanıtlar:


154

Sunucunuz POST isteğinin json olmasını bekliyorsa, bir başlık eklemeniz ve ayrıca isteğiniz için verileri serileştirmeniz gerekir ...

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


Başlığı belirtmezseniz, varsayılan application/x-www-form-urlencodedtür olacaktır.


Bir sorum var. üstbilgiye birden çok öğe eklemek mümkün mü ... içerik türü ve istemci kimliği gibi ... @jdi
Omar Jandali

@OmarJandali, add_header()eklemek istediğiniz her başlık için tekrar arayın .
jdi

Aşağıdaki kodu aldım ama hiçbir şey yazdırmıyor. url ve başlıkları yazdırması gerekiyordu ama hiçbir şey yazdırılmadı ... 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 tanınmadı, bu yüzden sadece urllib kullandım. Ayrıca istekle ilgili bir hata alıyorum. The view tab.views.profileSetup didn't return an HttpResponse object. It returned None instead. @jdi
Omar Jandali

@OmarJandali, lütfen bu cevabın ilk olarak 2012'de python 2.x altında verildiğini unutmayın. Python3 kullanıyorsunuz, bu nedenle içe aktarmalar farklı olacak. Şimdi olacak import urllib.requestve urllib.request.Request(). Ayrıca, gerekli nesneyi yazdırmak ilginç bir şey yapmaz. Başlıkların yazdırılarak eklendiğini açıkça görebilirsiniz req.headers. Bunun ötesinde, başvurunuzda neden çalışmadığından emin değilim.
jdi


66

python 3.4.2 için aşağıdakilerin işe yarayacağını buldum:

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 bu işe yaradı. Sadece req.add_header (...) ile başlık eklemek benim için çalıştı.
Shalin LK

18

Bu şunun için mükemmel çalışıyor Python 3.5 URL Sorgu Dizi / Parametre değerini içeriyorsa,

İstek URL'si = https://bah2.com/ws/rest/v1/concept/
Parametre değeri = 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)


4

Başlık eklemelisiniz, yoksa http 400 hatası alırsınız. Kod python2.6, centos5.4'te iyi çalışıyor

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)

2

Python standart kitaplığından urllib.request nesnesinin nasıl kullanılacağına dair bir örnek aşağıda verilmiştir.

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

En son istek paketinde, bir json dict göndermek için jsonparameter in requests.post()method kullanabilirsiniz ve Content-Typein başlığı olarak ayarlanacaktır application/json. Başlığın açıkça belirtilmesine gerek yoktur.

import requests

payload = {'key': 'value'}

requests.post(url, json=payload)

Bunun teknik olarak geçersiz olan tek tırnaklarla POSTed json ile sonuçlanacağını unutmayın.
Jethro

@Jethro Tek tırnak işareti kullanırken hata gözlemlediniz mi? Python'da tek tırnak kullanmak geçerlidir. Şahsen, bununla ilgili herhangi bir sorunla karşılaşmadım.
jdhao

Aah, yanıldığım için özür dilerim, sunucumun tek tırnaklı JSON aldığını düşündüm ancak ayrı bir sorun ve bazı yanıltıcı hata ayıklama olduğu ortaya çıktı. Şerefe, bu, başlığı manuel olarak belirtmek zorunda kalmaktan çok daha düzenli!
Jethro

0

Bu benim için apis ile iyi çalışıyor

import requests

data={'Id':id ,'name': name}
r = requests.post( url = 'https://apiurllink', data = data)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.