skills/skills.netease.im/python-ai-auto

python-ai-auto

SKILL.md

Python AI 环境一键部署工具

本 skill 提供跨平台 (macOS/Windows/Linux) 的 Python 虚拟环境创建、打包和部署自动化流程,附带爬虫测试脚本验证环境可用性。

快速开始

交互模板

用户提供以下信息时,直接生成并执行部署脚本:

  • Python 版本(如 3.8, 3.9, 3.10, 3.11, 3.12)
  • 需要的第三方包列表
  • 目标平台(macOS/Windows/Linux)
  • 部署方式(本地打包 or 远程部署)

请提供:

1. Python 版本:___
2. 需要安装的包(用逗号分隔):___
3. 目标平台:macOS / Windows / Linux
4. 部署方式:本地打包 / 远程部署

平台判断

在脚本开头自动检测当前操作系统:

import platform
import os

def get_platform():
    system = platform.system().lower()
    if system == "darwin":
        return "macos"
    elif system == "windows":
        return "windows"
    elif system == "linux":
        return "linux"
    return system

def get_script_extension():
    return ".bat" if get_platform() == "windows" else ".sh"

跨平台脚本

1. 一键创建环境 (create_env.py)

支持 macOS/Windows/Linux,自动检测平台并执行对应命令。

#!/usr/bin/env python3
"""跨平台 Python 虚拟环境创建脚本"""
import os
import sys
import platform
import subprocess
import shutil

def get_platform():
    system = platform.system().lower()
    return "macos" if system == "darwin" else system

def run_command(cmd, shell=True, check=True):
    """执行命令并返回结果"""
    print(f"执行: {cmd}")
    result = subprocess.run(cmd, shell=shell, capture_output=True, text=True)
    if check and result.returncode != 0:
        print(f"错误: {result.stderr}")
        sys.exit(1)
    return result

def main():
    env_name = sys.argv[1] if len(sys.argv) > 1 else "ai_env"
    python_version = sys.argv[2] if len(sys.argv) > 2 else "3.11"
    packages = sys.argv[3].split(",") if len(sys.argv) > 3 else []
    
    plat = get_platform()
    print(f"=== 创建虚拟环境: {env_name} (Python {python_version}, {plat}) ===")
    
    # 检测是否有 conda
    has_conda = shutil.which("conda") is not None
    
    if has_conda:
        # 使用 conda
        run_command(f"conda create -n {env_name} python={python_version} -y")
        # 激活环境并安装包
        if plat == "windows":
            run_command(f"conda activate {env_name} && pip install {' '.join(packages)}")
        else:
            run_command(f"source $(conda info --base)/etc/profile.d/conda.sh && conda activate {env_name} && pip install {' '.join(packages)}")
    else:
        # 使用 venv
        run_command(f"python{python_version} -m venv {env_name}")
        
        # 安装 pip 包
        if plat == "windows":
            run_command(f"{env_name}\\Scripts\\pip install {' '.join(packages)}")
        else:
            run_command(f"{env_name}/bin/pip install {' '.join(packages)}")
    
    print("=== 完成! ===")

if __name__ == "__main__":
    main()

2. 一键打包脚本 (pack_env.py)

跨平台打包脚本。

#!/usr/bin/env python3
"""跨平台虚拟环境打包脚本"""
import os
import sys
import platform
import subprocess
import shutil

def get_platform():
    system = platform.system().lower()
    return "macos" if system == "darwin" else system

def main():
    if len(sys.argv) < 2:
        print("用法: python pack_env.py <env_name>")
        sys.exit(1)
    
    env_name = sys.argv[1]
    plat = get_platform()
    
    print(f"=== 打包虚拟环境: {env_name} ({plat}) ===")
    
    # 检查是否有 conda
    if shutil.which("conda"):
        # 使用 conda pack
        subprocess.run(f"conda install conda-pack -y", shell=True)
        subprocess.run(f"conda pack -n {env_name} -o {env_name}.tar.gz", shell=True)
    else:
        # 使用 venvzip (推荐) 或手动打包
        print("使用 venvzip 打包...")
        if plat == "windows":
            subprocess.run(f"{env_name}\\Scripts\\pip install venv-pack", shell=True)
            subprocess.run(f"{env_name}\\Scripts\\venv-pack -o {env_name}.tar.gz", shell=True)
        else:
            subprocess.run(f"{env_name}/bin/pip install venv-pack", shell=True)
            subprocess.run(f"{env_name}/bin/venv-pack -o {env_name}.tar.gz", shell=True)
    
    print(f"=== 完成! 打包文件: {env_name}.tar.gz ===")

