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

DRM环境下Selenium+Pyinstaller打包exe后PDF下载损坏求助

Pyinstaller打包Selenium程序后PDF下载损坏的问题排查与解决方案

问题描述

我开发了一款使用Selenium爬取网站信息并自动下载PDF附件的Python程序,在VS Code中运行完全正常,但通过Pyinstaller打包为exe可执行文件后,下载的PDF文件损坏无法打开。企业环境下所有文档会自动应用DRM保护,已尝试Pyinstaller的--hidden-import选项,问题仍未解决。

测试情况

  • Case 1:通过Pyinstaller生成的exe启动Chrome并自动下载PDF,文件损坏无法打开;
  • Case 2:通过exe启动Chrome后手动下载PDF,文件同样损坏无法打开;
  • Case 3:手动打开Chrome访问网站下载同一PDF,文件可正常打开,说明原始PDF文件无问题。

核心代码(浏览器初始化部分)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.common.action_chains import ActionChains
import chromedriver_autoinstaller #type: ignore
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import openpyxl, pandas, requests, threading, datetime, xlwings # 외부 라이브러리
import os, time, shutil, getpass # 기본 라이브러리
from concurrent import futures
import sys, os

current_dir = "D:\\Python"
directory = current_dir.replace("\\","/",10) + "/"
chrome_down_path = current_dir+"\\Downloads"
down_path = directory+"Downloads/"

PartNumber = "JANTXV1N4616UR-1"
url = 'https://www.doeeet.com/home'

chrome_ver = chromedriver_autoinstaller.get_chrome_version().split(".")[0] #type:ignore
driver_path = f'./{chrome_ver}/chromedriver.exe'
if os.path.exists(driver_path):
    print(f"chrom driver is insatlled: {driver_path}") 
else:
    print(f"install the chrome driver(ver: {chrome_ver})")
    chromedriver_autoinstaller.install(True)

chrome_options = Options()
profile = {
            #"plugins.plugins_list": [{"enabled": False, "name": "Chrome PDF Viewer"}], # Disable Chrome's PDF Viewer
            "download.default_directory": chrome_down_path, #r"C:\Users\yunji.lim\Desktop\Data\Downloads",
            "download.prompt_for_download": False, #To auto download the file
            "download.directory_upgrade":True,
            "plugins.always_open_pdf_externally": True,
            "download.extensions_to_open": "applications/pdf"
            }
chrome_options.add_experimental_option("prefs",profile)
chrome_options.add_experimental_option("detach",True)
browser = webdriver.Chrome(driver_path, options=chrome_options)
browser.maximize_window()
browser.implicitly_wait(5)
browser.get(url)

try : 
    WebDriverWait(browser,5).until(
        EC.presence_of_element_located((By.XPATH,'//*[@id="ngrv_"]/a'))
    )
finally : 
    element = browser.find_element(By.XPATH,'//*[@id="ngrv_"]/a')
    element.send_keys("\n")
    element = browser.find_element(By.XPATH,'//*[@id="_58_login"]')
    element.clear()
    element.send_keys(user_id)
    element = browser.find_element(By.XPATH,'//*[@id="_58_password"]')
    element.send_keys(user_pw)
    element.send_keys("\n")

try : # 검색 가능한 상태까지 Wait (wait time : max 15sec)
    WebDriverWait(browser,15).until(
        EC.presence_of_element_located((By.NAME,'q'))
)
except :
    pass
finally : # 검색 가능한 상태에 도달 하면 Part Number 검색 수행
    element = browser.find_element(By.NAME,'q')
    element.send_keys(PartNumber)
    element.send_keys("\n")
    
    try : # Part Number 검색 결과가 로드 될 때 까지 대기 (wait time : max 15sec)
        WebDriverWait(browser,25).until(
            EC.presence_of_element_located((By.LINK_TEXT, PartNumber))
        )
    except :
        pass
    finally : # 클릭 가능한 상태에 도달하면 검색 결과 클릭
        search_res = browser.find_elements(By.LINK_TEXT, PartNumber)

可行解决方案

1. 统一Chrome用户配置文件

Pyinstaller打包的exe启动的Chrome使用临时隔离配置,和手动打开的Chrome环境不一致,企业DRM可能依赖本地配置的认证信息。解决方法:

# 在ChromeOptions中添加现有用户配置路径
chrome_options.add_argument(r"--user-data-dir=C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data")
chrome_options.add_argument(r"--profile-directory=Default")

注意:启动exe前需关闭所有手动打开的Chrome窗口,避免配置文件被占用。

2. 修复PDF下载偏好配置

移除冲突的配置项,确保下载路径权限充足:

# 调整profile配置
profile = {
    "download.default_directory": chrome_down_path,
    "download.prompt_for_download": False,
    "download.directory_upgrade": True,
    "plugins.always_open_pdf_externally": True
}
# 提前创建下载目录,避免权限不足
if not os.path.exists(chrome_down_path):
    os.makedirs(chrome_down_path)

3. 优化ChromeDriver加载逻辑

改用webdriver-manager管理驱动,避免打包后的路径依赖问题:

# 替换原驱动加载代码
from selenium.webdriver.chrome.service import Service
service = Service(ChromeDriverManager().install())
browser = webdriver.Chrome(service=service, options=chrome_options)

4. 调整Pyinstaller打包参数

  • 优先使用--onedir打包,减少临时路径问题:
    pyinstaller --onedir --hidden-import=selenium --hidden-import=chromedriver_autoinstaller --hidden-import=webdriver_manager your_script.py
    
  • 若使用--onefile,需在代码中处理运行时路径:
    if getattr(sys, 'frozen', False):
        current_dir = os.path.dirname(sys.executable)
    else:
        current_dir = os.path.dirname(os.path.abspath(__file__))
    

5. 隐藏Selenium自动化特征

企业DRM可能检测自动化环境,添加参数规避检测:

chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# 启动后移除webdriver标记
browser.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:56:57