装一个第三方库,进度条卡在下载那一步十几秒,然后蹦出一行红字。
pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timeout.
另一种长相是刷一大片警告,反复重试几次之后才失败:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(...getaddrinfo failed')': /simple/requests/
这两种都是网络层的事,跟要装的包本身没关系。pypi.org在国内访问不稳定,而pip默认的单次超时是15秒、重试5次,等它把重试全走完再报错,一分钟就过去了。
换源最直接。
临时换源:命令行加一个参数
pip install requests -i https://mirrors.cloud.tencent.com/pypi/simple/
不想每次都敲,就把它写进配置里,永久生效。
永久配置:pip config set
pip从10.0起自带config子命令,直接执行:
pip config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple/
执行完会打印一行Writing to ...,告诉你配置落在哪个文件。Windows上一般是C:\Users\用户名\AppData\Roaming\pip\pip.ini,Linux上是 ~/.config/pip/pip.conf,macOS上在 ~/Library/Application Support目录里。三个路径记不住也没关系,pip config list能反查当前生效的是哪一份。
嫌命令不好记,手写那个文件也一样。Windows下在资源管理器地址栏敲%APPDATA%进到Roaming目录,新建pip文件夹,在里面建pip.ini,内容写:
[global] index-url = https://mirrors.cloud.tencent.com/pypi/simple/ [install] trusted-host = mirrors.cloud.tencent.com
trusted-host这行对https源其实是多余的,留着也无害。早期pip(9.x那批)用http源时没有它会直接拒绝安装,报The repository located at xxx is not a trusted or secure host,那个年代过来的脚本里普遍带着这一行。
几个源地址,挑一个离得近的
https://mirrors.cloud.tencent.com/pypi/simple/ 腾讯云 https://repo.huaweicloud.com/repository/pypi/simple/ 华为云 https://mirrors.ustc.edu.cn/pypi/simple/ 中科大 https://pypi.tuna.tsinghua.edu.cn/simple/ 清华(实测偶发403) https://mirrors.aliyun.com/pypi/simple/ 阿里云(有IP黑名单)
实测下来,2026年在国内几台不同运营商的机器上,清华源返回过403,换UA也没用;阿里云更干脆,响应体里直接写denied by IP ACL = blacklist,出口IP被拉黑了。腾讯云那个一直正常,下载能跑到9.6MB/s上下,华为云和中科大作为备选也都通。源这东西没有永远可用的,装不上就换下一个,别跟它较劲。
requirements.txt里带源
项目要交给别人部署时,指望对方也配过全局源不现实。在requirements.txt第一行写:
--index-url https://mirrors.cloud.tencent.com/pypi/simple/ requests==2.32.3 flask==3.0.3
这样执行pip install -r requirements.txt不需要任何额外参数。这一行只对install场景生效,pip download之类的还得单独加 -i。
只放宽超时,不换源
源没问题、纯粹是网络抖动的场合,加大超时和重试次数就够:
pip install requests --timeout 60 --retries 10
默认那15秒对大wheel真不够,torch那种动辄800MB的包,慢一点的网络十几秒只下得了几百KB,还没到校验阶段就断了。
公司内网要走代理
pip install requests --proxy http://127.0.0.1:7890
也可以先set HTTPS_PROXY=http://127.0.0.1:7890再装,一次设置对当前命令行窗口都有效。之前碰到过一个环境,代理变量设了却依然失败,查了半天是no_proxy里把内网域名漏了,私有源的地址被一并转发出去了。
离线机器:先拉wheel再拷过去
生产环境不给外网的情况,在有网的机器上把包和依赖全下下来:
pip download requests -d D:\wheels -i https://mirrors.cloud.tencent.com/pypi/simple/
目标机器和当前机器不是同一个平台时,得显式指定平台和Python版本:
pip download pandas -d ./wheels --platform win_amd64 --python-version 3.12 --only-binary=:all:
拷到目标机器后离线安装:
pip install --no-index --find-links=./wheels pandas
--only-binary=:all: 这个参数要留神,包没有对应平台的wheel时会直接报错退出,不会退回去编译源码。碰到只有sdist的小众包,把参数去掉,在装了编译环境的机器上处理。
踩过的坑:pandas 2.2.x在Windows上有现成的win_amd64 wheel,但Python 3.13刚出那阵子(2024年10月)不少包还没跟上,用 --python-version 3.13去拉会空手而归。那会儿把版本降到3.12.6反而省事。
换个更快的工具:uv
2024年冒出来的uv,Rust写的,装包速度比pip快一个量级,命令基本兼容:
uv pip install requests --index-url https://mirrors.cloud.tencent.com/pypi/simple/
之前在一台CI机器上试过,同一份依赖清单,pip走完全程4分多钟,uv 40秒不到。它不读pip.conf,源要在命令行显式给,也不认trusted-host那套。
配了全局源之后装不了私有包
index-url一旦配成公网镜像,公司私有源会被盖掉。这种情况用extra-index-url追加,pip两个源都会去找:
[global] index-url = https://mirrors.cloud.tencent.com/pypi/simple/ extra-index-url = https://pypi.internal.example.com/simple/
extra-index-url有个隐患叫依赖混淆:私有源的包名如果和公网上某个包同名,pip会挑版本号高的那个装,不管它来自哪个源。真要隔离,私有源那台机器单独配一份pip.conf,别混着用。当初就是在这儿栽过一次,装出来的是公网上同名的空包,日志里看不出任何异常。
换源之后装的还是旧版本
大概率是缓存。缓存目录用pip cache dir查,清掉单个包用:
pip cache remove requests
装包失败先看报错里有没有connection、timeout、proxy这类字眼,有的话换源、放宽超时、走代理,三板斧基本能覆盖。报错带building wheel或者error: subprocess-exited-with-error的,那是编译环境和依赖缺失的问题,换源救不了。