覆盖 urllib2.HTTPError 或 urllib.error.HTTPError 并读取响应 HTML

Posted

技术标签:

【中文标题】覆盖 urllib2.HTTPError 或 urllib.error.HTTPError 并读取响应 HTML【英文标题】:Overriding urllib2.HTTPError or urllib.error.HTTPError and reading response HTML anyway 【发布时间】:2011-01-15 01:50:12 【问题描述】:

我收到“HTTP 错误 500:内部服务器错误”响应,但我仍想读取错误 html 中的数据。

使用 Python 2.6,我通常使用以下方法获取页面:

import urllib2
url = "http://google.com"
data = urllib2.urlopen(url)
data = data.read()

当尝试在失败的 URL 上使用它时,我收到异常 urllib2.HTTPError:

urllib2.HTTPError: HTTP Error 500: Internal Server Error

如何在返回内部服务器错误的同时获取此类错误页面(无论有无 urllib2)?

请注意,对于 Python 3,对应的异常是 urllib.error.HTTPError

【问题讨论】:

【参考方案1】:

HTTPErroris a file-like object。你可以抓住它,然后read它的内容。

try:
    resp = urllib2.urlopen(url)
    contents = resp.read()
except urllib2.HTTPError, error:
    contents = error.read()

【讨论】:

一旦我们完成了error.read(),error.read()随后返回空字符串。有时这会弄乱其他地方的代码。我们怎样才能礼貌地将错误的内容还给别人? @Matt 我从来没有尝试过这个,但是因为它是一个类似文件的对象,你可以做一个error.seek(0) 来将“文件指针”重置到流的开头。并非每个类文件对象都需要实现 I/O 接口的随机访问部分,因此不确定它是否有效。如果没有,您可以考虑在自己的问题中提出这个问题,以便吸引更多的受众。 请注意,在退化的情况下,HTTPError 可能不会像文件类对象那样表现。验证 read() 是否可用于 hasattr。 由于底层流是一个http响应,它是不可搜索的,这意味着你不能在它上面调用seek()【参考方案2】:
alist=['http://someurl.com']

def testUrl():
    errList=[]
    for URL in alist:
        try:
            urllib2.urlopen(URL)
        except urllib2.URLError, err:
            (err.reason != 200)
            errList.append(URL+" "+str(err.reason))
            return URL+" "+str(err.reason)
    return "".join(errList)

testUrl()

【讨论】:

您应该在答案中添加描述性文字 err.reason 实际上并没有提供与err.read() 提供的相同信息。后者可能更特别有用。【参考方案3】:

如果您的意思是要阅读 500 的正文:

request = urllib2.Request(url, data, headers)
try:
        resp = urllib2.urlopen(request)
        print resp.read()
except urllib2.HTTPError, error:
        print "ERROR: ", error.read()

在您的情况下,您不需要构建请求。做吧

try:
        resp = urllib2.urlopen(url)
        print resp.read()
except urllib2.HTTPError, error:
        print "ERROR: ", error.read()

所以,你不要覆盖 urllib2.HTTPError,你只是处理异常。

【讨论】:

不,如果用户不小心进入了 500 个内部错误页面之一,我想读取服务器发送给用户浏览器的 HTML。就像,如果 urllib 在任何 404 页面上中断(我不确定是否如此,我没有尝试过),我想阅读 404 页面提供的 html(例如,如果该站点执行自定义 404 页面)。

以上是关于覆盖 urllib2.HTTPError 或 urllib.error.HTTPError 并读取响应 HTML的主要内容,如果未能解决你的问题,请参考以下文章

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

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

Python 2.7 urllib2 在使用 xml 内容点击重定向时引发 urllib2.HTTPError 301

urllib2.HTTPError: HTTP Error 403: Forbidden 解决方法

python urllib2导出elasticsearch数据时 返回 "urllib2.HTTPError: HTTP Error 500: Internal Server Error&q

如何避免程序终止urllib2.httperror 404错误并显示相应的消息