urllib2和json


71

谁能指出一个教程,向我展示如何使用urllib2和JSON格式的数据进行POST请求?

Answers:


136

仅当服务器无需检查内容类型标头时,Messa的答案才有效。如果您希望它真正起作用,则需要指定一个内容类型标题。这是Messa的答案,修改后包含了内容类型标题:

import json
import urllib2
data = json.dumps([1, 2, 3])
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()

3
使用python3和urllib时,此外,我还必须对json解析的数据进行编码才能使其正常工作data = json.dumps([1, 2, 3]).encode("utf8)。参见stackoverflow.com/a/5441022/3757139
塞缪尔(Samuel)

应该data = urllib.parse.urlencode(data) 还可以应用?
汉斯·金泽尔

对json有效负载进行urlencoding对于这样的post请求来说是不正常的,其中json对象将进入post主体中。如果将json数据放入url的查询字符串中,则需要对其进行编码。但是,对json字符串进行urlencoding并不是urlencode设计的目的。关于您如何或为什么问这个问题,似乎有些怪异,您可能想发起一个新帖子,然后更全面地问您的问题
Bob Van Zant

38

不管urllib用于弄清楚Content-Length的内容是什么,都会被json弄糊涂,所以您必须自己计算。

import json
import urllib2
data = json.dumps([1, 2, 3])
clen = len(data)
req = urllib2.Request(url, data, {'Content-Type': 'application/json', 'Content-Length': clen})
f = urllib2.urlopen(req)
response = f.read()
f.close()

永远请我解决这个问题,因此希望对其他人有所帮助。


2
非常感谢veeery!5年后,这仍然是坏!
GuyMatz '16

1
我可以验证至少在旧版Python(尤其是2.6)中,除非您按照此答案设置Content-Length,否则所有内容都将无效!
Wingware '17

17

示例-将一些编码为JSON的数据作为POST数据发送:

import json
import urllib2
data = json.dumps([1, 2, 3])
f = urllib2.urlopen(url, data)
response = f.read()
f.close()

3
对于许多系统,这将不起作用。请参阅下面的Bob Van Zant的答案。
Speedplane

5

要读取json响应,请使用json.loads()。这是示例。

import json
import urllib
import urllib2

post_params = {
    'foo' : bar
}

params = urllib.urlencode(post_params)
response = urllib2.urlopen(url, params)
json_response = json.loads(response.read())

3
这不会发送JSON,而只会接收它。
tsturzl

3

您当然想破解标头以拥有适当的Ajax请求:

headers = {'X_REQUESTED_WITH' :'XMLHttpRequest',
           'ACCEPT': 'application/json, text/javascript, */*; q=0.01',}
request = urllib2.Request(path, data, headers)
response = urllib2.urlopen(request).read()

并json.load在服务器端的POST。

编辑:顺便说一句,您必须urllib.urlencode(mydata_dict)在发送它们之前。如果您不这样做,则POST不会是服务器所期望的


urlencode将发送以url格式而不是json编码的数据。
kolinko

2

这对我有用:

import json
import requests
url = 'http://xxx.com'
payload = {'param': '1', 'data': '2', 'field': '4'}
headers = {'content-type': 'application/json'}
r = requests.post(url, data = json.dumps(payload), headers = headers)

7
我认为请求包不是标准库的一部分。
桑达纳

尽管'requests'包​​不是标准库的一部分,但可以使用pip轻松安装。非常适合在虚拟环境中工作的人员。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.