if __name__ == "__main__":
    main()

3. 一键部署脚本 (deploy_env.py)

跨平台部署脚本,支持本地和远程部署。

#!/usr/bin/env python3
"""跨平台虚拟环境部署脚本"""
import os
import sys
import platform
import subprocess
import shutil

def get_platform():
    system = platform.system().lower()
    return "macos" if system == "darwin" else system

def deploy_local(env_name, tar_file, target_path):
    """本地部署"""
    plat = get_platform()
    
    print(f"=== 本地部署到: {target_path} ===")
    
    os.makedirs(target_path, exist_ok=True)
    
    # 解压
    if plat == "windows":
        subprocess.run(f'tar -zxf "{tar_file}" -C "{target_path}"', shell=True)
    else:
        subprocess.run(f'tar -zxf "{tar_file}" -C "{target_path}"', shell=True)
    
    # 设置权限 (Linux/macOS)
    if plat != "windows":
        env_path = os.path.join(target_path, env_name)
        subprocess.run(f"chmod -R 755 {env_path}/bin", shell=True)
    
    print("=== 本地部署完成 ===")
    print(f"使用方式: {target_path}/{env_name}/bin/activate")

def deploy_remote(env_name, tar_file, host, target_path, user="root"):
    """远程部署 (Linux)"""
    print(f"=== 远程部署到: {user}@{host}:{target_path} ===")
    
    # 上传文件
    subprocess.run(f'scp "{tar_file}" {user}@{host}:/tmp/', shell=True)
    
    # 远程部署命令
    remote_cmds = f"""
        mkdir -p {target_path}
        sudo tar -zxf /tmp/{tar_file.split('/')[-1]} -C {target_path}
        sudo chmod -R 755 {target_path}/{env_name}/bin
        rm /tmp/{tar_file.split('/')[-1]}
    """
    
    subprocess.run(f'ssh {user}@{host} "{remote_cmds}"', shell=True)
    
    print("=== 远程部署完成 ===")
    print(f"使用方式: ssh {user}@{host} \"{target_path}/{env_name}/bin/activate\"")

def main():
    if len(sys.argv) < 3:
        print("用法:")
        print("  本地部署: python deploy_env.py <env_name> <tar_file> <target_path>")
        print("  远程部署: python deploy_env.py <env_name> <tar_file> <user>@<host> <target_path>")
        sys.exit(1)
    
    env_name = sys.argv[1]
    tar_file = sys.argv[2]
    target = sys.argv[3] if len(sys.argv) > 3 else "/opt/python_envs"
    
    if "@" in target:
        # 远程部署
        user, host = target.split("@")
        deploy_remote(env_name, tar_file, host, sys.argv[4] if len(sys.argv) > 4 else "/opt/python_envs", user)
    else:
        # 本地部署
        deploy_local(env_name, tar_file, target)

if __name__ == "__main__":
    main()

平台特定脚本

macOS/Linux - Bash 脚本

创建 scripts/create_env.sh

#!/bin/bash
# 跨平台创建脚本 (macOS/Linux)

ENV_NAME=${1:-ai_env}
PYTHON_VERSION=${2:-3.11}
PACKAGES=${3:-}

echo "=== 创建虚拟环境: $ENV_NAME (Python $PYTHON_VERSION) ==="

# 创建环境
if command -v conda &> /dev/null; then
    conda create -n "$ENV_NAME" python="$PYTHON_VERSION" -y
    source $(conda info --base)/etc/profile.d/conda.sh
    conda activate "$ENV_NAME"
    
    # 安装包
    if [ -n "$PACKAGES" ]; then
        pip install $PACKAGES
    fi
else
    python$PYTHON_VERSION -m venv "$ENV_NAME"
    source "$ENV_NAME/bin/activate"
    
    if [ -n "$PACKAGES" ]; then
        pip install $PACKAGES
    fi
fi

echo "=== 完成! ==="
echo "激活环境: source $ENV_NAME/bin/activate"

创建 scripts/deploy.sh

#!/bin/bash
# 跨平台部署脚本 (macOS/Linux)

ENV_NAME=${1}
TAR_FILE=${2}
TARGET_PATH=${3:-/opt/python_envs}

if [ -z "$ENV_NAME" ] || [ -z "$TAR_FILE" ]; then
    echo "用法: $0 <env_name> <tar_file> [target_path]"
    exit 1
fi

echo "=== 部署虚拟环境: $ENV_NAME ==="

mkdir -p "$TARGET_PATH"
tar -zxf "$TAR_FILE" -C "$TARGET_PATH"

