Python自动注册函数递归调用后无法正常退出问题求助
问题根源
你的核心问题出在递归调用后的执行流程没有终止。举个具体场景:
- 第一次调用
create_account(),遇到未知验证码类型,触发递归调用create_account() - 第二次递归调用成功完成注册,执行
return退出了这个函数实例 - 但第一次调用的函数会从递归的位置继续往下执行——也就是继续发送POST请求、处理返回文本,此时的
text还是之前的错误内容,于是又触发了重试逻辑,导致流程无法正常终止。
另外你尝试的koniec变量之所以没用,是因为它是函数内部的局部变量,每次递归都会创建新的实例,上层函数的koniec不会被修改,自然无法阻止后续代码执行。
修复方案
推荐用循环替代递归(更易维护,避免栈溢出风险),如果坚持用递归,也需要在递归调用后立即终止当前函数流程。
方案1:用循环替代递归(优先推荐)
把递归逻辑改成while True循环,整个流程在一个函数实例内运行,成功后直接break退出即可:
def create_account(): global login global password global email print('# REJESTROWANIE NOWEGO KONTA') while True: # 循环直到注册成功 s = requests.Session() headers = { 'Accept-Encoding': 'gzip, deflate, sdch', 'Accept-Language': 'en-US,en;q=0.8', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', } s.headers.update(headers) r = s.get(REGISTER_URL) soup = BeautifulSoup(r.content, "html.parser") # 处理验证码 captcha_img = soup.find("img",{"alt":"captcha"})['src'] nazwa = basename(captcha_img) capublic = str(os.path.splitext(nazwa)[0]) with open('/root/environments/captcha_img/'+nazwa,"wb") as f: f.write(requests.get('https://www.mywebsite.net/'+captcha_img).content) captcha_text = '' try: captcha_text = captcha('captcha_img/'+nazwa) # 只删除当前验证码文件,避免误删其他文件 os.remove(os.path.join('/root/environments/captcha_img/', nazwa)) except: print('> nieznany typ captcha') print('> ponawiam') continue # 跳过本次循环,重新开始流程 # 提交注册请求 data={ "jscheck": '1', "login": login, "pass": password, "pass2": password, "email": email, "cacheck": captcha_text, "capublic": capublic, 'button_submit': 'Sign+Up+(Free)', } r = s.post(REGISTER_URL, headers=headers, data=data) text = str(r.content) # 处理返回结果 if "Your registration was successful" in text: print('# ZAREJESTROWANO') print('> login: '+login+', hasło: '+password+', email: '+email) break # 注册成功,退出循环 elif "The supplied Captcha is wrong." in text: print('# BŁĘDNE CAPTCHA') print('> ponawiam') elif "Please fill out both Passwordfields." in text: print('# NIE WPISANO HASŁA') print('> ponawiam') elif "The supplied Passwords do not match." in text: print('# HASŁA NIE SĄ TAKIE SAME') print('> ponawiam') elif "Please enter your Username." in text: print('# NIE WPISANO LOGINU') print('> ponawiam') elif "The Username is already in use." in text: print('# LOGIN ZAJĘTY') print('> generuję nowy login') login = get_uname(5, 10, False) print('> ponawiam') elif "The supplied E-Mail is already in use." in text: print('# ADRES EMAIL ZAJĘTY') print('> pobieram nowy adres e-mail') email = get_email() print('> ponawiam') else: print('# INNY NIEZNANY BŁĄD') print('> generuję nowe dane logowania') login = get_uname(5, 10, False) password = get_password(8) email = get_email() print('> ponawiam')
方案2:保留递归但添加终止逻辑
如果一定要用递归,每次递归调用后必须立即return,阻止当前函数继续执行后续代码:
# 示例:在未知验证码异常块中添加return except: print('> nieznany typ captcha') print('> ponawiam') create_account() return # 递归后立即返回,不让当前函数继续执行 # 同理,每个错误分支的递归调用后都要加return elif "The supplied Captcha is wrong." in text: print('# BŁĘDNE CAPTCHA') print('> ponawiam') create_account() return
额外优化建议
- 尽量避免使用
global变量,可将login、password、email作为函数参数传递,或封装成类,提升代码健壮性 - 添加重试次数限制,防止无限循环/递归导致栈溢出
- 验证码文件清理只针对当前下载的文件,避免误删其他文件
内容的提问来源于stack exchange,提问作者Daniel Koczuła
相关产品推荐
相关产品推荐

