首页 > 解决方案 > UnboundLocalError:分配前引用的局部变量“req”

问题描述

我观看了一段视频,并尝试应用以下代码

# pip install html5lib
import requests
from bs4 import BeautifulSoup
from random import choice

def get_proxy():
    url = "https://www.sslproxies.org/"
    r = requests.get(url)
    soup = BeautifulSoup(r.content, 'html5lib')
    return {'https': choice(list(map(lambda x:x[0]+':'+x[1], list(zip(map(lambda x:x.text, soup.findAll('td')[::8]), map(lambda x:x.text, soup.findAll('td')[1::8]))))))}

def proxy_request(request_type, url, **kwargs):
    while 1:
        try:
            proxy = get_proxy()
            req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs)
            break
        except:
            pass
            return req

r = proxy_request('get', "https://youtube.com")
print(r)

我收到以下回溯错误,但我不知道

Traceback (most recent call last):
  File "C:\Users\Future\Desktop\Spyder\Demo.py", line 16, in proxy_request
    req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs)
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 412, in send
    conn = self.get_connection(request.url, proxies)
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 309, in get_connection
    proxy_manager = self.proxy_manager_for(proxy)
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 193, in proxy_manager_for
    manager = self.proxy_manager[proxy] = proxy_from_url(
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\poolmanager.py", line 492, in proxy_from_url
    return ProxyManager(proxy_url=url, **kw)
  File "C:\Users\Future\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\poolmanager.py", line 429, in __init__
    raise ProxySchemeUnknown(proxy.scheme)
urllib3.exceptions.ProxySchemeUnknown: Not supported proxy scheme None

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Future\Desktop\Spyder\Demo.py", line 22, in <module>
    r = proxy_request('get', "https://youtube.com")
  File "C:\Users\Future\Desktop\Spyder\Demo.py", line 20, in proxy_request
    return req
UnboundLocalError: local variable 'req' referenced before assignment
[Finished in 1.4s]

最终代码..

# pip install html5lib
import requests
from bs4 import BeautifulSoup
from random import choice

def get_proxy():
    url = "https://www.sslproxies.org/"
    r = requests.get(url)
    soup = BeautifulSoup(r.content, 'html5lib')
    return {'https': 'https://' + choice(list(map(lambda x:x[0]+':'+x[1], list(zip(map(lambda x:x.text, soup.findAll('td')[::8]), map(lambda x:x.text, soup.findAll('td')[1::8]))))))}

def proxy_request(request_type, url, **kwargs):
    proxy = get_proxy()
    req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs)
    return req

for __ in range(10):
    try:
        r = proxy_request('get', "https://api.ipify.org")
    except (TimeoutError, OSError) as e:
        print("Exception:", e)
        continue

    print(r.status_code)
    print(r.content)
    break

标签: pythonbeautifulsouppython-requests

解决方案


        try:
            proxy = get_proxy()
            req = requests.request(request_type, url, proxies=proxy, timeout=5, **kwargs)
            break
        except:
            pass
            return req

该语句位于异常处理程序中,这意味着只有在调用orreturn req期间引发异常时才会执行该语句。无论哪种方式,这些都将导致永远不会被束缚,因此.get_proxyrequests.requestreqUnboundLocalError

我希望你想把循环放在return req外面while,尽管我只是用它替换break它,这样做会导致更直接和更有弹性的行为。

还:

  • 裸机except是一个非常糟糕的主意,因为它会捕获诸如键盘中断(Ctrl-C)之类的事情,这意味着当(而不是如果!)您的程序搞砸时,您必须通过任务管理器。
  • 当引发异常时,您只是忙于循环,甚至没有通知用户正在发生的事情,没有UnboundLocalError它可以尽可能快地循环调用sslproxies,这是禁止滥用的好方法,特别是当 sslproxy 明确宣传时它的代理列表每 10 分钟更新一次。
  • 在列表中选择一个随机代理很好,但是为什么不存储要从中选择的代理列表呢?见上面的点,列表最多每 10 分钟更新一次,而且你没有做任何分页,你每次都会得到相同的列表。只需在循环外获取代理列表,然后从内部随机选择一个代理进行尝试。

推荐阅读