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 脚本
#!/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"
#!/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 脚本
@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
@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_name 或 call env_name\Scripts\activate.bat
Q: 打包后环境太大?
A: 使用 conda clean -a 清理缓存,或在打包前删除 conda-meta
Q: 爬虫被拦截怎么办?
A:
- 使用代理池
- 添加随机 User-Agent
- 控制请求频率
- 使用 selenium/playwright 模拟真
Q: 跨平台打包要注意什么?
A: 尽量选择与目标服务器相同发行版和版本的操作系统进行打包,或使用纯 pip 环境
输出格式指南
根据用户需求,选择输出:
- 直接执行:提供可执行的脚本,用户可保存后直接运行
- 手动指引:提供分步骤的命令列表,供用户手动执行
- 组合方式:提供脚本 + 关键步骤说明
输出时优先使用代码块,便于用户复制使用。