Получить URL при обработке urllib2.URLError - PullRequest
7 голосов
/ 28 июня 2011

Это относится конкретно к urllib2, но к пользовательской исключительной ситуации относится более широко.Как передать дополнительную информацию в вызывающую функцию в другом модуле через возбуждаемое исключение?Я предполагаю, что я бы повторно поднял, используя пользовательский класс исключений, но я не уверен в технических деталях.

Вместо того, чтобы загрязнять образец кода тем, что я попробовал и потерпел неудачу, япросто представьте это как главным образом чистый лист.Моя конечная цель - чтобы последняя строка в образце работала.

#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)

Ответы [ 2 ]

8 голосов
/ 28 июня 2011

Вы можете добавить информацию и затем повторно вызвать исключение.

#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 голосов
/ 23 февраля 2017

Я не думаю, что повторное поднятие исключения является подходящим способом решения этой проблемы.

Как сказал @Jonathan Vanasco,

, если вы открываете a.com, и он 301 перенаправляет на b.com, urlopen будет автоматически следовать этому, поскольку ошибка HTTPError с перенаправлениембыл поднят.если b.com вызывает URLError, приведенный выше код помечает a.com как несуществующий

Мое решение - переписать redirect_request из 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()

давайте попробуемперенаправить URL на неизвестный URL:

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)

И результат:

error
http://a.com/

normal
http://www.google.com/
...