【问题标题】:Parse of HTTP response to JSON data解析对 JSON 数据的 HTTP 响应
【发布时间】:2018-06-11 17:58:13
【问题描述】:

抱歉这个菜鸟问题,但需要帮助解析我在发布请求后收到的 HTTP 响应。

有例子:

import requests
import json
import base64
url = 'someURL'
if __name__=='__main__':
    data = '{"requests":"data"}'
    r = requests.post(url, data)
    print(r.content)
    print(r.encoding)

我正在接收下一个:

b'{"results":[{"hits":[{"aliases":["Defence of the Ancients 2","远古防卫2","\xe0\xbc\xbc\xe3\x81\xa4 \xe2\x97\x95_\xe2\x97\x95 \xe0\xbc\xbd\xe3\x81\xa4"],"localizations":{},"name":"Dota 2","popularity":36184,"objectID":"29595","highlightResult":{"aliases":[{"value":"Defence 古人的 2","matchLevel":"none","matchedWords":[]},{"value":"防御 古人 2","matchLevel":"none","matchedWords":[]},{"value":"\xe0\xbc\xbc \xe3\x81\xa4 \xe2\x97\x95\xe2\x97\x95 \xe0\xbc\xbd\xe3\x81\xa4","matchLevel":"none","matchedWords":[]}],"name":{"value":"Dota 2","matchLevel":"full","fullyHighlighted":false,"matchedWords":["dota"]}}},{"aliases":["暴雪 All-Stars","Blizzard DOTA","HOTS"],"localizations":{},"name":"Heroes 的 Storm","popularity":27143,"objectID":"32959","_highlightResult":{"aliases":[{"value":"暴雪 All-Stars","matchLevel":"none","matchedWords":[]},{"value":"暴雪 DOTA","matchLevel":"full","fullyHighlighted":false,"matchedWords":["dota"]},{"value":"HOTS","matchLevel":"none ","matchedWords":[]}],"name":{"value":"英雄 的 Storm","matchLevel":"none","matchedWords":[]}}},{"aliases":[],"localizations":{},"name":"Fujiko F.不二雄人物大树狗!顺丰堂畑 派对!!","人气":0,"objectID":"490150","_highlightResult":{"name":{"value":"Fujiko F.不二雄人物大树狗! SF Dotabata 派对!!","matchLevel":"full","fullyHighlighted":false,"matchedWords":["dota"]}}},{"aliases":[],"localizations":{},"name" :"\xe5\x88\x80\xe5\xa1\x94\xe5\x82\xb3\xe5\xa5\x87 刀塔 图例","人气":0,"objectID":"488497","_highlightResult":{"name":{"value":"\xe5\x88\x80\xe5\xa1\x94\xe5\x82\xb3 \xe5\xa5\x87 刀塔 图例","matchLevel":"full","fullyHighlighted":false,"matchedWords":["dota"]}}}],"nbHits":4,"page":0,"nbPages":1," hitsPerPage":1000,"processingTimeMS":1,"facets":{},"exhaustiveFacetsCount":true,"exhaustiveNbHits":true,"query":"dota","params":"query=dota&page=0&hitsPerPage=99999&numericFilters =%5B%5D&facets=*&facetFilters=","index":"game"}]}\n'

UTF-8

但是我如何尝试编码、格式化它仍然有不同的问题。请帮忙,这个reqeust如何得到有效的json?

有我的坏例子:

print(j.json())
Traceback (most recent call last):
  File "./get_games.py", line 14, in <module>
    print(r.json())
UnicodeEncodeError: 'ascii' codec can't encode character '\u0f3c' in position 95: ordinal not in range(128)

或者这个:

json.loads(str(r.content)[1:])
Traceback (most recent call last):
  File "./get_games.py", line 17, in <module>
    a = json.loads(str(r.content)[1:])
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

谢谢

【问题讨论】:

  • 您永远不应该尝试将字节转换为字符串,方法是取它的str,然后从开头剪掉b。一方面,你最后还有'。更重要的是,不是实际解码字节,而是解码这些字节的反斜杠转义表示,这是无用的。如果你想把特定编码中的bytes变成str,只需调用decode就可以了。
  • 换句话说:r.content.decode(r.encoding)。但这应该给你和r.text 一样的东西,所以没什么意义。加。 r.json 应该已经为你做到了;你的问题似乎是你在其他东西上调用它j,它可能以某种方式包装了一些东西,阻止你在页面上使用编码,因此默认为 ASCII。
  • 最后,由于这是 UTF-8,您应该能够只使用 json.loads(r.content) 加载编码字节,甚至无需尝试对其进行解码。
  • 不幸的是,这些变体中的任何一个都无效:(我也尝试过这些变体,但一直都有编码错误“UnicodeEncodeError:'ascii'编解码器无法在位置95编码字符'\u0f3c' : 序数不在范围内(128)"
  • 好吧,您在问题中给出的示例中没有出现该错误,并且很难想象您会如何做到这一点,除非您尝试从 ASCII 而不是 UTF-8 解码。因此,您需要向我们展示一个 minimal reproducible example,它实际上证明了您的错误。

标签: python json http


【解决方案1】:

您的报告中有一些奇怪的地方,因为打印j.json() 会导致其中包含r.json() 的错误...。

如果您不使用 str() 进行隐式解码,您的第二次尝试将起作用。

尝试明确的、完全详细的方式:

print(json.loads(r.content.decode(r.encoding)))

【讨论】:

  • 不幸的是,在解码“UnicodeEncodeError: 'ascii' codec can't encode character '\u0f3c' in position 95: ordinal not in range(128)”时仍有问题
  • 该问题不是解码错误,因为它是UnicodeEncodeError,所以它是错误编码,而不是解码。尝试分别进行这两项操作,首先执行obj = json.loads(r.content.decode(r.encoding)),然后在下面的行中执行print(obj) ...如果错误出现在print 部分,则解码工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-06
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 1970-01-01
  • 2017-12-04
相关资源
最近更新 更多