ValueError:使用ast.literal_eval的格式错误的字符串 [英] ValueError: malformed string using ast.literal_eval

查看:256
本文介绍了ValueError:使用ast.literal_eval的格式错误的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个循环以获取json api,这是我循环中的内容:

I'm doing a loop to get json api, here is what I have in my loop:

response_item = requests.request('GET',url_item,params=None,verify=False)
response_item = json.loads(response_item.text)
response_item = ast.literal_eval(json.dumps(response_item, ensure_ascii=False).encode('utf8'))

我扫描了45000个json对象,每次迭代都会生成"url_item"变量.每个对象都是相同的,到达7064时会得到类似7000对象的错误,并且出现以下错误:

I scan around 45000 json objects, I generate "url_item" variable for each iteration. Each object is the same, I can get something like 7000 object and I have the following error when I reach the 7064th:

Traceback (most recent call last):
  File "C:\Python27\tools\api_item.py", line 47, in <module>
    response_item = ast.literal_eval(json.dumps(response_item, ensure_ascii=False).encode('utf8'))
  File "C:\Python27\lib\ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "C:\Python27\lib\ast.py", line 63, in _convert
    in zip(node.keys, node.values))
  File "C:\Python27\lib\ast.py", line 62, in <genexpr>
    return dict((_convert(k), _convert(v)) for k, v
  File "C:\Python27\lib\ast.py", line 63, in _convert
    in zip(node.keys, node.values))
  File "C:\Python27\lib\ast.py", line 62, in <genexpr>
    return dict((_convert(k), _convert(v)) for k, v
  File "C:\Python27\lib\ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

我曾经打印第二和第三"response_item".当然,在这种情况下,由于我之前有错误,所以第三个没有显示,这是我在json.load之后要打印的内容:

I used to print the second and third "response_item". Of course in this case the third one isn't displayed since I have the error just before, here what I have for the print after the json.load:

{u'restrictions': [], u'name': u'Sac \xe0 dos de base', u'level': 0, u'rarity': u'Basic', u'vendor_value': 11, u'details': {u'no_sell_or_sort': False, u'size': 20}, u'game_types': [u'Activity', u'Wvw', u'Dungeon', u'Pve'], u'flags': [u'NoSell', u'SoulbindOnAcquire', u'SoulBindOnUse'], u'icon': u'https://render.guildwars2.com/file/80E36806385691D4C0910817EF2A6C2006AEE353/61755.png', u'type': u'Bag', u'id': 8932, u'description': u'Un sac de 20 emplacements pour les personnages d\xe9butants.'}

在此之前得到的所有物品都具有相同的类型,相同的格式,除了7064号以外,我没有任何错误!

Every item I get before this one has the same type, same format, and I don't have any error except for the 7064th !

谢谢您的帮助!

推荐答案

您应对JSON数据使用ast.literal_eval(). JSON和Python文字可能看起来就像是同一件事,但是它们却不一样.

You should not use ast.literal_eval() on JSON data. JSON and Python literals may look like the same thing, but they are very much not.

在这种情况下,您的数据包含一个布尔标志,在JSON中设置为false.适当的Python布尔值使用标题大小写,因此False:

In this case, your data contains a boolean flag, set to false in JSON. A proper Python boolean uses title-case, so False:

>>> import json, ast
>>> s = '{"no_sell_or_sort": false, "size": 20}'
>>> json.loads(s)
{u'no_sell_or_sort': False, u'size': 20}
>>> ast.literal_eval(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/ast.py", line 63, in _convert
    in zip(node.keys, node.values))
  File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/ast.py", line 62, in <genexpr>
    return dict((_convert(k), _convert(v)) for k, v
  File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

其他区别包括使用null代替None,以及Python 2的Unicode转义序列看起来像纯(字节)字符串,在转义非BMP代码点.

Other differences include using null instead of None, and Unicode escape sequences in what to Python 2 looks like a plain (bytes) string, using UTF-16 surrogates when escaping non-BMP codepoints.

使用json.loads()而不是ast.literal_eval()加载数据.它不仅可以正确处理JSON,而且还更快.

Load your data with json.loads(), not ast.literal_eval(). Not only will it handle proper JSON just fine, it is also faster.

在您的情况下,您似乎正在使用json.dumps(),然后尝试再次使用ast.literal_eval()加载数据.该步骤不需要,您已经已经拥有一个Python对象.

In your case, it appears you are using json.dumps() then try to load the data again with ast.literal_eval(). There is no need for that step, you already had a Python object.

换句话说,一行:

response_item = ast.literal_eval(json.dumps(response_item, ensure_ascii=False).encode('utf8'))

最好是多余的,最坏的情况是非常非常错误的.将response_item重新编码为JSON字符串不会产生可解释为Python文字的内容.

is redundant at best, and very, very wrong, at worst. Re-encoding response_item to a JSON string does not produce something that can be interpreted as a Python literal.

这篇关于ValueError:使用ast.literal_eval的格式错误的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