Windows下Python脚本运行数分钟后控制台冻结无法正常退出求助
作为渗透测试同行,我完全理解你遇到的这个头疼问题——Linux下跑的好好的批量扫描脚本,到Windows就莫名卡死,还没法正常退出。结合你的代码和描述,我梳理了几个最可能的原因,以及对应的修复方案:
核心问题分析
你的脚本在Windows上的无响应,大概率和资源泄漏、线程管理不当、控制台输出阻塞这几个点有关,毕竟Windows和Linux的线程模型、网络资源管理差异很大。
1. 线程池资源未正确回收
你用了multiprocessing.dummy.Pool(本质是线程池),但代码里没有显式关闭和等待线程结束。Windows下未回收的线程会持续占用系统资源,积累到一定程度就会导致脚本假死。
修复代码:
def Main(): try: start = timer() ThreadPool = Pool(30) Threads = ThreadPool.map(sitebul, ooo) # 新增:关闭线程池并等待所有线程完成 ThreadPool.close() ThreadPool.join() print('Time: ' + str(timer() - start) + ' seconds') except Exception as e: # 不要隐藏异常!打印出来方便排查 print(f"Main function error: {str(e)}")
2. 网络请求资源泄漏(混合使用requests和urllib2)
你的代码同时用了requests和urllib2,两种库的资源管理逻辑不同,高并发下容易出现socket连接未释放的情况。另外,没有给请求加超时,一旦某个请求卡住,整个线程就会挂起。
修复代码:
# 全局初始化requests会话池,复用连接 import requests session = requests.Session() session.headers.update({'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:28.0) Gecko/20100101 Firefox/28.0'}) def sitebul(url): try: # 用session.get替代requests.get,添加超时避免线程挂死 baaReflexlibr = session.get(url, timeout=10) # 触发HTTP错误异常,避免隐藏请求失败的情况 baaReflexlibr.raise_for_status() if "/wp-content/" in baaReflexlibr.text: print(f"{fg}{fg}{url}{fc}{fc}{sb}{fr}") wpsbot(url) else: print(f"{sb}{sd}{url}{fc}{fc}{sb}{fr}") except requests.exceptions.RequestException as e: print(f"Request failed for {url}: {str(e)}") except Exception as e: print(f"Unexpected error for {url}: {str(e)}")
把
urllib2的代码全部替换成requests,统一用会话池管理连接,减少资源消耗。
3. 彩色输出导致控制台阻塞
Windows控制台对彩色输出的支持远不如Linux,colorama的init(autoreset=True)在30线程并发打印时,很容易导致输出缓冲区堆积,进而引发脚本假死。
优化方案:
- 减少高频控制台输出,把扫描结果写到日志文件:
import logging # 初始化日志 logging.basicConfig( filename="wp_scan.log", level=logging.INFO, format="%(asctime)s - %(message)s" ) # 替换所有print为logging.info logging.info(f"WordPress site detected: {url}")
- 如果必须保留控制台彩色输出,尝试降低线程数(比如从30降到15),或者去掉
init(autoreset=True),手动控制颜色重置。
4. 空except隐藏了关键错误
你的代码里大量使用except: pass,这会把所有错误都吞掉,包括线程挂死、资源耗尽的异常,导致你根本不知道问题出在哪。一定要捕获具体异常并打印日志。
修复示例:
# 不要用空except,捕获具体异常类型 except requests.exceptions.Timeout: print(f"Timeout for {url}") except requests.exceptions.ConnectionError: print(f"Connection failed for {url}") except Exception as e: print(f"Unknown error: {str(e)}")
5. Windows网络端口限制(可选)
Windows默认的动态端口范围比Linux小,高并发扫描时容易耗尽本地端口,导致后续请求无法建立连接。可以通过命令扩大端口范围:
# 以管理员身份打开命令提示符执行 netsh int ipv4 set dynamicport tcp start=1024 num=64511 netsh int ipv4 set tcp timestamps=disabled
最终建议
先从修复线程池回收、统一网络请求库、移除空except这三点入手,这是最可能解决问题的核心步骤。如果还是不行,再尝试优化控制台输出或者改用multiprocessing.Pool(进程池)替代线程池(进程池的资源隔离性更好,但开销略大)。
内容的提问来源于stack exchange,提问作者Seif Akacha




