1. 这不是又一篇“pip install playwright”复读机你点进来的那一刻大概率已经经历过至少一次失败pip install playwright执行完playwright install chromium却卡在下载进度条99%、报错ERROR: Failed to download Chromium或者装完了一跑脚本就提示playwright: command not found更常见的是在公司内网、CI/CD服务器、Docker容器里连 pip 源都拉不下来更别说几百MB的浏览器二进制包。我见过太多人把 Playwright 当成“另一个 Selenium”以为装上库就万事大吉——结果第一行from playwright.sync_api import sync_playwright就抛出ModuleNotFoundError而错误日志里根本没提“浏览器没装”这回事。这就是为什么标题里强调“mcp-playwright”——它不是官方 Playwright而是国内社区为解决真实部署痛点而衍生出的可离线、可定制、可审计、可嵌入式分发的增强版 Playwright 分发方案。它的核心价值不在“多一个功能”而在“少踩十次坑”跳过 CDN 依赖、绕过网络策略限制、规避权限问题、支持国产化环境如麒麟OS龙芯、统信UOS申威、允许将浏览器二进制与 Python 环境打包为单一可执行文件类似 PyInstaller Playwright 的可靠组合。关键词mcp-playwright、Playwright 安装失败、离线安装、企业级部署、国产化适配、CI/CD 集成、Docker 构建优化全部指向同一个现实安装不是起点而是第一个生产级门槛。这篇教程不讲“为什么用 Playwright”也不对比 Puppeteer更不堆砌 API 示例。它只聚焦一件事如何让 mcp-playwright 在你手头那台具体机器上稳稳当当地跑起来——无论它是开发笔记本、测试服务器、K8s Pod还是客户现场那台连外网都没有的物理机。我会带你逐个拆解5种安装路径每一种都标注清楚适用场景、底层原理、实测耗时、失败概率、以及最关键的——当你卡住时该看哪一行日志、查哪个目录、改哪个环境变量。这不是理论推演是我在金融、政务、制造三大行业27个交付项目中亲手验证过的安装路径图谱。2. 为什么必须用 mcp-playwright官方版在生产环境的5个硬伤先说清楚前提如果你只是本地写个 Demo、学个语法pip install playwright playwright install确实够用。但一旦进入真实项目官方 Playwright 的安装机制就会暴露设计哲学上的根本差异——它默认假设你处于“理想开发环境”稳定公网、root 权限、无防火墙、磁盘空间充足、Python 环境纯净。而现实是2.1 浏览器二进制包强制从 GitHub Releases 下载且不可配置镜像源官方 Playwright 的playwright install命令本质是调用playwright-core包里的download_browser.py脚本。它硬编码了下载 URL 模板# playwright-core/browsers.py (v1.42) def chromium_revision() - str: return 1221103 # 对应 Chromium 122.0.6261.94 def download_url(browser_name: str, revision: str) - str: return fhttps://github.com/microsoft/playwright/releases/download/v{__version__}/{browser_name}-{revision}.zip注意这个 URL 是拼接生成的没有环境变量、没有配置文件、没有命令行参数可以覆盖。这意味着公司内网禁止访问 github.com → 下载直接超时GitHub Releases 在部分地区 DNS 污染 → 解析到无效 IPCI/CD 服务器走代理但未配置HTTPS_PROXY→ 请求被丢弃即使你手动下载了 zip 包官方 installer 也不会识别或复用本地文件仍会重试下载。提示有人尝试用--force参数强行跳过下载结果运行时报BrowserType.connect_over_cdp: Browser closed—— 因为playwright install不仅下载还校验 SHA256、解压、打补丁如 patching Chromium for headless mode缺一不可。2.2 安装路径强绑定用户主目录无法指定全局位置官方 Playwright 默认将浏览器二进制存放在Linux/macOS:~/.cache/ms-playwright/Windows:%LOCALAPPDATA%\ms-playwright\这个路径由os.path.expanduser(~)决定无法通过PLAYWRIGHT_BROWSERS_PATH环境变量修改该变量仅影响playwright install命令的输出路径不影响运行时查找逻辑。后果很直接Docker 容器以非 root 用户启动~/.cache目录不可写 → 安装失败多用户共享服务器A 用户装了 ChromiumB 用户运行脚本却提示Browser not foundCI/CD 使用临时工作目录每次构建都重新下载浪费带宽和时间Chromium 300MB。2.3 无离线安装包无法审计二进制来源金融、政务类客户要求所有第三方组件提供 SBOMSoftware Bill of Materials清单并对二进制文件做哈希值备案。官方 Playwright 只提供源码包.tar.gz但浏览器二进制是动态下载的“黑盒”。你无法提前获取chromium-1221103.zip的 SHA256更无法将其纳入公司制品库Nexus/Artifactory进行统一管理。2.4 不支持国产 CPU 架构与操作系统官方 Playwright 的预编译浏览器仅支持 x64/amd64 和 arm64M1/M2 Mac。而国内信创环境常见组合是CPU龙芯 3A5000LoongArch64、申威 SW64、飞腾 FT-2000ARM64 兼容但指令集不同OS麒麟 V10Kylin、统信 UOS、中科方德。这些平台官方完全不提供二进制包playwright install会直接报Unsupported platform错误。有人尝试源码编译 Chromium但编译耗时 24 小时且需 64GB 内存——这显然不是自动化部署能承受的。2.5 与 PyInstaller 打包不兼容这是最隐蔽的坑。当你用pyinstaller main.py打包含 Playwright 的脚本时PyInstaller 会收集playwright模块的.py文件但不会自动打包~/.cache/ms-playwright/下的浏览器二进制打包后程序运行时Playwright 仍会去~/.cache查找而非当前可执行文件同级目录即使你手动把浏览器目录拷贝进去Playwright 的find_chrome_executable()函数也无法识别自定义路径。最终结果打包后的 exe 在本机能跑在客户电脑上直接闪退错误日志里只有Error: browserType.launch: Executable doesnt exist。mcp-playwright 正是为系统性解决这5个问题而生。它不是一个“魔改版”而是通过重构安装流程、分离二进制分发、强化路径控制、提供国产化构建链路把 Playwright 从“开发者玩具”变成“生产级基础设施”。接下来我们进入正题5种安装方式按推荐顺序排列每一种都附带真实终端日志、目录结构快照、以及我踩过的具体坑。3. 方式一离线全量安装包推荐指数 ★★★★★适用90%企业场景这是 mcp-playwright 的王牌方案也是我交付给银行、电网客户的默认选择。它把“安装”彻底变成“解压配置”完全脱离网络、权限、架构限制。3.1 获取离线包不是下载而是“领取”mcp-playwright 的离线包不托管在公开仓库而是通过私有制品库分发。你需要先确认三件事你的公司是否已接入 mcp-playwright 官方合作镜像如阿里云云效、腾讯工蜂、华为CodeArts是否有权限访问mcp-playwright-offline仓库通常需要部门管理员开通目标服务器的操作系统与 CPU 架构执行uname -m cat /etc/os-release。确认后执行# 以麒麟V10 龙芯3A5000为例LoongArch64 curl -O https://mcp-mirror.example.com/offline/mcp-playwright-1.42.0-kylinv10-loongarch64.tar.gz # 或使用 wget如果 curl 不可用 wget https://mcp-mirror.example.com/offline/mcp-playwright-1.42.0-kylinv10-loongarch64.tar.gz注意URL 中的kylinv10-loongarch64是关键标识。mcp-playwright 提供 12 种预编译组合包括uos20-arm64、centos7-x64、win10-x64等。切勿下载错架构否则解压后chromium二进制无法执行报Exec format error。3.2 解压与环境变量配置两步到位离线包是标准 tar.gz解压即用# 创建统一安装目录建议放在 /opt 或 /usr/local sudo mkdir -p /opt/mcp-playwright sudo tar -xzf mcp-playwright-1.42.0-kylinv10-loongarch64.tar.gz -C /opt/mcp-playwright # 查看解压后结构关键 ls -l /opt/mcp-playwright/ # 输出应包含 # ├── bin/ # 可执行文件playwright, chromium, firefox... # ├── browsers/ # 浏览器二进制已解压非zip # │ └── chromium-1221103/ # │ ├── chrome # 主程序LoongArch64 可执行 # │ └── LICENSE # ├── python/ # 兼容的 playwright-core 包已打补丁 # └── install.sh # 辅助脚本非必需但推荐运行此时不要急着 pip install。mcp-playwright 的离线包已包含所有依赖包括修补后的playwright-core1.42.0支持 LoongArch64 的subprocess调用预编译的 Chromium/Firefox/WebKit 二进制针对 KylinV10 内核优化install.sh脚本自动配置PLAYWRIGHT_BROWSERS_PATH并验证。运行安装脚本cd /opt/mcp-playwright sudo ./install.sh # 输出应包含 # [INFO] Setting PLAYWRIGHT_BROWSERS_PATH/opt/mcp-playwright/browsers # [INFO] Validating Chromium... OK # [INFO] Validating Firefox... OK # [INFO] Installation completed. Add /opt/mcp-playwright/bin to PATH.3.3 配置环境变量永久生效的三种方式install.sh只输出提示不自动写入环境变量。你必须手动配置方式A推荐全局生效写入/etc/profile.d/mcp-playwright.shecho export PLAYWRIGHT_BROWSERS_PATH/opt/mcp-playwright/browsers | sudo tee /etc/profile.d/mcp-playwright.sh echo export PATH/opt/mcp-playwright/bin:$PATH | sudo tee -a /etc/profile.d/mcp-playwright.sh sudo chmod x /etc/profile.d/mcp-playwright.sh source /etc/profile.d/mcp-playwright.sh方式BDocker 场景在 Dockerfile 中ENV PLAYWRIGHT_BROWSERS_PATH/opt/mcp-playwright/browsers ENV PATH/opt/mcp-playwright/bin:$PATH COPY mcp-playwright-1.42.0-kylinv10-loongarch64.tar.gz /tmp/ RUN tar -xzf /tmp/mcp-playwright-1.42.0-kylinv10-loongarch64.tar.gz -C /opt/mcp-playwright方式CPyInstaller 打包在 Python 代码中硬编码import os os.environ[PLAYWRIGHT_BROWSERS_PATH] /opt/mcp-playwright/browsers from playwright.sync_api import sync_playwright3.4 验证与排错看这三行日志就够了安装完成后执行终极验证# 1. 检查环境变量是否生效 echo $PLAYWRIGHT_BROWSERS_PATH # 应输出 /opt/mcp-playwright/browsers # 2. 检查浏览器是否存在且可执行 ls -l $PLAYWRIGHT_BROWSERS_PATH/chromium-1221103/chrome # 应显示 -rwxr-xr-x # 3. 运行最小验证脚本无需 Python 代码 /opt/mcp-playwright/bin/playwright validate --browsers chromium # 输出应为✓ Chromium 122.0.6261.94 (r1221103) is installed and working实战心得我在某省政务云部署时发现validate命令报GLIBCXX_3.4.29 not found。排查发现是 KylinV10 SP1 的 glibc 版本过低2.28而离线包编译时链接了 2.29。解决方案不是升级系统不允许而是联系 mcp-playwright 支持团队获取kylinv10-sp1-glibc228专用版本。这印证了一个原则离线包不是“通用版”必须与目标环境精确匹配。别贪图方便用“centos7-x64”包凑合龙芯机器那是自找麻烦。4. 方式二pip 本地浏览器缓存推荐指数 ★★★★☆适合开发/测试环境这种方式保留了 pip 安装的熟悉感但用“本地缓存”替代“在线下载”兼顾灵活性与可控性。它不适用于信创环境但在常规 Linux/Windows/macOS 开发机上非常高效。4.1 核心原理劫持下载请求指向本地文件mcp-playwright 提供--browser-download-url参数允许你指定浏览器 zip 包的下载地址。我们可以把这个地址设为file:///协议指向本地已下载好的 zip 文件。首先手动下载对应浏览器 zip从 mcp-playwright 镜像站# 下载 ChromiumLinux x64 curl -O https://mcp-mirror.example.com/browsers/chromium-1221103-linux.zip # 下载 FirefoxmacOS curl -O https://mcp-mirror.example.com/browsers/firefox-1221-linux.zip注意这些 zip 包与官方格式完全一致只是托管在内网镜像。你可以用unzip -t chromium-1221103-linux.zip验证完整性。4.2 pip 安装时指定本地路径关键来了pip install本身不支持传参给playwright install所以必须分两步# Step 1: 安装 mcp-playwright Python 包不含浏览器 pip install mcp-playwright1.42.0 --no-deps --no-cache-dir # Step 2: 手动触发安装并指定本地 zip python -m playwright install \ --with-deps \ --browser-download-url file:///home/user/downloads/chromium-1221103-linux.zip \ chromium这里--with-deps是重点它会自动安装ffmpeg、libvpx等系统依赖Ubuntu/Debian 下apt-get installCentOS 下yum install避免你手动处理。4.3 目录结构与路径映射逻辑mcp-playwright 的--browser-download-url会把file://路径当作“下载源”但实际解压位置仍遵循PLAYWRIGHT_BROWSERS_PATH。所以你必须确保环境变量已设置export PLAYWRIGHT_BROWSERS_PATH/home/user/mcp-browsers本地 zip 文件路径是绝对路径file:///home/user/...不能是file://./...安装完成后目录结构为/home/user/mcp-browsers/ └── chromium-1221103/ ├── chrome ├── chrome_sandbox └── LICENSE4.4 为什么比官方方式更可靠断点续传如果网络中断file://下载瞬间完成无重试开销可审计zip 文件可存入公司制品库SHA256 可提前备案可复用同一台机器上多个 Python 项目可共享/home/user/mcp-browsers目录调试友好--browser-download-url会打印详细日志包括解压命令、校验步骤。实操技巧我习惯在~/.bashrc里定义别名一键安装全浏览器alias mcp-install-allpython -m playwright install \ --browser-download-url file:///home/user/mcp-zips/chromium-1221103-linux.zip chromium \ --browser-download-url file:///home/user/mcp-zips/firefox-1221-linux.zip firefox \ --browser-download-url file:///home/user/mcp-zips/webkit-1761-linux.zip webkit这样mcp-install-all就是一条命令搞定全部。5. 方式三Docker 多阶段构建推荐指数 ★★★★☆CI/CD 自动化首选当你的测试脚本要跑在 Kubernetes 或 GitLab CI 上Docker 是唯一靠谱的选择。但直接FROM python:3.11 RUN pip install playwright playwright install会带来两个致命问题构建层臃肿浏览器二进制 300MB导致镜像体积爆炸构建失败率高CI Runner 网络策略严格playwright install经常超时。mcp-playwright 的 Docker 方案采用多阶段构建 二进制挂载把“安装”和“运行”彻底分离。5.1 构建阶段只下载不解压# 构建阶段纯净环境下载浏览器 zip FROM python:3.11-slim AS builder # 安装 curl 和 unzip用于下载和解压 RUN apt-get update apt-get install -y curl unzip rm -rf /var/lib/apt/lists/* # 下载 mcp-playwright Python 包和浏览器 zip WORKDIR /tmp RUN curl -O https://mcp-mirror.example.com/python/mcp-playwright-1.42.0-py3-none-any.whl \ curl -O https://mcp-mirror.example.com/browsers/chromium-1221103-linux.zip # 安装 Python 包不安装浏览器 RUN pip install --no-deps --no-cache-dir mcp-playwright-1.42.0-py3-none-any.whl5.2 运行阶段轻量基础镜像 挂载二进制# 运行阶段极简镜像只含必要依赖 FROM python:3.11-slim # 安装系统依赖Chromium 运行必需 RUN apt-get update apt-get install -y \ libnss3 \ libatk1.0-0 \ libatk-bridge2.0-0 \ libcups2 \ libdrm2 \ libxkbcommon0 \ libxcomposite1 \ libxdamage1 \ libxfixes3 \ libxrandr2 \ libgbm1 \ libasound2 \ rm -rf /var/lib/apt/lists/* # 复制 Python 包不含浏览器 COPY --frombuilder /usr/local/lib/python3.11/site-packages/ /usr/local/lib/python3.11/site-packages/ # 创建浏览器目录并挂载关键 ENV PLAYWRIGHT_BROWSERS_PATH/opt/mcp-browsers RUN mkdir -p $PLAYWRIGHT_BROWSERS_PATH # 将浏览器 zip 复制进来并解压在构建时完成非运行时 COPY --frombuilder /tmp/chromium-1221103-linux.zip /tmp/ RUN unzip /tmp/chromium-1221103-linux.zip -d $PLAYWRIGHT_BROWSERS_PATH \ rm /tmp/chromium-1221103-linux.zip # 验证安装 RUN python -c from playwright.sync_api import sync_playwright; print(OK)5.3 构建与推送命令# 构建自动触发多阶段 docker build -t myapp-e2e:latest . # 推送体积仅 ~420MB比传统方式小 60% docker push myapp-e2e:latest5.4 为什么这是 CI/CD 黄金方案构建确定性所有步骤在 Docker BuildKit 下执行网络、权限、环境完全隔离镜像可复现Dockerfile 锁定了 mcp-playwright 版本、浏览器 revision、系统依赖版本安全合规浏览器 zip 从内网镜像下载不触碰公网快速迭代修改 Python 代码只需重建运行阶段浏览器层复用缓存。注意事项GitLab CI 的docker:dind服务默认禁用unshare系统调用导致 Chromium 启动失败报Failed to move to new namespace。解决方案是在.gitlab-ci.yml中添加services: - docker:dind variables: DOCKER_DRIVER: overlay2 # 关键启用 user namespace DOCKER_OPTS: --userns-remapdefault6. 方式四国产化环境专项安装推荐指数 ★★★★★信创项目必选当客户明确要求“全栈国产化”你的安装方案必须回答三个问题CPU 架构支持吗操作系统适配吗供应链安全吗mcp-playwright 为此提供了完整的信创工具链。6.1 环境确认四步精准识别在龙芯/申威/飞腾机器上不要盲目下载先执行# Step 1: 确认 CPU 架构LoongArch64 / SW64 / aarch64 uname -m # Step 2: 确认操作系统发行版与版本 cat /etc/os-release | grep -E (NAME|VERSION_ID) # Step 3: 确认内核版本影响 sandbox 兼容性 uname -r # Step 4: 检查是否启用 SELinux/AppArmor影响 Chromium 启动 getenforce 2/dev/null || echo SELinux not enabled例如某银行信创云返回loongarch64 NAMEKylin Linux Advanced Server VERSION_IDV10 (Tercel) 5.10.0-106.102.100.100.ky10.aarch64 # 注意虽是 loongarch64但内核名仍标 aarch64这说明需选择kylinv10-tercel-loongarch64离线包而非kylinv10-tercel-aarch64。6.2 安装流程三件套缺一不可信创安装不是单个命令而是三个组件协同mcp-playwright-corePython 包含 LoongArch64 专用subprocess补丁mcp-chromium-loongarch64龙芯版 Chromium启用--no-sandbox且禁用seccompmcp-system-deps麒麟V10 专用依赖包含libglib2.0-02.68、libgtk-3-03.24。安装命令以麒麟V10龙芯为例# 1. 安装系统依赖rpm 包 sudo rpm -Uvh https://mcp-mirror.example.com/deps/kylinv10/mcp-system-deps-1.0-1.ky10.loongarch64.rpm # 2. 安装 Python 包wheel pip install https://mcp-mirror.example.com/python/mcp-playwright-core-1.42.0-py3-none-any.whl # 3. 安装浏览器二进制tar.gz解压到固定路径 sudo tar -xzf https://mcp-mirror.example.com/browsers/mcp-chromium-loongarch64-1221103.tar.gz -C /opt/mcp-browsers # 4. 配置环境变量 echo export PLAYWRIGHT_BROWSERS_PATH/opt/mcp-browsers ~/.bashrc source ~/.bashrc6.3 启动参数定制绕过国产内核限制龙芯/申威内核对 Chromium 的 sandbox 机制支持不完善必须显式禁用from playwright.sync_api import sync_playwright with sync_playwright() as p: # 关键添加 --no-sandbox 和 --disable-setuid-sandbox browser p.chromium.launch( headlessTrue, args[ --no-sandbox, --disable-setuid-sandbox, --disable-dev-shm-usage, # 避免 /dev/shm 空间不足 --disable-gpu, # 龙芯 GPU 驱动不兼容 ] ) page browser.new_page() page.goto(https://example.com) print(page.title()) browser.close()6.4 信创验收 checklist交付前必须通过以下测试测试项命令期望结果浏览器可执行/opt/mcp-browsers/chromium-1221103/chrome --version输出Chromium 122.0.6261.94无 sandbox 启动/opt/mcp-browsers/chromium-1221103/chrome --no-sandbox --headless --dump-dom https://example.com输出 HTML 源码Python 调用成功python -c from playwright.sync_api import sync_playwright; psync_playwright().start(); bp.chromium.launch(); print(OK); b.close(); p.stop()输出OK血泪教训某次在申威SW64服务器上chrome --version正常但 Python 调用时卡死。抓包发现是libdbus-1.so.3版本冲突系统自带 1.12Chromium 需 1.14。解决方案不是升级系统不允许而是用patchelf工具修改 Chromium 二进制的 RPATHpatchelf --set-rpath /usr/lib64:/opt/mcp-browsers/chromium-1221103/lib /opt/mcp-browsers/chromium-1221103/chrome这种底层修复只有 mcp-playwright 的离线包才允许你这么做——官方包是只读的。7. 方式五PyInstaller 打包集成推荐指数 ★★★★☆交付给客户单机版当你要把自动化脚本打包成app.exe或app交给客户且客户电脑可能没装 PythonPyInstaller 是唯一选择。但如前所述官方 Playwright 与 PyInstaller 天然不兼容。mcp-playwright 提供了--add-data自动注入方案。7.1 打包前准备提取浏览器二进制mcp-playwright 的离线包已解压浏览器所以你只需指定路径# 假设浏览器在 /opt/mcp-browsers/chromium-1221103/ # 提取所有必要文件chromium 目录下除 .zip 外的所有文件 ls -l /opt/mcp-browsers/chromium-1221103/ # 重点关注chrome, chrome_sandbox, LICENSE, resources/7.2 PyInstaller 命令三段式数据注入# 关键用 --add-data 把整个 chromium-1221103 目录注入到打包后目录 pyinstaller \ --onefile \ --add-data /opt/mcp-browsers/chromium-1221103:chromium-1221103 \ --add-binary /opt/mcp-browsers/chromium-1221103/chrome:. \ --add-binary /opt/mcp-browsers/chromium-1221103/chrome_sandbox:. \ main.py这里--add-data将目录映射为./chromium-1221103/--add-binary将关键二进制复制到根目录便于 Playwright 查找。7.3 Python 代码适配运行时定位浏览器打包后main.py必须能动态找到浏览器路径import os import sys from pathlib import Path def get_browser_path(): 获取打包后浏览器路径 if getattr(sys, frozen, False): # PyInstaller 打包后浏览器在 _MEIPASS/chromium-1221103/ base_path Path(sys._MEIPASS) else: # 开发时浏览器在 /opt/mcp-browsers/ base_path Path(/opt/mcp-browsers) # 尝试两种路径 for candidate in [ base_path / chromium-1221103, base_path / chromium-1221103 ]: if candidate.exists(): return str(candidate) raise RuntimeError(Chromium browser not found) # 在 launch 前设置环境变量 os.environ[PLAYWRIGHT_BROWSERS_PATH] get_browser_path() from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessTrue) # ... rest of code7.4 打包后验证三步确认法生成dist/main后执行# Step 1: 检查目录结构 ls -l dist/main/ # 应包含main, chromium-1221103/, chrome, chrome_sandbox # Step 2: 检查 chrome 是否可执行Linux/macOS chmod x dist/main/chrome dist/main/chrome --version # 应输出版本号 # Step 3: 运行打包程序 ./dist/main # 应正常打开网页并输出结果无 Executable doesnt exist 错误经验总结PyInstaller 打包最大的坑是--onefile模式下sys._MEIPASS是临时解压目录chrome_sandbox需要 setuid 权限但临时目录无法设权。解决方案是放弃--onefile改用--onedir并确保chrome_sandbox文件权限为4755chmod 4755 dist/main/chrome_sandbox这样客户双击main就能运行无需任何前置安装。8. 五种方式对比与选型决策树面对这么多方案如何选择我画了一张决策树覆盖 99% 的真实场景开始 │ ├─ 你的环境是否完全离线无任何外网、无代理、无内网镜像 │ ├─ 是 → 选【方式一离线全量安装包】唯一选择 │ └─ 否 → 进入下一步 │ ├─ 你的目标平台是信创环境龙芯/申威/飞腾 麒麟/统信 │ ├─ 是 → 选【方式四国产化环境专项安装】必须用专用包 │ └─ 否 → 进入下一步 │ ├─ 你的部署目标是 Docker/K8s/CI/CD │ ├─ 是 → 选【方式三Docker 多阶段构建】构建确定性最高 │ └─ 否 → 进入下一步 │ ├─ 你需要把脚本打包成单文件交付给客户 │ ├─ 是 → 选【方式五PyInstaller 打包集成】交付最简单 │ └─ 否 → 进入下一步 │ └─ 其他所有情况开发机、测试服务器、有内网镜像→ 选【方式二pip 本地浏览器缓存】最灵活再附一张参数对比表帮你量化选择维度方式一离线包方式二pip缓存方式三Docker方式四信创方式五PyInstaller**