# 设置权限
chmod -R 755 "$TARGET_PATH/$ENV_NAME/bin"

echo "=== 部署完成 ==="
echo "激活: source $TARGET_PATH/$ENV_NAME/bin/activate"

Windows - Batch 脚本

创建 scripts/create_env.bat

@echo off
REM 跨平台创建脚本 (Windows)

set ENV_NAME=%1
set PYTHON_VERSION=%2
set PACKAGES=%3

if "%ENV_NAME%"=="" set ENV_NAME=ai_env
if "%PYTHON_VERSION%"=="" set PYTHON_VERSION=3.11

echo === 创建虚拟环境: %ENV_NAME% (Python %PYTHON_VERSION%) ===

where conda >nul 2>nul
if %errorlevel%==0 (
    conda create -n %ENV_NAME% python=%PYTHON_VERSION% -y
    call conda activate %ENV_NAME%
    if not "%PACKAGES%"=="" pip install %PACKAGES%
) else (
    python -m venv %ENV_NAME%
    call %ENV_NAME%\Scripts\activate.bat
    if not "%PACKAGES%"=="" pip install %PACKAGES%
)

echo === 完成! ===
echo 激活环境: %ENV_NAME%\Scripts\activate.bat

创建 scripts/deploy.bat

@echo off
REM 跨平台部署脚本 (Windows)

set ENV_NAME=%1
set TAR_FILE=%2
set TARGET_PATH=%3

if "%ENV_NAME%"=="" goto :error
if "%TAR_FILE%"=="" goto :error
if "%TARGET_PATH%"=="" set TARGET_PATH=C:\PythonEnvs

echo === 部署虚拟环境: %ENV_NAME% ===

if not exist "%TARGET_PATH%" mkdir "%TARGET_PATH%"

tar -zxf "%TAR_FILE%" -C "%TARGET_PATH%"

echo === 部署完成 ===
echo 激活: %TARGET_PATH%\%ENV_NAME%\Scripts\activate.bat
goto :end

:error
echo 用法: deploy.bat ^<env_name^> ^<tar_file^> [target_path]

:end

爬虫测试脚本

创建 references/test_crawler.py

#!/usr/bin/env python3
"""爬虫测试脚本 - 验证 Python 环境爬虫功能是否正常"""
import sys
import subprocess

def test_imports():
    """测试所需库是否已安装"""
    print("\n=== 测试库导入 ===")
    
    required_libs = [
        ("requests", "HTTP 请求"),
        ("urllib", "URL 处理"),
        ("bs4", "BeautifulSoup"),
        ("lxml", "XML/HTML 解析"),
        ("selenium", "Selenium 自动化"),
        ("playwright", "Playwright"),
        ("httpx", "异步 HTTP"),
        ("aiohttp", "异步 HTTP 客户端"),
    ]
    
    results = []
    for lib, desc in required_libs:
        try:
            __import__(lib)
            print(f"✓ {lib} - {desc}")
            results.append(True)
        except ImportError:
            print(f"✗ {lib} - {desc} (未安装)")
            results.append(False)
    
    return any(results)

def test_basic_request():
    """测试基本 HTTP 请求"""
    print("\n=== 测试 HTTP 请求 ===")
    
    try:
        import requests
        response = requests.get("https://httpbin.org/get", timeout=10)
        print(f"✓ 状态码: {response.status_code}")
        
        if response.status_code == 200:
            print("✓ HTTP 请求功能正常")
            return True
    except Exception as e:
        print(f"✗ HTTP 请求失败: {e}")
    
    return False

def test_html_parsing():
    """测试 HTML 解析"""
    print("\n=== 测试 HTML 解析 ===")
    
    try:
        from bs4 import BeautifulSoup
        
        html = "<html><body><div class='test'>Hello</div></body></html>"
        soup = BeautifulSoup(html, "lxml")
        
        result = soup.find("div", class_="test").text
        if result == "Hello":
            print(f"✓ HTML 解析成功: {result}")
            return True
    except Exception as e:
        print(f"✗ HTML 解析失败: {e}")
    
    return False

def test_async_request():
    """测试异步 HTTP 请求"""
    print("\n=== 测试异步请求 ===")
    
    try:
        import asyncio
        import aiohttp
        
        async def test():
            async with aiohttp.ClientSession() as session:
                async with session.get("https://httpbin.org/get") as response:
                    return response.status == 200
        
        result = asyncio.run(test())
        if result:
            print("✓ 异步请求功能正常")
            return True
    except Exception as e:
        print(f"✗ 异步请求失败: {e}")
    
    return False

