python json 编码 - 丢失 ( 和 ' - urllib2.open() 结果返回 HTTP 错误 400
我正在把一个40kb的字典(里面有字典和列表)编码成json格式,然后通过http发送到一个nosql数据库。我用过jsonpickle.encode和json.dumps这两个模块来编码我的字典内容,但都导致了http错误。我尝试手动用CURL命令来处理出问题的代码部分,结果出现了错误“-bash: syntax error near unexpected token `('”。
下面是一些示例代码:
import urllib2 , jsonpickle
url = "http://amazonaws.com/server/%s/_create" % item
data = jsonpickle.encode( some_dict_of_dicts_and_lists ) # also tried json.dumps here.
try:
req = urllib2.Request ( url , data , { 'Content-Type' : 'application/json' } )
f = urllib2.urlopen ( req )
except Exception as e:
print "Error: %s" %e
上面的代码在把我的字典的某些部分放入nosql数据库时是有效的。然而,当我发送字典的其他部分时,它却打印出“错误:HTTP错误400:错误的请求”。这对我来说意味着数据变量/字符串中的某些内容没有正确编码。为了获取CURL对这个问题的响应,我尝试了以下代码:
item_id = item_dictionary [ 'id' ]
data = jsonpickle.encode( some_dict_of_dicts_and_lists ) # also tried json.dumps here.
command = 'curl -XPOST "http://amazonaws.com/server/%s/_create" -d '"%s"' % ( nsn_id , data )
os.system(command)
这产生了错误“sh: -c: line 0: syntax error near unexpected token `('”。
如果我尝试手动在命令行中输入curl命令,我会得到以下一系列错误:
curl: (6) 无法解析主机:material;未提供节点名或服务名,或未知
curl: (6) 无法解析主机:items;未提供节点名或服务名,或未知
curl: (6) 无法解析主机:of;未提供节点名或服务名,或未知
curl: (3) [globbing] 在位置146处未匹配的闭合大括号/方括号
{"error":"MapperParsingException[解析失败]; nested: JsonParseException[在VALUE_STRING中遇到意外的输入结束\n at [Source: [B@2ff246ab; line: 1, column: 6519]]; ","status":400}
所以:
1) 有没有更好的方法确保json编码过程能正确处理所有的括号和单引号,在它们前面加上一个反斜杠('\')?我应该对它们进行替换吗?
2) 有没有好的方法使用urllib2更详细地找出这个错误的原因,还是我需要从命令行使用CURL才能得到bash类型的错误?
1 个回答
来回答你的两个问题:
1) json.dumps
- 如果你传入的是有效的数据,它总是会生成一个表示有效JSON对象的字符串。如果你传入无效的数据,它就会抛出一个异常。Python的json
模块非常常用,如果有bug导致它输出格式不正确的JSON字典,那早就被大家发现并修复了。
2) 你收到HTTP错误是因为网页服务器对你的请求返回了一个状态码为400的页面。这个状态码表示请求有问题。页面里可能还有其他内容,urllib2
并没有把这些内容丢掉。你可以调用HTTPError的.read()
方法来获取页面上的内容,而不仅仅是看到状态码(有时候光看状态码是无法理解你哪里出错的)。
大多数网络API在返回400 - Bad Request
错误时,会给你一些有用的解释,比如告诉你在请求中缺少了哪个参数。在你的异常处理代码里加上print e.read()
,你就能看到这些信息,可能会帮助你解决当前的问题。