urllib2 HTTP 错误 429

Posted

技术标签:

【中文标题】urllib2 HTTP 错误 429【英文标题】:urllib2 HTTP error 429 【发布时间】:2012-10-24 03:55:53 【问题描述】:

所以我有一个 sub-reddits 列表,我正在使用 urllib 打开它们。当我浏览它们时,最终 urllib 失败了:

urllib2.HTTPError: HTTP Error 429: Unknown

做了一些研究,我发现 reddit 通过 IP 限制了对其服务器的请求数量:

每两秒发出不超过一个请求。有一些请求突发的余地,但要保持理智。一般来说,保持在一分钟内不超过 30 个请求。

所以我想我会使用time.sleep() 将我的请求限制为每 10 秒一页。这最终也会失败。

以上引用来自reddit API 页面。我没有使用 reddit API。在这一点上,我在想两件事。该限制仅适用于 reddit API,或者 urllib 也有限制。

有谁知道这是这两件事中的哪一件?或者我该如何解决这个问题?

【问题讨论】:

urllib2 没有限制,您可以通过尝试其他网页发现。他们可能阻止了您的 IP 访问 API,请尝试向他们发送电子邮件。 @larsmans 请求随机通过。我得到了一些然后它失败了一段时间然后它再次工作。他们也不能阻止我使用他们的 API,因为我没有使用他们的 API。 【参考方案1】:

来自https://github.com/reddit/reddit/wiki/API:

许多默认的用户代理(如“Python/urllib”或“Java”)都受到严格限制,以鼓励使用独特和描述性的用户代理字符串。

这也适用于常规请求。发出请求时,您需要提供自己的用户代理标头。

#TODO: change user agent string
hdr =  'User-Agent' : 'super happy flair bot by /u/spladug' 
req = urllib2.Request(url, headers=hdr)
html = urllib2.urlopen(req).read()

但是,这将为每个请求创建一个新连接。我建议使用另一个能够重用连接的库,例如httplib 或Request。它将减轻服务器的压力并加快请求速度:

import httplib
import time

lst = """
science
scifi
"""

hdr=  'User-Agent' : 'super happy flair bot by /u/spladug' 
conn = httplib.HTTPConnection('www.reddit.com')
for name in lst.split():
    conn.request('GET', '/r/'+name, headers=hdr)
    print conn.getresponse().read()
    time.sleep(2)
conn.close()

【讨论】:

这似乎工作的唯一原因是因为您没有使用通用用户代理。但是,根据 API 规则,您仍然需要设置唯一的用户代理,此解决方案最终仍可能导致您收到 429 错误。 感谢您纠正我的错误评估。我已更改答案以反映这一点。【参考方案2】:

reddit 通过请求对 IP 地址和用户代理执行速率限制(而不是匿名 Coward 的 suggested 连接)。您遇到的问题是,尝试使用 urllib2 访问 reddit 的每个用户都将被限制为单个用户。

解决办法是设置一个用户代理,你可以在this question找到答案。

或者,放弃编写自己的代码来爬取 reddit 并使用 PRAW instead。它支持 reddit API 的几乎所有功能,您无需担心遵循任何 API 规则,因为它会为您处理这些问题。

【讨论】:

谢谢 bboe。我在 reddit IRC 上抓住了你,你告诉我关于 PRAW 的事。再次欢呼。【参考方案3】:

我遇到了同样的错误。修改代码

from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen(url)
bsObj = BeautifulSoup(html)

from urllib.request import urlopen
from bs4 import BeautifulSoup
import urllib.request

webRequest = urllib.request.Request(url, headers="User-Agent": <you username in case you are scraping reddit>)
html = urlopen(webRequest)
bsObj = BeautifulSoup(html)

解决了问题

【讨论】:

以上是关于urllib2 HTTP 错误 429的主要内容,如果未能解决你的问题,请参考以下文章

urllib2 HTTP 错误 400:错误请求

urllib2.HTTPError:HTTP 错误 403:禁止

urllib2.HTTPError:HTTP 错误 401:未经授权

python: urllib2.HTTPError: HTTP 错误 405: 方法不允许

导入错误:没有模块名称 urllib2

从 Google App Engine 调用 Reddit api 时出现错误 429