摘要
还在为Python项目依赖安装失败而头疼?网络不稳定、离线环境、镜像源太慢,统统有解了!本文介绍一款专为开发者打造的Python依赖管理神器,支持自动分析requirements.txt或import语句,一键下载离线安装包,并在无网络环境下快速部署。内置8大常用镜像源,智能测速选最快源,多线程下载安装,还带简洁GUI界面,操作零门槛。无论你是在本地开发、远程部署还是教学演示,它都能大幅提升效率。想知道如何离线批量安装依赖、避免重复安装、解决常见报错?这篇实用指南全讲清楚了。
— 文章内容摘要
1. 程序简介
本程序是一个用于Python项目依赖库管理的工具,主要功能包括自动分析项目依赖、下载离线安装包以及离线安装依赖库。它可以帮助开发者在没有网络或网络环境较差的情况下,快速安装项目所需的依赖库。
2. 功能特点
- 自动依赖分析:支持从项目的
requirements.txt文件或Python源代码的import语句自动分析依赖 - 镜像源管理:内置8个常用Python镜像源,支持手动选择或自动测试最快镜像
- 离线包下载:可以将依赖库下载为离线安装包,方便在无网络环境下使用
- 智能安装:自动检测已安装的依赖,跳过已安装的包,只安装缺失的依赖
- 多线程支持:使用多线程进行安装和下载,提高效率
- 友好的GUI界面:提供直观易用的图形用户界面,操作简单
3. 系统要求
- 操作系统:Windows 7及以上
- Python版本:3.8及以上
- 依赖:
- tkinter(Python标准库,用于GUI界面)
- urllib.request(Python标准库,用于镜像速度测试)
- subprocess(Python标准库,用于调用pip命令)
4. 运行方法
- 确保已安装Python 3.8或更高版本
- 下载程序文件
dependency_manager.py - 双击运行或在命令行中执行:
python dependency_manager.py
5. 使用步骤
5.1 选择项目路径
- 在”项目路径”区域点击”浏览”按钮
- 选择要分析的Python项目目录
- 点击”分析依赖”按钮开始分析项目依赖
5.2 分析依赖
程序会自动分析项目依赖,优先读取项目中的requirements.txt文件,如果没有则通过分析Python文件的import语句来获取依赖。分析结果会显示在”依赖库列表”中,包括依赖名称、版本要求和安装状态。
5.3 镜像源设置
- 在”镜像源设置”区域,可以通过下拉菜单手动选择镜像源
- 点击”自动选择最快镜像”按钮,程序会自动测试所有镜像源的速度,并选择最快的镜像源
- 支持的镜像源包括:
- 官方源
- 阿里云
- 腾讯云
- 华为云
- 清华大学
- 北京大学
- 豆瓣
- 中科大
5.4 下载依赖
- 在”离线包存储路径”区域点击”浏览”按钮,选择离线包存储目录
- 在”依赖库列表”中选择要下载的依赖(可使用”全选”按钮选择所有依赖)
- 点击”下载选中依赖”或”下载全部依赖”按钮开始下载
- 下载完成后,离线包会保存在指定的目录中
5.5 安装依赖
5.5.1 在线安装
- 在”依赖库列表”中选择要安装的依赖
- 点击”安装选中依赖”按钮开始在线安装
- 程序会使用选定的镜像源下载并安装依赖
5.5.2 离线安装
- 点击”选择离线包目录安装”按钮
- 选择包含离线安装包的目录
- 程序会自动安装目录中的所有离线包,跳过已安装的包
6. 常见问题
6.1 分析依赖失败
- 检查项目路径是否正确
- 确保项目中包含Python文件或requirements.txt文件
- 检查Python文件是否使用了正确的import语法
6.2 下载或安装失败
- 检查网络连接是否正常
- 尝试更换镜像源
- 检查权限是否足够(特别是在安装到系统Python目录时)
- 确保离线包目录中包含有效的安装包(.whl或.tar.gz文件)
6.3 镜像速度测试失败
- 检查网络连接是否正常
- 确保防火墙没有阻止程序访问网络
- 尝试手动选择镜像源
7. 注意事项
- 本程序使用系统中的Python解释器执行pip命令,确保系统中已安装pip
- 离线安装时,建议使用与目标环境相同的Python版本下载离线包
- 程序会自动跳过已安装的依赖,无需担心重复安装
- 镜像速度测试结果可能会受到网络环境的影响,建议在网络稳定时进行测试
- 对于大型项目,依赖分析可能需要一些时间,请耐心等待
- 在Windows系统中,建议以管理员身份运行程序,以避免权限问题
8. 更新日志
- 版本1.0:
- 初始版本,支持基本的依赖分析、下载和安装功能
- 版本1.1:
- 添加了镜像源选择功能
- 支持自动测试最快镜像
- 优化了GUI界面
- 版本1.2:
- 改进了依赖分析算法
- 增强了错误处理
- 提高了程序稳定性
# -*- coding: utf-8 -*-
"""
Python依赖库下载与离线安装程序 - 精简核心代码
只包含最关键的功能实现,去掉了完整的UI设计
"""
import subprocess
import sys
import os
import threading
import re
import time
import urllib.request
# -------------------
# 隐藏CMD窗口的关键代码
# -------------------
if sys.platform == 'win32':
STARTUPINFO = subprocess.STARTUPINFO()
STARTUPINFO.dwFlags |= subprocess.STARTF_USESHOWWINDOW
STARTUPINFO.wShowWindow = 0 # SW_HIDE
# -------------------
# 核心功能:获取正确的Python解释器路径
# -------------------
def get_python_exe():
"""获取正确的Python解释器路径,避免PyInstaller打包后调用自身"""
python_exe = sys.executable
# 检查是否为PyInstaller打包环境
if getattr(sys, 'frozen', False):
# 尝试从注册表获取Python安装路径
try:
import winreg
python_versions = ['3.8', '3.9', '3.10', '3.11', '3.12']
for version in python_versions:
try:
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, f"SOFTWARE\Python\PythonCore\{version}\InstallPath") as key:
python_path = winreg.QueryValueEx(key, "ExecutablePath")[0]
if os.path.exists(python_path):
return python_path
except Exception:
continue
except Exception:
pass
# 尝试使用环境变量
env_python = os.environ.get('PYTHONHOME')
if env_python and os.path.exists(os.path.join(env_python, 'python.exe')):
return os.path.join(env_python, 'python.exe')
# 回退到系统默认python
return 'python'
return python_exe
# -------------------
# 核心功能:依赖分析
# -------------------
def analyze_from_imports(project_path):
"""从Python文件的import语句分析依赖"""
imports = set()
# 获取Python标准库模块列表
def get_stdlib_modules():
# 简化版本,只包含常用标准库
return {
'abc', 'argparse', 'array', 'ast', 'asyncio', 'base64', 'bisect', 'builtins',
'collections', 'datetime', 'decimal', 'difflib', 'enum', 'functools', 'gc',
'glob', 'hashlib', 'heapq', 'http', 'importlib', 'inspect', 'io', 'itertools',
'json', 'logging', 'math', 'multiprocessing', 'os', 'pathlib', 're', 'shutil',
'socket', 'sqlite3', 'ssl', 'string', 'subprocess', 'sys', 'threading',
'time', 'tkinter', 'urllib', 'uuid', 'warnings', 'xml', 'zipfile'
}
stdlib_modules = get_stdlib_modules()
for root, dirs, files in os.walk(project_path):
# 跳过虚拟环境和版本控制目录
dirs[:] = [d for d in dirs if d not in ['venv', 'env', '.venv', '__pycache__', '.git', 'node_modules']]
for file in files:
if file.endswith('.py'):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
# 匹配import语句
import_matches = re.findall(r'^import\s+([a-zA-Z0-9_]+)', content, re.MULTILINE)
from_matches = re.findall(r'^from\s+([a-zA-Z0-9_]+)', content, re.MULTILINE)
imports.update(import_matches)
imports.update(from_matches)
except Exception:
continue
# 过滤标准库,映射模块名到包名
def module_to_package(module_name):
mapping = {
'cv2': 'opencv-python', 'PIL': 'Pillow', 'sklearn': 'scikit-learn',
'yaml': 'PyYAML', 'bs4': 'beautifulsoup4', 'dotenv': 'python-dotenv'
}
return mapping.get(module_name, module_name)
third_party = []
for imp in imports:
if imp.lower() not in [m.lower() for m in stdlib_modules]:
pkg_name = module_to_package(imp)
if pkg_name:
third_party.append((pkg_name, ""))
return list(set(third_party))
# -------------------
# 核心功能:镜像源管理与速度测试
# -------------------
class MirrorManager:
def __init__(self):
self.mirror_sources = {
"官方源": "https://pypi.org/simple",
"阿里云": "https://mirrors.aliyun.com/pypi/simple/",
"腾讯云": "https://mirrors.cloud.tencent.com/pypi/simple/",
"华为云": "https://mirrors.huaweicloud.com/repository/pypi/simple/",
"清华大学": "https://pypi.tuna.tsinghua.edu.cn/simple/",
"北京大学": "https://mirrors.pku.edu.cn/pypi/simple/",
"豆瓣": "https://pypi.doubanio.com/simple/",
"中科大": "https://pypi.mirrors.ustc.edu.cn/simple/"
}
self.selected_mirror = "官方源"
def test_mirror_speed(self, mirror_name, mirror_url):
"""测试单个镜像源的响应速度"""
try:
start_time = time.time()
# 测试URL,选择pip包的简单路径
test_url = f"{mirror_url.rstrip('/')}/pip/"
with urllib.request.urlopen(test_url, timeout=5) as response:
response.read(1024) # 只读取少量数据
end_time = time.time()
return mirror_name, end_time - start_time
except Exception:
return mirror_name, float('inf')
def select_fastest_mirror(self):
"""测试所有镜像源并选择最快的"""
results = []
for mirror_name, mirror_url in self.mirror_sources.items():
name, speed = self.test_mirror_speed(mirror_name, mirror_url)
if speed != float('inf'):
results.append((name, speed))
if results:
results.sort(key=lambda x: x[1])
fastest_mirror = results[0][0]
self.selected_mirror = fastest_mirror
return fastest_mirror, results[0][1]
return None, None
# -------------------
# 核心功能:依赖下载与安装
# -------------------
def download_packages(packages, download_path, mirror_manager):
"""下载包"""
os.makedirs(download_path, exist_ok=True)
python_exe = get_python_exe()
for name, version in packages:
pkg_spec = f"{name}{version}" if version else name
print(f"正在下载: {pkg_spec}")
try:
cmd = [
python_exe, "-m", "pip", "download",
pkg_spec,
"-d", download_path,
"--no-cache-dir"
]
# 添加镜像源参数
mirror_url = mirror_manager.mirror_sources[mirror_manager.selected_mirror]
cmd.extend(["--index-url", mirror_url])
result = subprocess.run(
cmd, capture_output=True, text=True, encoding='utf-8',
startupinfo=STARTUPINFO
)
if result.returncode == 0:
print(f"✓ {pkg_spec} 下载成功")
else:
print(f"✗ {pkg_spec} 下载失败: {result.stderr}")
except Exception as e:
print(f"✗ {pkg_spec} 下载出错: {e}")
def install_online_packages(packages, mirror_manager):
"""在线安装包"""
python_exe = get_python_exe()
# 获取已安装包列表
def get_installed_packages():
try:
result = subprocess.run(
[python_exe, "-m", "pip", "list", "--format=freeze"],
capture_output=True, text=True, encoding='utf-8',
startupinfo=STARTUPINFO
)
installed = {}
for line in result.stdout.strip().split('\n'):
if '==' in line:
name, version = line.split('==')
installed[name.lower()] = version
return installed
except Exception:
return {}
installed = get_installed_packages()
for name, version in packages:
pkg_spec = f"{name}{version}" if version else name
# 检查是否已安装
if name.lower() in installed:
installed_version = installed[name.lower()]
if version and version.startswith('=='):
required_version = version[2:]
if installed_version == required_version:
print(f"⊘ {name}=={installed_version} 已安装相同版本,跳过")
continue
elif not version:
print(f"⊘ {name} 已安装({installed_version}),跳过")
continue
print(f"正在安装: {pkg_spec}")
try:
cmd = [python_exe, "-m", "pip", "install", pkg_spec]
# 添加镜像源参数
mirror_url = mirror_manager.mirror_sources[mirror_manager.selected_mirror]
cmd.extend(["--index-url", mirror_url])
result = subprocess.run(
cmd, capture_output=True, text=True, encoding='utf-8',
startupinfo=STARTUPINFO
)
if result.returncode == 0:
print(f"✓ {pkg_spec} 安装成功")
else:
print(f"✗ {pkg_spec} 安装失败: {result.stderr}")
except Exception as e:
print(f"✗ {pkg_spec} 安装出错: {e}")
# -------------------
# 使用示例
# -------------------
if __name__ == "__main__":
# 1. 分析项目依赖
project_path = "./"
dependencies = analyze_from_imports(project_path)
print(f"分析到的依赖: {dependencies}")
# 2. 选择最快镜像源
mirror_manager = MirrorManager()
fastest_mirror, speed = mirror_manager.select_fastest_mirror()
if fastest_mirror:
print(f"最快的镜像源是: {fastest_mirror} (响应时间: {speed:.3f}秒)")
# 3. 下载依赖
# download_path = "./offline_packages"
# download_packages(dependencies, download_path, mirror_manager)
# 4. 安装依赖
# install_online_packages(dependencies, mirror_manager)程序截图:

打包好的可执行文件(因涉及OS库,所以可能会有误报情况,介意的请直接用源码自行编译),源码在附件中。
蓝奏云网盘

评论(11)