Tôi không nghĩ việc nâng cao ngoại lệ là một cách thích hợp để giải quyết vấn đề này.
Như @ Jonathan Vanasco nói,
if you're opening a.com , and it 301 redirects to b.com , urlopen will automatically follow that because an HTTPError with a redirect was raised. if b.com causes the URLError , the code above marks a.com as not existing
Giải pháp của tôi là ghi đè lên redirect_request
của urllib2.HTTPRedirectHandler
import urllib2
class NewHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
m = req.get_method()
if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
or code in (301, 302, 303) and m == "POST"):
newurl = newurl.replace(' ', '%20')
newheaders = dict((k,v) for k,v in req.headers.items()
if k.lower() not in ("content-length", "content-type")
)
# reuse the req object
# mind that req will be changed if redirection happends
req.__init__(newurl,
headers=newheaders,
origin_req_host=req.get_origin_req_host(),
unverifiable=True)
return req
else:
raise HTTPError(req.get_full_url(), code, msg, headers, fp)
opener = urllib2.build_opener(NewHTTPRedirectHandler)
urllib2.install_opener(opener)
# mind that req will be changed if redirection happends
#req = urllib2.Request('http://127.0.0.1:5000')
req = urllib2.Request('http://www.google.com/')
try:
response = urllib2.urlopen(req)
except urllib2.URLError as e:
print 'error'
print req.get_full_url()
else:
print 'normal'
print response.geturl()
chúng ta hãy cố gắng chuyển hướng url đến một url biết:
import os
from flask import Flask,redirect
app = Flask(__name__)
@app.route('/')
def hello():
# return 'hello world'
return redirect("http://a.com", code=302)
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
Và kết quả là:
error
http://a.com/
normal
http://www.google.com/
+1 Vâng, đó là những gì tôi đang tìm kiếm. Tôi thấy nó rất đơn giản, nhưng tôi đã không nhận được thông qua google hoặc dùng thử và lỗi. – mwolfe02
urlib2.urlopen() sẽ theo các chuyển hướng - vì vậy 'e.url_original' sẽ phù hợp hơn. tôi đã không thể tìm ra cách để có được 'url_actual' đã kích hoạt URLError. Tôi không cố gắng nitpick ở đây. nếu bạn đang mở a.com và chuyển hướng 301 sang b.com, urlopen sẽ tự động theo dõi bởi vì một HTTPError có chuyển hướng được nâng lên. nếu b.com gây ra URLError, mã ở trên đánh dấu a.com là không tồn tại - khi nó hoạt động và hoạt động hoàn hảo, nó chỉ trỏ đến url không đúng tại b.com. –
'e.reason =" URL không tồn tại "' sẽ cung cấp 'AttributeError: không thể đặt thuộc tính' – histrio