Python urllib2 出现 HTTP 错误 429

Python HTTP Error 429 with urllib2

我正在使用以下代码将重定向解析为 return 最终链接 url

def resolve_redirects(url):
    return urllib2.urlopen(url).geturl()

不幸的是,我有时会收到 HTTPError: HTTP Error 429: Too Many Requests。什么是解决这个问题的好方法?下面这个好还是有更好的办法

def resolve_redirects(url):
    try:
        return urllib2.urlopen(url).geturl()
    except HTTPError:
        time.sleep(5)
        return urllib2.urlopen(url).geturl()

还有,如果except块出现异常怎么办?

这是处理异常的好方法,但您应该检查以确保您始终在给定网站的请求之间休眠适当的时间(例如,twitter 限制每分钟的请求量和他们的 api 文档中清楚地显示了这个数量)。所以只要确保你总是睡得足够久。

要从异常中的异常中恢复,您可以简单地嵌入另一个 try/catch 块:

def resolve_redirects(url):
    try:
        return urllib2.urlopen(url).geturl()
    except HTTPError:
        time.sleep(5)
        try:
            return urllib2.urlopen(url).geturl()
        except HTTPError:
            return "Failed twice :S"

编辑:正如@jesse-w-at-z 指出的那样,您应该在第二个错误情况下返回 URL,我发布的代码只是一个如何编写嵌套的参考示例try/catch。

最好在重试之前确保 HTTP 代码实际上是 429。

可以这样做:

def resolve_redirects(url):
    try:
        return urllib2.urlopen(url).geturl()
    except HTTPError, e:
        if e.code == 429:
             time.sleep(5);
             return resolve_redirects(url)
        raise

这也将允许任意次数的重试(可能需要也可能不需要)。

https://docs.python.org/2/howto/urllib2.html#httperror

添加 User-Agent 请求 header 解决了我的问题:

from urllib import request
from urllib.request import urlopen

url = 'https://www.example.com/abc.json'
req = request.Request(url)
req.add_header('User-Agent', 'abc-bot')
response = request.urlopen(req)