离线安装Python包必须用pip download --recursive递归下载完整依赖树,并严格匹配--platform、--python-version等参数,否则内网安装会因依赖缺失或标签不匹配而失败;内网安装须成对使用--no-index与--find-links指向扁平目录。

离线安装 Python 包不是“把 .whl 文件扔进去就能装”,关键在于外网下载时是否拉全了整棵依赖树,且 wheel 标签(platform、python-version)是否跟内网环境严丝合缝。漏一层依赖、错一个标签,pip install 就会卡在 Could not find a version 或 is not a supported wheel on this platform。
pip download 必须加 --recursive 才算真正离线可用
只执行 pip download -d ./pkgs requests,只会下 requests 本体;安装时 pip 仍会联网找 urllib3、certifi、charset-normalizer——这在内网直接失败。
-
pip download --recursive -r requirements.txt -d ./offline_pkgs是唯一能递归解析setup.py或pyproject.toml并拉下全部子依赖的命令 - 不加
--recursive,哪怕requirements.txt里写了pandas==2.2.2,下载目录里也大概率没有numpy、pytz、python-dateutil - 如果项目用了
pip install -e .开发模式,pip download无法处理-e git+https://...这类 VCS 依赖,必须提前转成固定 commit 的.whl或删掉
外网打包机必须严格匹配内网环境的 platform 和 python-version
你在 CentOS 7 上用 Python 3.9 跑服务,外网打包机就得是同版本;否则下载的 wheel 名里带 cp312 或 macosx_10_9_x86_64,进内网后 pip 直接跳过,报错 is not a supported wheel。
- 显式指定平台:
--platform manylinux_2_17_x86_64(CentOS 7/8)、--platform win_amd64(Windows 64)、--platform manylinux_2_28_aarch64(ARM64 服务器) - 强制 Python 版本标签:
--python-version 39(对应 Python 3.9)、--python-version 311(对应 3.11) - 禁用源码包:
--only-binary=all,避免内网因缺gcc或MSVC编译失败 - 清空缓存干扰:
--no-cache-dir,防止 pip 拼凑出本地缓存里的不完整依赖
内网安装必须 --no-index 与 --find-links 成对出现
--no-index 只是关掉 PyPI,但没告诉 pip “去哪找包”;--find-links 才是真正指向离线包所在目录的指针。两者缺一不可。
- 命令格式固定为:
pip install --no-index --find-links=./offline_pkgs -r requirements.txt -
--find-links指向的目录必须是扁平结构——所有.whl和.tar.gz都在该目录下,不能有子文件夹;pip 不会递归扫描 - 确保当前用户对
./offline_pkgs有读权限;用sudo pip install容易因环境隔离导致 pip 找不到包 - 不需要加
--force-reinstall,pip 默认跳过已满足的包;如需降级,才额外加--force-reinstall
别用 pip install --download,它早在 pip 10 就被移除了
执行 pip install --download ./pkgs requests 会直接报错 unrecognized arguments: --download。这是最常被文档误导的操作,连试都不用试。
- 唯一合法起点是
pip download,不是pip install带任何 download 参数 - 网上很多教程写
pip install --download,要么是照抄旧资料,要么根本没在 pip ≥10 环境下验证过 - 如果你看到
pip install --find-links=... --no-index ...却没配--find-links指向的目录内容,那基本等于白忙活——包可能都下全了,但 pip 在内网压根看不见
最麻烦的不是命令记不全,而是依赖树太深时,pip download 显示“done”你以为齐了,结果内网一跑 pip install,某个包内部硬编码调用了另一个没被 setup.py 声明的模块,或者用了 pkg_resources.get_distribution() 动态加载——这种 case 得靠实际运行时暴露,没法靠下载阶段预判。


















