3

我正在使用 ast.literal_eval 将从 json.loads() 收到的数据更改为 Python 字典;但是,如果我应该以一种完全不同的方式来解决这个问题 - 请随时指出这一点。

# Authentication
buf = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(c.URL, "https://kippt.com/api/account")
c.setopt(c.WRITEFUNCTION, buf.write)
c.setopt(c.HTTPHEADER, header)
c.perform()

result = buf.getvalue()
buf.close()

print result

# Printing Output
data_string = json.dumps(result)
jsonload = json.loads(data_string)
jsondict = ast.literal_eval(jsonload)

目前它可以与单行 JSON 返回一起正常工作,例如:

{“用户名”:“我的用户名”,“api_token”:“my_api_token”}

我可以通过以下方式正确获取值:

print jsondict['username']
print jsondict['api_token']

我遇到问题的部分是数据嵌套时,例如:

{“meta”:{“next”:null,“total_count”:6,“previous”:null,“limit”:20,“offset”:0},“objects”:[{“rss_url”:“https: //kippt.com/feed/username_here/stuff_here/cool-stuff", "updated": "1339003710", "title": "Cool Stuff", "created": "1339001514", "slug": "cool-stuff ”,“id”:54533,“resource_uri”:“/api/lists/54533/”},{“rss_url”:“https://kippt.com/feed/username_here/stuff_here/programming”,“更新”: “1339003479”、“title”:“Programming”、“created”:“1339001487”、“slug”:“programming”、“id”:54532、“resource_uri”:“/api/lists/54532/”},{“rss_url”:“https://kippt.com/feed/username_here/stuff_here/android”,“更新”:“1339003520”,“标题”:“Android”, “创建”:“1339000936”,“slug”:“android”,“id”:54530,“resource_uri”:“/api/lists/54530/”},{“rss_url”:“https://kippt.com /feed/username_here/stuff_here/chrome", "updated": "1339000931", "title": "Chrome", "created": "1339000412", "slug": "chrome", "id": 54529, "resource_uri ": "/api/lists/54529/"}, {"rss_url": "https://kippt.com/feed/username_here/stuff_here/inbox", "更新": "1338946730”,“标题”:“收件箱”,“已创建”:“1338945940”,“slug”:“收件箱”,“id”:54432,“resource_uri”:“/api/lists/54432/”},{“ rss_url”:“https://kippt.com/feed/username_here/stuff_here/read-later”,“更新”:“1338945940”,“标题”:“稍后阅读”,“创建”:“1338945940”,“slug ": "稍后阅读", "id": 54433, "resource_uri": "/api/lists/54433/"}]}com/feed/username_here/stuff_here/read-later”、“updated”:“1338945940”、“title”:“稍后阅读”、“created”:“1338945940”、“slug”:“稍后阅读”、“id ": 54433, "resource_uri": "/api/lists/54433/"}]}com/feed/username_here/stuff_here/read-later”、“updated”:“1338945940”、“title”:“稍后阅读”、“created”:“1338945940”、“slug”:“稍后阅读”、“id ": 54433, "resource_uri": "/api/lists/54433/"}]}

当我使用相同的代码(/api/lists 的交换 URL)时,我在运行脚本时收到以下错误:

回溯(最后一次调用):文件“kippt.py”,第 48 行,在 jsondict = ast.literal_eval(jsonload) 文件“/usr/local/lib/python2.7/ast.py”,第 80 行,在literal_eval return _convert(node_or_string) File "/usr/local/lib/python2.7/ast.py", line 63, in _convert in zip(node.keys, node.values)) File "/usr/local/lib/python2 .7/ast.py”,第 62 行,返回 dict((_convert(k), _convert(v)) for k, v 文件“/usr/local/lib/python2.7/ast.py”,第 63 行,在 _convert in zip(node.keys, node.values)) 文件“/usr/local/lib/python2.7/ast.py”,第 62 行,返回 dict((_convert(k), _convert(v) ) for k, v File "/usr/local/lib/python2.7/ast.py", line 79, in _convert raise ValueError('malformed string') ValueError: malformed string

任何帮助,将不胜感激。谢谢!

编辑 - 在下面回答:

看起来我的第一个输入可能被解释为 Python 语法,这是我的错,因为我在技术上没有以正确的方式开始。

我现在只想 json.loads() 我从 cURL 得到的结果,而不是做我以前做的那些古怪的事情。

例如:

buf = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(c.URL, "https://kippt.com/api/lists")
c.setopt(c.WRITEFUNCTION, buf.write)
c.setopt(c.HTTPHEADER, header)
c.perform()

result = buf.getvalue()
buf.close()

print result

# Printing Output
jsonload = json.loads(result)
print jsonload['meta']['total_count'] # Gets the total_count item in the meta object.
4

2 回答 2

8

ast.literal_eval嵌套字典没有问题:

>>> ast.literal_eval("{'a': {'b':'c'}}")
{'a': {'b': 'c'}}

ast.literal_eval正在破坏,因为数据实际上是 JSON……而且 JSON 不是有效的 Python。具体来说,null它不是有效的 Python 文字。

为什么不只是json.loads()用来加载数据呢?

于 2012-06-07T02:45:32.990 回答
0

我想出了一个场景,我想在 pandas 中使用 json.normalize 但值是 str 类型。使用 ast.literal_eval,我输入 cast

您可以像下面一样使用 ast.literal_eval - df[column_name] = df[column_name].apply(ast.literal_eval)

这会将 str 转换为 dict。例如。df = [{'A': "{'value': '1'}", 'B': "{'value': '2'}"}]

应用文字 eval - df = [{'A': {'value': '1'}, 'B': {'value': '2'}}]

于 2020-09-01T08:35:21.567 回答