吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1225|回复: 28
上一主题 下一主题
收起左侧

[Python 原创] Python依赖库检测、安装第三方依赖库程序

  [复制链接]
跳转到指定楼层
楼主
popcfan 发表于 2026-1-4 10:56 回帖奖励

Python依赖库下载与离线安装程序使用说明

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. 运行方法

  1. 确保已安装Python 3.8或更高版本
  2. 下载程序文件dependency_manager.py
  3. 双击运行或在命令行中执行:
    python dependency_manager.py

5. 使用步骤

5.1 选择项目路径

  1. 在"项目路径"区域点击"浏览"按钮
  2. 选择要分析的Python项目目录
  3. 点击"分析依赖"按钮开始分析项目依赖

5.2 分析依赖

程序会自动分析项目依赖,优先读取项目中的requirements.txt文件,如果没有则通过分析Python文件的import语句来获取依赖。分析结果会显示在"依赖库列表"中,包括依赖名称、版本要求和安装状态。

5.3 镜像源设置

  1. 在"镜像源设置"区域,可以通过下拉菜单手动选择镜像源
  2. 点击"自动选择最快镜像"按钮,程序会自动测试所有镜像源的速度,并选择最快的镜像源
  3. 支持的镜像源包括:
    • 官方源
    • 阿里云
    • 腾讯云
    • 华为云
    • 清华大学
    • 北京大学
    • 豆瓣
    • 中科大

5.4 下载依赖

  1. 在"离线包存储路径"区域点击"浏览"按钮,选择离线包存储目录
  2. 在"依赖库列表"中选择要下载的依赖(可使用"全选"按钮选择所有依赖)
  3. 点击"下载选中依赖"或"下载全部依赖"按钮开始下载
  4. 下载完成后,离线包会保存在指定的目录中

5.5 安装依赖

5.5.1 在线安装
  1. 在"依赖库列表"中选择要安装的依赖
  2. 点击"安装选中依赖"按钮开始在线安装
  3. 程序会使用选定的镜像源下载并安装依赖
5.5.2 离线安装
  1. 点击"选择离线包目录安装"按钮
  2. 选择包含离线安装包的目录
  3. 程序会自动安装目录中的所有离线包,跳过已安装的包

6. 常见问题

6.1 分析依赖失败

  • 检查项目路径是否正确
  • 确保项目中包含Python文件或requirements.txt文件
  • 检查Python文件是否使用了正确的import语法

6.2 下载或安装失败

  • 检查网络连接是否正常
  • 尝试更换镜像源
  • 检查权限是否足够(特别是在安装到系统Python目录时)
  • 确保离线包目录中包含有效的安装包(.whl或.tar.gz文件)

6.3 镜像速度测试失败

  • 检查网络连接是否正常
  • 确保防火墙没有阻止程序访问网络
  • 尝试手动选择镜像源

7. 注意事项

  1. 本程序使用系统中的Python解释器执行pip命令,确保系统中已安装pip
  2. 离线安装时,建议使用与目标环境相同的Python版本下载离线包
  3. 程序会自动跳过已安装的依赖,无需担心重复安装
  4. 镜像速度测试结果可能会受到网络环境的影响,建议在网络稳定时进行测试
  5. 对于大型项目,依赖分析可能需要一些时间,请耐心等待
  6. 在Windows系统中,建议以管理员身份运行程序,以避免权限问题

8. 更新日志

  • 版本1.0
    • 初始版本,支持基本的依赖分析、下载和安装功能
  • 版本1.1
    • 添加了镜像源选择功能
    • 支持自动测试最快镜像
    • 优化了GUI界面
  • 版本1.2
    • 改进了依赖分析算法
    • 增强了错误处理
    • 提高了程序稳定性

9. 联系方式

如果您在使用过程中遇到问题或有改进建议,欢迎提出反馈。


提示:本程序仅用于辅助开发,建议在使用前备份重要数据。



关键代码:
[Python] 纯文本查看 复制代码
# -*- 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库,所以可能会有误报情况,介意的请直接用源码自行编译),源码在附件中。
https://pan.baidu.com/s/1uPIoa2cb8bkktDcZQu7Xyw?pwd=9cyh

py依赖库下载、离线安装程序.7z

38.56 KB, 下载次数: 122, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 6吾爱币 +12 热心值 +6 收起 理由
sorke + 1 + 1 热心回复!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
yjn866y + 1 + 1 谢谢@Thanks!
1588 + 1 + 1 谢谢@Thanks!
wa22 + 1 + 1 我很赞同!
lswdla + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
Kls673M 发表于 2026-1-4 15:29
https://www.52pojie.cn/thread-2051744-1-1.html

https://www.52pojie.cn/thread-2015323-1-1.html

一个可选多版本安装库,一个打包

大佬可以整合下吗
推荐
 楼主| popcfan 发表于 2026-1-4 15:44 |楼主
本帖最后由 popcfan 于 2026-1-4 15:57 编辑
Kls673M 发表于 2026-1-4 15:29
https://www.52pojie.cn/thread-2051744-1-1.html

https://www.52pojie.cn/thread-2015323-1-1.html

https://www.52pojie.cn/thread-2051744-1-1.html  这个贴子我看楼主在下面的回复里又更新了一次,那个应该可以满足需求
沙发
xjkonglong 发表于 2026-1-4 11:31
3#
hurric 发表于 2026-1-4 11:54
这个工具挺方便的 支持一下
4#
dork 发表于 2026-1-4 11:57
这个要是能和https://www.52pojie.cn/thread-2083616-1-1.html结合一下就更好了
5#
 楼主| popcfan 发表于 2026-1-4 12:00 |楼主
dork 发表于 2026-1-4 11:57
这个要是能和https://www.52pojie.cn/thread-2083616-1-1.html结合一下就更好了

那个贴子楼主没有放源码,不然的话是可以结合一下的
6#
flytim 发表于 2026-1-4 12:11
多谢了,学习一下
7#
haoiss 发表于 2026-1-4 12:12
感谢楼主分享,收藏备用
8#
gongfugao 发表于 2026-1-4 12:41
这个很好,很方便,谢谢楼主!
9#
极速星辰 发表于 2026-1-4 13:19
这个不错,感谢
10#
懒人的传说 发表于 2026-1-4 14:27
下载学习下,谢谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-1-7 23:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表