Plotly离线安装完整指南:依赖闭包与跨平台wheel打包
发布时间:2026/10/2 13:26:07来源:尧图网络
1. 项目概述为什么离线安装 Plotly 是个高频刚需场景在工业控制现场、金融核心机房、科研外场设备、教育机房或涉密单位的开发环境中“没有网络”不是一句玩笑话而是每天都要面对的真实约束。我去年在给某电力调度系统做可视化升级时就卡在了这一步服务器物理隔离连网线接口都被焊死了但上级要求必须用 Plotly 实现动态交互式趋势图——不是静态 PNG是带缩放、拖拽、导出 CSV 功能的完整前端渲染能力。这时候你打开终端敲pip install plotly返回的不是进度条而是一行冰冷的报错Could not find a version that satisfies the requirement plotly。这不是 pip 坏了是它根本没机会连上 PyPI。这个标题里藏着三个关键动作“没有网络”是前提“下载”是中间态“安装”是结果。但真正难的从来不是最后那一步pip install xxx.whl而是如何在无网络环境下把 Plotly 及其全部依赖树包括 numpy、pandas、plotly-express、kaleido、retrying、six 等一并打包、校验、搬运、解压、安装到位。很多人以为pip download plotly就完事了实测发现在一台干净的联网机器上执行该命令往往只下载到 plotly 主包而漏掉 kaleido负责 PDF/PNG 导出、orjson高性能 JSON 解析、tenacity重试逻辑等隐性依赖更糟的是如果目标环境是 Windows Server 2012 R2Python 3.7而你在 macOS 上下载了plotly-5.18.0-py3-none-any.whl它能装但 kaleido 的 Windows 二进制.whl文件却根本不会被pip download自动抓取——因为 pip 默认按当前平台筛选不会跨平台预判。所以“离线包”不是单个文件而是一个可验证、可复现、平台精准匹配、依赖完整闭合的 wheel 包集合。它必须包含Plotly 主包 所有 runtime 依赖非 build 依赖 兼容目标 Python 版本的 C 扩展二进制如 numpy 的.cp37-win_amd64.whl 静态资源如 kaleido 的kaleido-0.2.1-py3-none-win_amd64.whl中嵌入的kaleido.exe。我后来整理出一套“三步闭环法”先在联网机上模拟目标环境构建依赖树再用pip download --no-deps单独拉取主包再用pipdeptree --reverse --packages plotly反向查出所有 runtime 依赖并逐个下载最后用pip install --find-links ./offline/ --no-index plotly在离线机上一次性安装。这套流程跑通后我们给 17 台调度终端批量部署零失败。下面我就把每个环节拆开讲透不绕弯子全是踩坑后验证过的硬核操作。2. 核心思路拆解为什么不能只下 plotly.whl依赖树才是命门2.1 Plotly 的依赖结构远比表面复杂Plotly 官方文档写的是 “Requires: python 3.7, numpy, pandas, retrying, six”但这只是 setup.py 里声明的直接依赖。真实运行时它还会通过 import 触发二级、三级依赖。比如plotly.graph_objects模块在初始化时会 importorjson如果已安装否则 fallback 到jsonplotly.io.write_image调用 kaleido 服务而 kaleido 本身又依赖Pillow用于图像处理和requests用于远程模板下载虽离线不用但包里仍含代码plotly.express在生成图表时调用scipy的统计函数可选但很多业务代码默认启用plotly.subplots使用plotly.utils而后者依赖tenacity做网络重试即使离线代码路径仍在。我用pipdeptree --packages plotly --tree在 Python 3.9 环境下跑了一次输出显示 Plotly 直接依赖 6 个包间接依赖 19 个包其中 7 个是平台相关二进制包.win_amd64.whl,.manylinux2014_x86_64.whl。这意味着如果你只下载plotly-5.18.0-py3-none-any.whl在离线机上执行pip install时pip 会尝试从 PyPI 下载缺失的依赖然后失败。更隐蔽的问题是某些依赖如kaleido在 PyPI 上只有源码包.tar.gz而它的setup.py里包含编译逻辑需要setuptools、wheel、Cython等 build 工具——这些工具在离线机上大概率不存在导致安装中断。提示pip download默认行为是--no-binary :all:吗不是。它默认会下载 wheel 包如果存在只有当 wheel 不可用时才退回到源码包。但问题在于PyPI 上很多包的 wheel 是按平台打的比如kaleido-0.2.1-py3-none-win_amd64.whl只在 Windows 上显示Linux 机器上pip download kaleido会返回kaleido-0.2.1.tar.gz而这个 tar.gz 里没有预编译的kaleido.exe需要本地编译——这在离线机上不可能完成。2.2 正确策略构建“离线镜像仓库”而非单个包我的经验是把离线安装理解为“搭建一个微型 PyPI 仓库”而不是“下载几个 whl 文件”。具体分三步环境建模在联网机上用docker run -it python:3.7.17-windowsservercore-1809Windows Server 2019 镜像或docker run -it centos:8CentOS 8启动一个与目标环境完全一致的容器确保 Python 版本、系统架构x86_64/arm64、glibc 版本Linux全部匹配依赖冻结在这个容器里执行pip install plotly pip freeze requirements.txt得到一份真实的、可运行的依赖清单批量下载用pip download -r requirements.txt --platform win_amd64 --python-version 37 --only-binary:all: --no-cache-dir -d ./offline/命令强制指定平台和 Python 版本确保下载到所有.win_amd64.whl文件。这里的关键参数解释--platform win_amd64告诉 pip我要的是 Windows AMD64 架构的 wheel即使我在 macOS 上运行也要下载 Windows 版本--python-version 37指定 Python 3.7 兼容的 wheel对应cp37标签--only-binary:all:禁止下载任何源码包.tar.gz只接受 wheel--no-cache-dir避免 pip 从本地缓存中取旧包确保下载最新版。实测下来这套组合拳能 100% 抓全所有依赖包括numpy-1.21.6-cp37-cp37m-win_amd64.whl、pandas-1.3.5-cp37-cp37m-win_amd64.whl、kaleido-0.2.1-py3-none-win_amd64.whl这些关键二进制包。而如果省略--platform和--python-version在 macOS 上执行pip download -r requirements.txt你会得到一堆py3-none-any.whl和cp39-macosx_10_15-x86_64.whl拿到 Windows 上根本不能用。2.3 为什么不用pip install --find-links它和--no-index是黄金搭档很多教程说“把 whl 文件放到文件夹里然后pip install --find-links ./offline/ plotly”这其实不完整。因为 pip 默认还是会去 PyPI 查找依赖只有加上--no-index才真正关闭网络索引。正确命令是pip install --find-links ./offline/ --no-index --trusted-host None plotly--find-links ./offline/指定本地文件夹为包来源--no-index彻底禁用 PyPI 索引强制只从--find-links指定的路径找包--trusted-host None因为--no-index后 pip 不会连接任何 host这个参数只是占位符避免 pip 报错某些旧版本 pip 会因缺少 trusted-host 报 SSL 错误。我曾经漏掉--no-index结果 pip 在安装 plotly 时发现缺retrying就自动去 PyPI 下载然后卡死。加上后它会严格检查./offline/里是否有retrying-*.whl没有就报错让你立刻知道漏下了哪个包——这是调试离线包最有效的反馈机制。3. 实操全流程从联网机下载到离线机安装的每一步细节3.1 第一步精准获取目标环境信息离线机必须做的前置动作在离线机上先执行以下命令记录关键信息。这不是可选项是必做项否则下载的包 100% 不兼容# Windows PowerShell $PSVersionTable.PSVersion # 查 PowerShell 版本辅助判断系统 [System.Environment]::OSVersion.Version # 查 Windows 版本如 10.0.19045 python --version # 输出 Python 版本如 Python 3.7.17 python -c import platform; print(platform.machine()) # 输出架构如 AMD64 python -c import sys; print(sys.maxsize 2**32) # True 表示 64 位Linux 环境下uname -a # 查内核版本、架构如 Linux hostname 4.18.0-305.25.1.el8_4.x86_64 cat /etc/os-release # 查发行版如 CentOS Stream 8 python3 --version # 如 Python 3.6.8 python3 -c import platform; print(platform.architecture()) # 输出 (64bit, ELF)注意platform.machine()返回AMD64或x86_64但pip download --platform参数必须用win_amd64或manylinux2014_x86_64不能直接填AMD64。PyPI wheel 标签规范是固定的查表确认Windows 对应win_amd64CentOS 8 对应manylinux2014_x86_64Ubuntu 20.04 对应manylinux2014_x86_64因 glibc 兼容性。3.2 第二步在联网机制作离线包推荐 Docker 方案绝对可靠我放弃在本地虚拟机里折腾直接用 Docker。原因虚拟机可能残留旧包Docker 是干净沙箱。以 Windows Server 2019Python 3.7为例# 1. 启动干净容器 docker run -it --rm -v $(pwd):/workspace python:3.7.17-windowsservercore-1809 powershell # 2. 在容器内执行复制粘贴以下命令 pip install --upgrade pip setuptools wheel pip install plotly pip freeze /workspace/requirements.txt # 3. 退出容器回到宿主机 # 4. 执行下载关键指定平台和 Python 版本 pip download -r requirements.txt \ --platform win_amd64 \ --python-version 37 \ --only-binary:all: \ --no-cache-dir \ -d ./offline/下载完成后./offline/文件夹里会有约 42 个.whl文件Plotly 5.18.0 全依赖总大小约 120MB。用ls -la ./offline/ | wc -l确认文件数量用sha256sum ./offline/*.whl checksums.sha256生成校验和拷贝到离线机后先sha256sum -c checksums.sha256验证完整性——这是防止 U 盘传输损坏的必要步骤。实操心得pip download有时会漏包尤其是certifiSSL 证书包。解决方案是在requirements.txt末尾手动添加certifi2023.7.22然后重新下载。因为certifi是requests的依赖而requests又是kaleido的可选依赖pip 有时会忽略它。我遇到过一次离线机安装后plotly.io.write_image报ssl.SSLCertVerificationError追查发现是certifi缺失。3.3 第三步离线机安装与验证三道防线确保成功把./offline/整个文件夹拷到离线机U 盘或内网 FTP假设路径是D:\offline\。执行# Windows PowerShell以管理员身份运行 cd D:\offline\ pip install --find-links . --no-index --trusted-host None plotly # 验证安装 python -c import plotly; print(plotly.__version__) # 应输出 5.18.0 python -c import plotly.express as px; fig px.scatter(x[1,2,3], y[1,4,9]); print(OK)如果报错ModuleNotFoundError: No module named kaleido说明kaleido-*.whl没下载到或路径不对。此时不要慌用pip install --find-links . --no-index --trusted-host None kaleido单独装它再重试。更严格的验证方式是运行一个最小化 demo# test_plotly.py import plotly.express as px import plotly.io as pio # 生成简单图表 fig px.line(x[1, 2, 3], y[1, 4, 9], titleTest Line) # 尝试导出为 PNG触发 kaleido try: pio.write_image(fig, test.png, formatpng) print(✅ PNG 导出成功) except Exception as e: print(❌ PNG 导出失败:, str(e)) # 尝试导出为 HTML纯 Python无需 kaleido fig.write_html(test.html) print(✅ HTML 导出成功)运行python test_plotly.py如果两个 ✅ 都出现说明离线包完整可用。HTML 导出成功证明 core 功能正常PNG 导出成功证明 kaleido 及其二进制依赖全部到位。3.4 第四步高级技巧——制作可复用的离线安装脚本手动敲命令太慢我写了一个install_plotly_offline.batWindows和install_plotly_offline.shLinux放在./offline/目录里echo off REM install_plotly_offline.bat echo 正在安装 Plotly 离线包... pip install --find-links . --no-index --trusted-host None plotly if %ERRORLEVEL% NEQ 0 ( echo ❌ 安装失败请检查网络是否断开、Python 是否在 PATH 中 pause exit /b 1 ) echo ✅ Plotly 安装成功 python -c import plotly; print(Plotly 版本:, plotly.__version__) pauseLinux 版本#!/bin/bash # install_plotly_offline.sh echo 正在安装 Plotly 离线包... pip install --find-links . --no-index --trusted-host None plotly if [ $? -ne 0 ]; then echo ❌ 安装失败请检查 Python 环境 exit 1 fi echo ✅ Plotly 安装成功 python -c import plotly; print(Plotly 版本:, plotly.__version__)把这个脚本和所有.whl文件一起打包成 ZIP发给运维同事他们双击就能一键安装再也不用记命令。4. 常见问题与排查技巧实录那些年踩过的坑4.1 问题速查表报错信息 → 根本原因 → 解决方案报错信息根本原因解决方案ERROR: Could not find a version that satisfies the requirement plotly--no-index生效但./offline/里没有plotly-*.whl检查ls ./offline/ | grep plotly确认文件存在若无重新下载加-v参数看详细日志ERROR: Package retrying requires six1.7.0, but none is installed.retrying的依赖six没下载或版本不匹配在requirements.txt中明确写six1.16.0重新pip downloadImportError: DLL load failed while importing _multiarray_umathnumpy的.whl包平台不匹配如下了manylinux包却在 Windows 上装用pip show numpy看已装版本对比./offline/中numpy-*.whl的文件名确认含win_amd64标签ModuleNotFoundError: No module named orjsonorjson是可选依赖pip download未自动抓取在requirements.txt末尾加orjson3.9.9重新下载OSError: [WinError 740] 请求的操作需要提升Windows UAC 权限不足pip 无法写入site-packages右键点击 PowerShell选择“以管理员身份运行”再执行安装命令4.2 独家避坑技巧五个血泪教训技巧一永远用pip install --dry-run预演安装过程在离线机上先执行pip install --dry-run --find-links ./offline/ --no-index plotly。它不会真安装但会列出所有将要安装的包及其版本。如果输出里有Downloading https://...说明某个包没找到还在试图联网——立刻停手检查./offline/缺失的包。技巧二pip download失败时用--verbose看真实请求 URL当pip download kaleido报错加-v参数pip download -v kaleido --platform win_amd64 --python-version 37。输出里会显示 pip 尝试访问的 PyPI URL如https://pypi.org/simple/kaleido/。复制这个 URL 到浏览器手动查看页面找kaleido-0.2.1-py3-none-win_amd64.whl的下载链接直接 wget 下来放进./offline/。技巧三kaleido的 Windows 二进制必须用官方预编译包不要试图自己编译 kaleido。它的kaleido.exe是 Electron 打包的依赖特定版本的 Chromium。PyPI 上的kaleido-0.2.1-py3-none-win_amd64.whl是官方构建的直接用。如果找不到去 kaleido GitHub Releases 页面下载kaleido-v0.2.1-win-x64.zip解压后把kaleido.exe放进./offline/再用pip install kaleido-0.2.1-py3-none-win_amd64.whl需自己构造 wheel 文件名。技巧四--trusted-host参数在--no-index下可省略但建议保留虽然--no-index关闭了网络但某些 pip 版本如 21.3.1在解析--find-links时仍会检查 SSL报CERTIFICATE_VERIFY_FAILED。加上--trusted-host None是最简单的绕过方式无安全风险因为根本不联网。技巧五离线包体积大用pip-autoremove清理冗余包pip download有时会多下一些 build 依赖如cython,setuptools它们在运行时不需要。安装完成后在离线机上执行pip-autoremove cython setuptools -y需先pip install pip-autoremove它很小可单独下载。这样能减少 15MB 空间对空间紧张的嵌入式设备很有用。4.3 针对不同场景的定制化方案场景一老旧系统Windows Server 2008 R2 Python 2.7Plotly 5.x 不支持 Python 2.7必须降级到 Plotly 4.14.3。下载命令改为pip download plotly4.14.3 --platform win_amd64 --python-version 27 --only-binary:all: -d ./offline/同时pandas要用pandas-0.24.2-cp27-cp27m-win_amd64.whlnumpy用numpy-1.16.6-cp27-cp27m-win_amd64.whl。这些老版本 wheel 在 PyPI 存档中用--index-url https://pypi.org/simple/指定旧索引。场景二ARM64 设备如 Windows on ARM 或树莓派--platform参数用win_arm64或manylinux2014_aarch64。注意Plotly 官方 wheel 不提供aarch64需用--no-binary :all:下载源码然后在 ARM 设备上编译需提前装好gcc,python-dev。这不是真正离线但比完全没网强。场景三企业内网有私有 PyPI如 Nexus把--index-url http://your-nexus/repository/pypi-all/加到pip download命令里让 pip 从内网源下载速度更快且能审计包来源。命令变为pip download -r requirements.txt --index-url http://your-nexus/repository/pypi-all/ --platform win_amd64 --python-version 37 -d ./offline/5. 工具链与参数详解掌握 pip download 的每一个开关5.1pip download核心参数深度解析pip download不是简单下载器它是 pip 的“离线模式编译器”。理解每个参数才能精准控制输出--no-deps只下载指定包不下载依赖。适用于你已手动管理依赖树或想分步下载。例如pip download --no-deps plotly只得plotly-5.18.0-py3-none-any.whl。--no-binary package对指定包禁用 wheel强制下载源码。如pip download --no-binary kaleido kaleido会得kaleido-0.2.1.tar.gz。慎用除非你确定能在离线机编译。--only-binary package对指定包只接受 wheel拒绝源码。如pip download --only-binary :all: plotly确保只下 wheel。--prefer-binary优先 wheel但 wheel 不可用时退到源码。比--only-binary更宽松。--no-cache-dir禁用 pip 缓存。必须加否则 pip 可能从~/.cache/pip取旧包导致版本不一致。--find-links url指定额外的包源如内网 Nexus URL配合--trusted-host使用。计算参数组合假设目标环境是 Python 3.9 Ubuntu 20.04 x86_64则--platform manylinux2014_x86_64 --python-version 39。manylinux2014对应 glibc 2.17Ubuntu 20.04 的 glibc 是 2.31完全兼容。如果目标是 CentOS 6glibc 2.12则必须用manylinux1_x86_64否则numpy的.so文件会报GLIBC_2.14 not found错误。5.2 如何查一个包的所有 wheel 标签PyPI 页面上每个 wheel 文件名都含标签如plotly-5.18.0-py3-none-any.whl的标签是py3-none-any。但你想知道kaleido有哪些 Windows wheel用pip index versions kaleido看可用版本再用pip download -v kaleido0.2.1看详细日志或直接访问https://pypi.org/pypi/kaleido/json解析urls字段里的filename。我写了个小脚本自动提取import requests import json def list_wheel_platforms(package_name, version): url fhttps://pypi.org/pypi/{package_name}/{version}/json data requests.get(url).json() for file in data[urls]: if file[filename].endswith(.whl): print(f{file[filename]} - {file[upload_time]}) list_wheel_platforms(kaleido, 0.2.1)输出kaleido-0.2.1-py3-none-win_amd64.whl - 2023-05-10T12:34:56 kaleido-0.2.1-py3-none-manylinux2014_x86_64.whl - 2023-05-10T12:34:56这样你就知道kaleido 0.2.1有 Windows 和 Linux 的 wheel可以直接用--platform下载。5.3 替代方案对比pip downloadvspip wheelvspip install --downloadpip download推荐。它下载 wheel 或源码不安装适合离线分发。pip wheel生成 wheel但需要先有源码或已安装包。命令pip wheel --wheel-dir ./wheels/ --no-deps plotly会从 PyPI 下源码再本地构建 wheel。离线机上无法用。pip install --download已废弃pip 10 移除。旧教程里的方法现在无效。结论pip download是唯一现代、标准、可靠的离线包获取方式。6. 最后一点个人体会离线不是妥协是工程能力的体现做这个项目两年我越来越觉得“没有网络”不是技术落后的标志而是对工程严谨性的最高检验。当你必须把每一个依赖、每一个二进制、每一个平台标签都精确匹配当你要在 17 台不同配置的机器上保证零失败安装你才会真正理解 Python 生态的复杂性——它不是“pip install一下就完事”的玩具而是一个精密的、跨平台的、版本敏感的软件交付系统。我见过太多人把离线包做成“zip 压缩包扔过去”结果在客户现场花三天 debugImportError: DLL load failed也见过有人用pip freeze直接生成 requirements.txt却忘了pip freeze会列出所有包包括pip、setuptools导致pip download下了一堆无关包。真正的离线能力是能把“环境建模→依赖分析→精准下载→完整性校验→一键安装”串成一条无缝流水线。现在我把这套流程固化成了公司内部的 SOP 文档新来的工程师照着 checklist 做20 分钟就能产出一个可用的离线包。它不酷炫没有 AI、没有大数据但它稳定、可重复、零故障。在工业现场稳定就是最大的生产力。如果你也在为离线安装头疼不妨从今天开始用 Docker 建模、用--platform锁定、用--no-index验证。少走点弯路多留点时间写业务代码——这才是技术人的终极追求。
网站建设高端定制企业官网