Python多线程请求脚本随机崩溃问题排查与解决咨询
多线程登录请求脚本崩溃的解决方案
问题重现代码
import requests import threading url = 'example.url' username = input('Enter Username:') data= { 'UserName': 'username', 'Password': 'JJJJJJJJJ', 'AuthMethod': 'FormsAuthentication', } def do_request(): while True: response = requests.post(url, data=data).text print(response) threads = [] for i in range(50): t = threading.Thread(target=do_request) t.daemon = True threads.append(t) for i in range(50): threads[i].start() for i in range(50): threads[i].join()
崩溃原因分析
脚本无预期崩溃的核心原因是未处理网络异常:VPN负载过高或波动时,会引发请求超时、连接中断、DNS解析失败等错误,当前代码直接调用requests.post却未捕获任何异常,一旦出错就会导致线程崩溃,最终引发整个程序退出。此外,50个线程无限制发起请求会进一步加剧VPN和目标服务器的负载,放大出错概率。
修复方案
1. 给请求添加异常捕获与重试机制
在请求逻辑中捕获所有网络相关异常,对失败请求进行有限次数重试,避免单次错误导致线程崩溃:
import requests import threading from requests.exceptions import RequestException import time url = 'example.url' username = input('Enter Username:') data= { 'UserName': username, # 修复原代码硬编码用户名的bug 'Password': 'JJJJJJJJJ', 'AuthMethod': 'FormsAuthentication', } def do_request(): while True: max_retries = 3 retry_count = 0 success = False while retry_count < max_retries and not success: try: # 添加超时时间,避免请求无限阻塞 response = requests.post(url, data=data, timeout=10).text print(response) success = True except RequestException as e: retry_count += 1 print(f"请求失败,重试第{retry_count}次:{str(e)}") time.sleep(2) # 重试间隔,降低瞬时负载 if not success: print("多次重试失败,暂停30秒后继续") time.sleep(30) # 长时间暂停,避免持续消耗VPN资源 time.sleep(1) # 每次请求循环后添加间隔,控制请求频率
2. 优化线程并发数
原代码启动50个线程过于激进,会大幅增加VPN负载。建议根据实际带宽调整线程数量(比如10-20个),同时使用线程池管理线程,比手动创建线程更稳定:
from concurrent.futures import ThreadPoolExecutor def main(): # 限制最大并发线程数为15 with ThreadPoolExecutor(max_workers=15) as executor: for _ in range(15): executor.submit(do_request) if __name__ == "__main__": main()
3. 额外稳定性优化
- 监控VPN状态:可以在脚本中定期ping一个稳定的外部节点(比如
8.8.8.8),如果连续几次ping失败,说明VPN可能异常,此时暂停所有请求,直到恢复后再继续 - 日志记录:将请求结果和错误信息写入日志文件,方便后续排查崩溃原因
- 避免高频请求:过于密集的请求不仅会让VPN过载,还可能触发目标网站的反爬机制,根据测试需求合理调整请求间隔
内容的提问来源于stack exchange,提问作者Spoob Spooby
相关产品推荐
相关产品推荐

