在 Python 3.6 中解码来自 API 的文本响应

Posted

技术标签:

【中文标题】在 Python 3.6 中解码来自 API 的文本响应【英文标题】:Decode text response from API in Python 3.6 【发布时间】:2018-09-21 04:28:22 【问题描述】:

我正在尝试从 mailchimp 导出 api 中提取数据,它根据以下规范返回响应:

    Returns:

参数-文本

说明: JSON 对象的纯文本转储。第一行是标题行。返回的每个附加行都是一个单独的 JSON 对象。行使用换行符 (\n) 标记分隔,因此实现可以一次读取一行,处理它,然后继续。

要获取我正在使用的数据:

response = requests.get(urldetails).text

如果我使用 .json() 它会出现 JSON 解码错误。上面的输出是这样的:

数据.. 数据...

我不确定每个 dict 是否在单独的行上,但是我的印象是它实际上只是一个连续的字符串,因为我的许多解码尝试都以错误 'str' object cannot be...etc . .当我使用 .text 方法时,我在任何地方都看不到 '\n' 分隔符。

最好的方法是让每个 dict 成为列表中的单独项目或数据框中的一行(我可以稍后解压缩)。

谢谢

【问题讨论】:

您查询的端点是什么? https://<dc>.api.mailchimp.com/3.0/lists/? 它的导出 API https://.api.mailchimp.com/export/1.0/campaignSubscriberActivity/ : developer.mailchimp.com/documentation/mailchimp/guides/… 【参考方案1】:

您可以使用简单的方法从MailChimp export api 获取所有数据。请注意,我使用的是f-strings,仅适用于 Python 3.6+。

import requests
import json


apikey = '<your-api-key>'
id = "<list-id>"

URL = f"https://us10.api.mailchimp.com/export/1.0/campaignSubscriberActivity/?apikey=apikey&id=id"

json_data = [json.loads(s) for s in requests.get(URL).text.strip().split("\n")]
print(json_data[0]['<some-subscriber-email>'][0]['action'])

【讨论】:

显然 splitlines() 对他不起作用 - 为什么要在拆分之前剥离字符串使其功能有所不同 因为响应中有额外的空格,如果你在带有额外空格的字符串上执行json.loads,则会导致JSONDecodeError 嗯,对了 - 我无法测试我本来可以测试的 api。谢谢! 谢谢! - 我将其标记为正确答案,尽管我需要使用稍微不同的方法,因为我需要一个整洁的数据框中的所有内容(目前看起来像是一个挑战......)。但是,'.text.strip().split("\n")' 方法有效!【参考方案2】:

如果文本响应不是格式非常糟糕的 json,您可以使用 json library。特别是 load() 函数。

import json
json_response = json.loads(response)

loads() 将 JSON 从字符串加载到 python 字典中。

编辑: Mailchimp API 声明每个 JSON 对象由换行符分隔。我们可以使用以下代码创建一个字典列表:

# get response from GET request and load as a string
import json
json_resp = [json.loads(line) for line in response.split('\n')]

【讨论】:

我试过这个,收到以下错误:'TypeError: JSON object must be str, bytes or bytearray, not 'Response''。另一方面,如果我使用 .text 版本:json.loads(response.text),我会得到一个不同的错误:json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 113) @DBa 这是假设问题上的代码 - response = requests.get(urldetails).text - 已经执行,因此如果遵循发布的代码应该已经是一个字符串。 另外,您有返回的样本吗?还是我可以测试的网址? 是的,对不起,后来意识到,编辑了我的答案以涵盖有和没有 .text 错误。 @DBa 一些样本会真的帮助我帮助你

以上是关于在 Python 3.6 中解码来自 API 的文本响应的主要内容,如果未能解决你的问题,请参考以下文章

在 Python-3.6 中使用网络摄像头作为二维码扫描仪

在 Python 中使用来自 Gravitee 的公钥解码 JWT 令牌时出现问题

Clarisse 3.6 python api

在 Python 中解码字符(YouTube 数据 API)

使用 python 3.6,找不到满足要求 tensorflow 的版本(来自版本:)没有为 tensorflow 找到匹配的分布

在 Swift 中解码 JSON API - 重复的结构名称