2011-06-28 8 views
7

Điều này liên quan đến urllib2 cụ thể, nhưng xử lý ngoại lệ tùy chỉnh nói chung hơn. Làm cách nào để chuyển thông tin bổ sung vào chức năng gọi điện trong mô-đun khác thông qua ngoại lệ đã nêu? Tôi giả sử tôi sẽ tái nâng cao bằng cách sử dụng một lớp ngoại lệ tùy chỉnh, nhưng tôi không chắc chắn về các chi tiết kỹ thuật.Nhận URL khi xử lý urllib2.URLError

Thay vì làm ô nhiễm mã mẫu bằng những gì tôi đã thử và không thành công, tôi sẽ chỉ trình bày nó dưới dạng phiến đá trống. Mục tiêu cuối cùng của tôi là dành cho dòng cuối cùng trong mẫu để hoạt động.

#mymod.py 
import urllib2 

def openurl(): 
    req = urllib2.Request("http://duznotexist.com/") 
    response = urllib2.urlopen(req) 

#main.py 
import urllib2 
import mymod 

try: 
    mymod.openurl() 
except urllib2.URLError as e: 
    #how do I do this? 
    print "Website (%s) could not be reached due to %s" % (e.url, e.reason) 

Trả lời

8

Bạn có thể thêm thông tin và sau đó tăng lại ngoại lệ.

#mymod.py 
import urllib2 

def openurl(): 
    req = urllib2.Request("http://duznotexist.com/") 
    try: 
     response = urllib2.urlopen(req) 
    except urllib2.URLError as e: 
     # add URL and reason to the exception object 
     e.url = "http://duznotexist.com/" 
     e.reason = "URL does not exist" 
     raise e # re-raise the exception, so the calling function can catch it 

#main.py 
import urllib2 
import mymod 

try: 
    mymod.openurl() 
except urllib2.URLError as e: 
    print "Website (%s) could not be reached due to %s" % (e.url, e.reason) 
+0

+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

+1

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. –

+0

'e.reason =" URL không tồn tại "' sẽ cung cấp 'AttributeError: không thể đặt thuộc tính' – histrio

0

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/