You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Windows下Python脚本运行数分钟后控制台冻结无法正常退出求助

解决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)

你的代码同时用了requestsurllib2,两种库的资源管理逻辑不同,高并发下容易出现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,coloramainit(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

火山引擎 最新活动