【问题标题】:Error local variable has been referenced before assignment赋值前已引用错误局部变量
【发布时间】:2021-01-09 05:28:08
【问题描述】:

我是 stackoverflow 社区的新手,一般来说也是编程新手。我的第一个项目是构建一个网络爬虫,看看我是否可以收集市场数据。在尝试构建它时,我一直陷入未绑定的本地错误。我知道这与我如何实例化我的类以及我如何引用变量有关,strong text 但不知道如何解决它..

class Stock:
    def __init__(self,symbol,company):
        self.symbol = symbol
        self.company = company
        self.data = []
            
            
    
    def query_stock_symbol(self):
        wait_time = round(max(5, 10 +random.gauss(0,3)), 2)
        time.sleep(wait_time)
        
        
        url = 'https://www.barrons.com/quote/stock/us/xnys/%s?mod=DNH_S'  % (self.symbol)
        page = requests.get(url)
        if page.status_code == 403 or page.status_code == 404:
            url = 'https://www.barrons.com/quote/stock/us/xnas/%s?mod=DNH_S' % (self.symbol)
       
        user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
        headers = {'User-Agent': user_agent}
        req = urllib.request.Request(url,headers=headers)
        
        try:
            response = urllib.request.urlopen(req)
        except urllib.error.URLError as e:
            print(e.reason)
           
        self.soup = BeautifulSoup(response, 'html.parser')
           
        
#         Finding stock price
        for a in self.soup.findAll('span',{'class':'market_price'}):
            stock_price_str = a.text.replace(',','')
            if stock_price_str != 'N/A':
                self.stock_price = float(stock_price_str)
            else:
                self.stock_price = None

我收到的错误是这样的

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-277-f9c756bf109f> in <module>
      1 x = Stock('CRM','Salesforce')
----> 2 x.query_stock_symbol()
      3 

<ipython-input-276-1f910b91d713> in query_stock_symbol(self)
     26             print(e.reason)
     27 
---> 28         self.soup = BeautifulSoup(response, 'html.parser')
     29 
     30 

UnboundLocalError: local variable 'response' referenced before assignment
```


Thanks for all your time and consideration, I really do appreciate it

【问题讨论】:

  • 请将edit所有代码和错误以文本形式写入问题本身。
  • 嗨!欢迎来到 SO :) Here 您可以找到编写好问题的指南并增加获得好答案的机会。例如,您应该在此处添加您的代码(不是图片),以便其他用户可以轻松地在您的代码中重现错误或问题。
  • 大家好,感谢您的提示,仍在尝试掌握一切,但希望这更符合预期。
  • 这个query_stock_symbol(self,response="")怎么样?

标签: python class web-scraping


【解决方案1】:

这是因为您在 try 块中声明了 response,而您尝试在该块之外 使用它,您可以:

1- 在try 块内使用之前全局声明response,如下所示:

try:
    global response
    response = ...
except ...:
    ...
self.soup = ....

2- 在 try 块内实例化 Soup 对象,如下所示 response 赋值:

try:
    response = ...
    self.soup = BeautifulSoup(response, 'html.parser')

3- 在try 块之前声明response 变量,这是一种更成问题的方法,并且在未正确分配响应时可能会导致问题(例如在引发exception 时),但是如果您决定为此,您可以执行以下操作:

response = None
try:
    response = ...
except ...:
    .....
self.soup = ...

永远记住,本地声明的变量,如try 块、if 块、else 块等在所述块之外无法访问,它们是 本地到那个block

【讨论】:

  • 感谢您的快速回复!但是,我很感激;当我尝试您建议的第一次编辑时,我收到一条错误消息,说我的对象库存现在没有汤,因为我相信根据您之前的评论,汤现在是该 try 块的本地。我该如何解决这个问题?
  • 啊,是的,我的错在这里没有预见到,我认为最佳解决方案是使用关键字global,我已经编辑了我的答案
【解决方案2】:

您应该处理urllib.request.urlopen 引发的错误:如果此方法引发错误,您只需打印它并继续执行您的代码。但是,这意味着 try 块中的所有指令可能还没有执行,response 还没有定义。

例如,此代码按预期工作:

try:
    a = 10
except Exception:
    print(e)

print(a)

输出是:

10

所以变量a 是在打印时定义的;另一方面,这段代码引发了一个错误,就像你正在试验的那样:

try:
    a = 10 / 0
except Exception as e:
    print(e)

print(a)
division by zero
Traceback (most recent call last):
  File "try_catch_example.py", line 6, in <module>
    print(a)
NameError: name 'a' is not defined

所以,真正的问题是,当try 块中的某些内容失败时,您必须决定该怎么做。

在您的情况下,仅打印错误是不够的;您可能应该中断该方法,发出警告或重新提出更多“注释”错误:

        try:
            response = urllib.request.urlopen(req)
        except urllib.error.URLError as e:
            print('Something wrong with urlopen! Read carefully the reason of the error')
            print(f'req: {req}')
            print(e.reason)
            raise RuntimeError('Failed to open the required url') from exc

【讨论】:

  • 非常感谢您的反馈,这非常有帮助,并且会相应地调整我的代码以处理异常。
猜你喜欢
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多