【问题标题】:urllib2 HTTP error 429urllib2 HTTP 错误 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。

标签: python urllib2 reddit http-status-code-429


【解决方案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()

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

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)

解决了问题

【讨论】:

    猜你喜欢
    • 2014-08-29
    • 1970-01-01
    • 2012-02-09
    • 2015-09-22
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    相关资源
    最近更新 更多