从 Google App Engine 调用 Reddit api 时出现错误 429
Posted
技术标签:
【中文标题】从 Google App Engine 调用 Reddit api 时出现错误 429【英文标题】:Error 429 when invoking Reddit api from Google App Engine 【发布时间】:2012-02-16 07:43:01 【问题描述】:我已经在 Google App Engine 上运行 cron 作业一个多月了,没有任何问题。这项工作做了很多事情,其中之一是它使用 urllib2 进行调用以从 Reddit 以及其他一些站点检索 json 响应。大约两周前,我在调用 Reddit 时开始看到错误,但在调用其他站点时没有错误。我收到的错误是 HTTP 错误 429。
我已尝试在 Google App Engine 之外执行相同的代码,但没有任何问题。我尝试使用 urlFetch,但收到相同的错误。
使用应用程序engine's interactive shell时可以看到错误,代码如下。
import urllib2
data = urllib2.urlopen('http://www.reddit.com/r/Music/.json', timeout=60)
编辑:不知道为什么它总是对我而不是其他人失败。这是我收到的错误:
>>> import urllib2
>>> data = urllib2.urlopen('http://www.reddit.com/r/Music/.json', timeout=60)
Traceback (most recent call last):
File "/base/data/home/apps/s~shell-27/1.356011914885973647/shell.py", line 267, in get
exec compiled in statement_module.__dict__
File "<string>", line 1, in <module>
File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 400, in open
response = meth(req, response)
File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 513, in http_response
'http', request, response, code, msg, hdrs)
File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 438, in error
return self._call_chain(*args)
File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 372, in _call_chain
result = func(*args)
File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 521, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 429: Unknown
类似的代码在应用引擎之外运行没有问题:
print urllib2.urlopen('http://www.reddit.com/r/Music/.json').read()
起初我认为它与超时问题有关,因为它最初可以工作,但由于没有超时错误而是奇怪的 HttpError 代码,我不确定。 有任何想法吗?
【问题讨论】:
使用交互式 shell 和您提供的代码对我有用。 这只是意味着你提出了太多的请求。作为程序员,您无能为力。为了避免这些错误,您通常可以在请求之间设置一个睡眠。 tools.ietf.org/html/draft-nottingham-http-new-status-02#page-4 @user947240:听从 shadyabhi 的建议。 这可能有助于多次调用,但在第一次调用 Reddit 时会失败。 Reddit api 站点仅声明您不能在 30 秒内多次调用同一个 url。他们是否认为来自多个应用的所有谷歌应用引擎调用都来自同一个来源,因此阻止了来自谷歌应用引擎上运行的任何应用的任何调用? 我添加了重试逻辑和 31 秒睡眠。它似乎通常在一两次尝试后起作用,但并非总是如此。我通过电子邮件发送了 reddit 的限速电子邮件地址,但没有收到回复。 【参考方案1】:Reddit 对 python shell 的默认用户代理的 api 限制非常严格。您需要使用您的 reddit 用户名设置一个唯一的用户代理,如下所示:
User-Agent:/u/spladug 的超级快乐天才机器人
更多关于reddit api的信息在这里https://github.com/reddit/reddit/wiki/API。
【讨论】:
这应该是公认的答案。直接从该链接中的文档“许多默认用户代理(如“Python/urllib”或“Java”)受到极大限制,以鼓励独特和描述性的用户代理字符串。”【参考方案2】:Reddit 可能会根据 IP 计算调用次数 - 这意味着 GAE 上共享您 IP 的其他应用程序可能已经用尽配额。
如果您使用 Reddit API 密钥(我不知道他们是否发布它们)或者如果他们同意根据应用标头限制 API 调用的速率,这可能会更好。
【讨论】:
Sudhir,这只是猜测。 是的……是的。我不认为答案是确定的。以上是关于从 Google App Engine 调用 Reddit api 时出现错误 429的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Google App Engine dev_appserver.py:watcher_ignore_re 标志“不是 JSON 可序列化”错误? [复制]
Google App Engine 上的 Django TemplateDoesNotExist
如何从本地 Google App-engine 数据存储中删除所有实体?
Google App Engine 渲染和 Django 表单
使用 OAuth 2.0 Google App Engine 刷新访问令牌
如何在 Google Cloud App Engine 上使用 PubSub 创建订阅者,该订阅者通过 Publisher 从 Google Cloud App Engine Flex 收听消息?