You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pyinstaller编译含Selenium与Multiprocessing的Python脚本为EXE后无法运行

Pyinstaller打包含Selenium+Multiprocessing脚本无响应问题解决

以下是针对你遇到的打包后EXE无反应问题的具体解决步骤:

1. 修复多进程打包适配问题

Windows下Pyinstaller对multiprocessing的支持需要额外处理,否则会导致进程无法正常启动:

  • 在if __name__ == '__main__':代码块第一行添加multiprocessing.freeze_support()
  • 避免直接用len(urls)设置进程数(可能因链接过多导致资源耗尽),建议设为CPU核心数或固定值(比如4)

2. 解决ChromeDriver路径依赖

打包后EXE无法直接找到chromedriver.exe,需处理路径并确保打包时包含驱动文件:

  • 修改代码动态获取驱动路径:
    import sys
    import os
    
    def get_chromedriver_path():
        if getattr(sys, 'frozen', False):
            # 打包后环境,取临时解压目录
            base_path = sys._MEIPASS
        else:
            # 开发环境,取脚本所在目录
            base_path = os.path.dirname(os.path.abspath(__file__))
        return os.path.join(base_path, 'chromedriver.exe')
    
    然后将webdriver.Chrome("chromedriver.exe", ...)替换为webdriver.Chrome(get_chromedriver_path(), ...)
  • 打包命令需添加驱动文件的打包参数(Windows):
    pyinstaller --add-data "chromedriver.exe;." your_script.py
    

3. 开启控制台查看错误信息

如果之前用了-w参数打包(无窗口模式),会屏蔽所有报错输出,导致无法定位问题:

  • 去掉-w参数重新打包:pyinstaller your_script.py
  • 运行生成的EXE,通过控制台输出的错误信息排查具体问题

4. 优化Headless模式参数

旧版Headless模式可能存在兼容性问题,添加额外参数保证稳定运行:

options = webdriver.ChromeOptions()
options.add_argument('--headless=new')  # 使用新版Headless模式,兼容性更好
options.add_argument('window-size=1920x935')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

打包后EXE的工作目录可能与脚本不同,需动态获取文件路径:

def get_links_path():
    if getattr(sys, 'frozen', False):
        # 打包后取EXE所在目录
        base_path = os.path.dirname(sys.executable)
    else:
        # 开发环境取脚本所在目录
        base_path = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(base_path, 'links.txt')

links = open(get_links_path(), encoding='utf-8', errors='ignore')

修改后的完整代码

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from multiprocessing import Pool, freeze_support
import time
import sys
import os

def get_chromedriver_path():
    if getattr(sys, 'frozen', False):
        base_path = sys._MEIPASS
    else:
        base_path = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(base_path, 'chromedriver.exe')

def get_links_path():
    if getattr(sys, 'frozen', False):
        base_path = os.path.dirname(sys.executable)
    else:
        base_path = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(base_path, 'links.txt')

def start(url):
    url = url.strip()  # 去除链接中的换行符,避免无效请求
    options = webdriver.ChromeOptions()
    options.add_argument('--headless=new')
    options.add_argument('window-size=1920x935')
    options.add_argument('--disable-gpu')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    
    browser = webdriver.Chrome(get_chromedriver_path(), options=options)
    wait = WebDriverWait(browser, 10)
    try:
        browser.get(url)
        browser.switch_to.window(browser.window_handles[-1])
        wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="movie_player"]/div[33]/div[2]/div[1]/button'))).click()
        wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="movie_player"]/div[33]/div[2]/div[1]/span/button'))).click()
        time.sleep(180)
    except Exception as e:
        print(f"处理链接 {url} 时出错: {e}")
    finally:
        browser.quit()

if __name__ == '__main__':
    freeze_support()  # 必须放在多进程启动前
    urls = []
    try:
        with open(get_links_path(), encoding='utf-8', errors='ignore') as links:
            urls = [line.strip() for line in links if line.strip()]  # 过滤空行并去除换行
        
        if not urls:
            print("links.txt中无有效链接")
            sys.exit(1)
        
        # 限制进程数为CPU核心数或固定值,避免资源耗尽
        process_count = min(len(urls), os.cpu_count() or 4)
        with Pool(processes=process_count) as p:
            p.map(start, urls)
    except Exception as e:
        print(f"程序初始化出错: {e}")
        input("按回车退出...")  # 打包后控制台不会自动关闭,方便查看错误

内容的提问来源于stack exchange,提问作者NIKITA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 03:35:32