def test_proxy():
    """测试代理支持"""
    print("\n=== 测试代理支持 ===")
    
    try:
        import requests
        
        # 尝试不使用代理
        response = requests.get("https://httpbin.org/ip", timeout=10)
        print(f"✓ 直接请求成功: {response.json()}")
        
        # 测试代理环境变量
        proxies = {
            "http": os.environ.get("HTTP_PROXY"),
            "https": os.environ.get("HTTPS_PROXY"),
        }
        
        if proxies["http"] or proxies["https"]:
            print(f"✓ 代理已配置: http={proxies['http']}, https={proxies['https']}")
        else:
            print("○ 未配置代理(如需代理,请在环境中设置 HTTP_PROXY/HTTPS_PROXY)")
        
        return True
    except Exception as e:
        print(f"✗ 代理测试失败: {e}")
        return False

def test_headers():
    """测试自定义请求头"""
    print("\n=== 测试自定义请求头 ===")
    
    try:
        import requests
        
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
            "Accept": "text/html,application/xhtml+xml",
        }
        
        response = requests.get("https://httpbin.org/headers", headers=headers, timeout=10)
        
        if response.status_code == 200:
            print("✓ 自定义请求头功能正常")
            return True
    except Exception as e:
        print(f"✗ 自定义请求头失败: {e}")
    
    return False

def run_full_test():
    """运行完整测试"""
    import os
    
    print("=" * 50)
    print("Python 爬虫环境测试")
    print(f"Python 版本: {sys.version}")
    print(f"工作目录: {os.getcwd()}")
    print("=" * 50)
    
    tests = [
        ("库导入", test_imports),
        ("HTTP 请求", test_basic_request),
        ("HTML 解析", test_html_parsing),
        ("异步请求", test_async_request),
        ("代理支持", test_proxy),
        ("自定义请求头", test_headers),
    ]
    
    results = []
    for name, test_func in tests:
        try:
            result = test_func()
            results.append((name, result))
        except Exception as e:
            print(f"✗ {name} 测试异常: {e}")
            results.append((name, False))
    
    # 汇总
    print("\n" + "=" * 50)
    print("测试汇总")
    print("=" * 50)
    
    passed = sum(1 for _, r in results if r)
    total = len(results)
    
    for name, result in results:
        status = "✓ 通过" if result else "✗ 失败"
        print(f"{status}: {name}")
    
    print(f"\n总计: {passed}/{total} 通过")
    
    if passed == total:
        print("\n🎉 所有测试通过!爬虫环境配置正确。")
        return 0
    else:
        print(f"\n⚠️  {total - passed} 项测试失败,请安装缺失的库。")
        print("\n安装建议:")
        print("  pip install requests beautifulsoup4 lxml aiohttp")
        print("  pip install selenium playwright (可选)")
        return 1

if __name__ == "__main__":
    sys.exit(run_full_test())

常用配置

requirements.txt

创建 references/requirements.txt

# 基础爬虫
requests>=2.31.0
urllib3>=2.0.0
beautifulsoup4>=4.12.0
lxml>=4.9.0
html5lib>=1.1

# 异步爬虫
aiohttp>=3.8.0
asyncio>=3.4.3
httpx>=0.24.0

# 动态爬虫
selenium>=4.10.0
playwright>=1.37.0

# 数据处理
pandas>=2.0.0
numpy>=1.24.0

# 工具
pyyaml>=6.0
python-dotenv>=1.0.0
fake-useragent>=1.1.0

conda_requirements.txt

创建 references/conda_requirements.txt

# 优先使用 conda 安装的包
requests
urllib3
beautifulsoup4
lxml
pandas
numpy

常见问题

Q: Windows 下 conda 激活失败?

A: 使用 conda activate env_namecall env_name\Scripts\activate.bat

Q: 打包后环境太大?

A: 使用 conda clean -a 清理缓存,或在打包前删除 conda-meta

Q: 爬虫被拦截怎么办?

A:

  1. 使用代理池
  2. 添加随机 User-Agent
  3. 控制请求频率
  4. 使用 selenium/playwright 模拟真

Q: 跨平台打包要注意什么?

A: 尽量选择与目标服务器相同发行版和版本的操作系统进行打包,或使用纯 pip 环境


输出格式指南

根据用户需求,选择输出:

  1. 直接执行:提供可执行的脚本,用户可保存后直接运行
  2. 手动指引:提供分步骤的命令列表,供用户手动执行
  3. 组合方式:提供脚本 + 关键步骤说明

输出时优先使用代码块,便于用户复制使用。

Installs
1
First Seen
Apr 2, 2026