【问题标题】:Python JSON Iteration into a POST requestPython JSON迭代到POST请求
【发布时间】:2016-05-26 17:48:02
【问题描述】:

我有一个 JSON 文件,其格式类似于

{
   "unknown1": 
   [
        {"text": "random text again",
        "time": "Thu May 15 19:21:59 +0000 2016"}, 
        "text": "akmfkdlm safsa fasffalmfa",
        "time": "Thu May 21 09:53:51 +0000 2016"}
   ]
   "unknown2":
   [ 
        "text": "fsda lmfalmfa",
        "time": "Thu May 21 09:53:51 +0000 2016"},
   ]
}

JSON 中的第一项是随机(未知)标签,可以有任意数量的这些未知数。在这些未知数中总是有一堆text/time 配对。

我正在尝试将每个 text 发送到接受 JSON 格式的 REST 发布服务

text: "foo bar bat",
mime_type: "text/html",
extract_type: "HP" # HP, MP

所以当我尝试运行我的代码但我不知道该怎么做时,我收到了这个错误。

这是我的代码:

import json
import requests

with open('locations_stripped.json') as data_file:
    data = json.load(data_file)

headers = {'Content-Type' : 'application/json'}

for thing in data:
    for text, time in data.iteritems():
        print text
        body = [{ "text": text , "mime_type": "text/html", "extract_type": "HP"}]
        r = requests.post('localhost:3003/api/extract/run', data=body, headers=headers)
        print (r.content)

这是错误:

 $ python filterrest.py
unknown1
Traceback (most recent call last):
  File "filterrest.py", line 30, in <module>
    r = requests.post('localhost:3003/api/extract/run', data=body, headers=headers)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api.py", line 111, in post
return request('post', url, data=data, json=json, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api.py", line 57, in request
return session.request(method=method, url=url, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/sessions.py", line 461, in request
prep = self.prepare_request(req)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/sessions.py", line 394, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/models.py", line 298, in prepare
self.prepare_body(data, files, json)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/models.py", line 452, in prepare_body
body = self._encode_params(data)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/models.py", line 89, in _encode_params
for k, vs in to_key_val_list(data):
ValueError: too many values to unpack

需要注意的一点是它正在打印错误的文本(“unknown1”而不是“再次随机文本”),我不知道如何让它只打印文本。

有什么帮助吗?

更新

根据每个人的回答/评论,我更改了代码

... 
for thing in data:
    for text in data[thing]:
        print text['text']

这会打印出我所期望的 text['text'] 。问题在于我执行请求的方式。我更改了我的代码作为测试并将数据设置为我知道应该工作的东西(我通过Postman 运行它)。

更改代码:

r = requests.post('localhost:3003/api/extract/run', data='Hello. Where does the brown fox go?', headers=headers)

预期响应:

[
  {
    "score": 0.30253747367501777,
    "tag": "HP",
  }
]

相反,打印出来的是看起来像整个 HTML 页面的内容。

【问题讨论】:

  • 你的 Json 格式是假的。看这里"text: "akmfkdlm safsa fasffalmfa"。您的bodylist。必须是dict
  • for thing in data: for text, time in data.iteritems(): 也是假的 ;)
  • 哎呀。我手动输入了 JSON,但它直接来自文件,因此 JSON 绝对有效。将问题编辑为有效!
  • 但就像我写的那样。整数 data=body body 必须是 dict
  • 啊,好吧。这似乎解决了这个问题,但由于某种原因,我的请求在打印时看起来像是整个 HTML 页面而不是响应。

标签: python json rest http-post httprequest


【解决方案1】:

关于您问题的第 1 部分:

for thing in data:
    for text, time in data.iteritems():

使用此循环,您将无法获得text。您的更新:

for thing in data:
    for text in data[thing]:
        print text['text']

是正确的。你的headers 是对的。下一个问题是:

body = [{ "text": text , "mime_type": "text/html", "extract_type": "HP"}]
r = requests.post('localhost:3003/api/extract/run', data=body, headers=headers)

现在查看模块requests的文档:

通常,您希望发送一些表单编码的数据——很像 HTML 形式。为此,只需将字典传递给 data 参数。您的 数据字典将在请求时自动进行表单编码 制作完成

有很多次你想要发送的数据不是 形式编码。如果您传入一个字符串而不是一个字典,则该数据 将直接发布。

对于关键字参数data,您必须提供dict 或有效的json str。您在问题中的变量body 直到list 并且在您的更新中是无效的json str。有两种解决方案:

body = { "text": text , "mime_type": "text/html", "extract_type": "HP"}
# Dont't forget: dict will be used to send form-encoded data
# It will work. But not a intended solution for json data
r = requests.post('localhost:3003/api/extract/run', data=body, headers=headers)

或者

import json
body = { "text": text , "mime_type": "text/html", "extract_type": "HP"}
r = requests.post('localhost:3003/api/extract/run', data=json.dumps(body), headers=headers)

但是 requests 文档说:

不用自己编码dict,也可以直接传 使用 json 参数(在 2.4.2 版本中添加),它将是 自动编码

所以从2.4.2版本开始最好使用关键字参数json而不是data来发送json数据。所以这是最好的解决方案:

body = { "text": text , "mime_type": "text/html", "extract_type": "HP"} 
r = requests.post('localhost:3003/api/extract/run', json=body, headers=headers)

总结

我使用这个来源:

{
   "unknown1": 
   [
        {"text": "random text again",
        "time": "Thu May 15 19:21:59 +0000 2016"}, 
        "text": "akmfkdlm safsa fasffalmfa",
        "time": "Thu May 21 09:53:51 +0000 2016"}
   ],
   "unknown2":
   [ 
        "text": "fsda lmfalmfa",
        "time": "Thu May 21 09:53:51 +0000 2016"},
   ]
}

代码:

import json
import requests

with open('locations_stripped.json') as data_file:
    data = json.load(data_file)

headers = {'Content-Type' : 'application/json'}

for list_values in data.values():
    for dict_element in list_values:
        text = dict_element['text']
        print text
        body = { "text": text , "mime_type": "text/html", "extract_type": "HP"}
        r = requests.post('localhost:3003/api/extract/run', json=body, headers=headers)
        print (r.content)

P/S:我不知道你的服务器,所以我无法测试它。我希望它有效。

【讨论】:

    【解决方案2】:

    假设你有一个有效的 json。您首先需要遍历与“未知”键对应的列表,现在该列表再次包含字典 带有texttime 键。

    for unknown_key in data:
        for obj in data[unknown_key]:
             body = { "text": obj['text'] , "mime_type": "text/html", "extract_type": "HP"}
             r = requests.post('localhost:3003/api/extract/run', data=body, headers=headers)
             print (r.content)
    

    【讨论】:

    • 当我尝试将我的代码更改为您的for thing in data: for text, time in data.iteritems(): print text 时,我可以告诉我这可以通过输入正确的text 来纠正我的问题,但看起来我的问题出在其他地方。我已经用信息更新了我的问题
    • 您在请求中发送 text 数据,而在您的标头中有 'Content-Type' : 'application/json'
    • 文本数据?我将 Content-Type 设置为 JSON,因为它需要 JSON。
    • '你好。棕狐去哪儿了?这不是 json
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 2022-07-27
    • 2020-03-06
    • 1970-01-01
    • 2017-05-08
    • 2022-01-22
    相关资源
    最近更新 更多