UnboundLocalError使用请求进行递归URI调用

时间:2015-12-13 07:29:07

标签: python python-2.7 recursion python-requests

我有一些代码,嗯,从给定的URL获取页面。

在try / except子句中,如果发生异常,程序会休眠几秒钟,打印回溯,然后再次递归启动。

def fetch_page(self, url):
    head = {'User-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0"}
    time.sleep(2)
    print "..."
    try:
        r = requests.get(url, headers=head)
    except:
        time.sleep(2)
        print 'error', url, "Trying again"
        traceback.print_exc()
        self.fetch_page(url)
    r.raise_for_status()
    print r.status_code
    return r.text

但是每当发生异常时,代码会成功休眠,进行递归调用,打印r.status_code,然后在UnboundLocalError上提供r.raise_for_status()

...
200
Traceback (most recent call last):
  File "./calling.py", line 140, in <module>
    get_valid_url = Get()
  File "./calling.py", line 22, in __init__
    self.call()
  File "./calling.py", line 44, in call
    text = self.fetch_page(link.strip('\n'))
  File "./calling.py", line 35, in fetch_page
    r.raise_for_status()
UnboundLocalError: local variable 'r' referenced before assignment

现在,如果在分配之前引用r,为什么要打印r.status_code

我的第一个猜测可能是我搞砸了递归电话。但这没有任何意义。我错过了什么?

1 个答案:

答案 0 :(得分:2)

想象一下,你运行你的功能并第一次获得404。您输入except块,然后再次递归调用fetch_page。假设你这次得到200分。您没有输入except块;相反,您将运行到函数的末尾并return r.text

然后

Control返回到调用者,这是您之前调用的fetch_page。执行下一行代码r.raise_for_status()。但是在 {/ 1}}(顶层)的调用中,fetch_page从未实际定义过,因为r块中抛出了异常。因此,try

一种可能的解决方案 - 而不是:

UnboundLocalError

将递归调用的结果返回except: time.sleep(2) print 'error', url, "Trying again" traceback.print_exc() self.fetch_page(url)

fetch_page

我还建议你做一些更像这样的事情,这样你就可以避免在不同的缩进级别获得回报:

except:
    time.sleep(2)
    print 'error', url, "Trying again"
    traceback.print_exc()
    return self.fetch_page(url)