覆盖urllib2.HTTPError或urllib.error.HTTPError并以任何方式读取响应HTML


72

我收到“ 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

Answers:


136

HTTPError 是一个类似文件的对象。您可以先捕获它,然后捕获它read的内容。

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

2
一旦完成error.read(),error.read()随后将返回空字符串。有时,这会使其他地方的代码混乱。我们如何礼貌地将错误的内容放回他人?
Panic Panic

1
@Matt我从未尝试过,但是由于它是一个类似文件的对象,因此您可以执行操作error.seek(0)以将“文件指针”重置为流的开头。并非每个文件类对象都需要实现I / O接口的随机访问部分,因此不确定它是否有效。如果没有,您可以考虑在自己的问题中提问,这样可以吸引更多的听众。
乔·霍洛威

1
请注意,在简并的情况下,HTTPError可能不会表现为类似文件的对象。验证read()是否可用于hasattr。
罗恩

2
由于基础流是http响应,因此它是不可搜索的,这意味着您无法对其进行调用seek()
remcoder

9

如果您要阅读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,而只需处理异常。


1
不,我想阅读服务器发送给用户浏览器的HTML,如果他们不小心转到了500个内部错误页面之一。就像,如果urllib在任何404页面上损坏(我不确定是否可以,我没有尝试过),我想阅读404页面提供的html(如果该网站执行自定义404页面,则为EG)。
backus 2010年

-1
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()

1
您应该在回答中添加描述性文字
侯赛因·哈利勒

err.reason实际提供的信息与实际提供的信息不同err.read()。后者可能更特别有用。
Acumenus '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.