diff --git a/Dockerfile b/Dockerfile index 35ced0b..d402246 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 ENV TZ=Asia/Shanghai -# 安装系统依赖 +# 安装系统依赖(包括Playwright浏览器依赖) RUN apt-get update && \ apt-get install -y --no-install-recommends \ nodejs \ @@ -25,6 +25,51 @@ RUN apt-get update && \ libpng-dev \ libfreetype6-dev \ fonts-dejavu-core \ + # Playwright浏览器依赖 + libnss3 \ + libnspr4 \ + libatk-bridge2.0-0 \ + libdrm2 \ + libxkbcommon0 \ + libxcomposite1 \ + libxdamage1 \ + libxrandr2 \ + libgbm1 \ + libxss1 \ + libasound2 \ + libatspi2.0-0 \ + libgtk-3-0 \ + libgdk-pixbuf2.0-0 \ + libxcursor1 \ + libxi6 \ + libxrender1 \ + libxext6 \ + libx11-6 \ + libxft2 \ + libxinerama1 \ + libxrandr2 \ + libxss1 \ + libxtst6 \ + ca-certificates \ + fonts-liberation \ + libappindicator3-1 \ + libasound2 \ + libatk-bridge2.0-0 \ + libdrm2 \ + libgtk-3-0 \ + libnspr4 \ + libnss3 \ + libx11-xcb1 \ + libxcomposite1 \ + libxcursor1 \ + libxdamage1 \ + libxfixes3 \ + libxi6 \ + libxrandr2 \ + libxrender1 \ + libxss1 \ + libxtst6 \ + xdg-utils \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -39,6 +84,10 @@ RUN pip install --no-cache-dir --upgrade pip && \ # 复制项目文件 COPY . . +# 安装Playwright浏览器(必须在复制项目文件之后) +RUN playwright install chromium && \ + playwright install-deps chromium + # 创建必要的目录并设置权限 RUN mkdir -p /app/logs /app/data /app/backups && \ chmod 777 /app/logs /app/data /app/backups diff --git a/README.md b/README.md index 3aa7824..26821c6 100644 --- a/README.md +++ b/README.md @@ -332,7 +332,26 @@ curl http://localhost:8080/health ## 📞 技术支持 ### 🔧 故障排除 -如遇问题,请: + +#### 常见问题解决 + +**1. 商品搜索功能报错(Playwright浏览器问题)** +```bash +# 错误信息:Executable doesn't exist at /root/.cache/ms-playwright/chromium... + +# 解决方案:重新构建镜像(推荐) +docker-compose down +docker-compose build --no-cache +docker-compose up -d + +# 或者手动修复(临时方案) +docker exec -it xianyu-auto-reply bash +playwright install chromium +exit +docker restart xianyu-auto-reply +``` + +**2. 其他问题排查** 1. 查看日志:`docker-compose logs -f` 2. 检查状态:`./docker-deploy.sh status` 3. 健康检查:`curl http://localhost:8080/health` diff --git a/docker-deploy.sh b/docker-deploy.sh index c79458a..b9a7fa3 100644 --- a/docker-deploy.sh +++ b/docker-deploy.sh @@ -88,14 +88,14 @@ start_services() { else print_info "启动基础服务..." fi - + docker-compose $profile up -d print_success "服务启动完成" - + # 等待服务就绪 print_info "等待服务就绪..." sleep 10 - + # 检查服务状态 if docker-compose ps | grep -q "Up"; then print_success "服务运行正常" @@ -328,6 +328,9 @@ main() { "cleanup") cleanup ;; + "fix-playwright") + fix_playwright + ;; "help"|"--help"|"-h") show_help ;; diff --git a/static/item_search.html b/static/item_search.html index cff7c1f..fd235bc 100644 --- a/static/item_search.html +++ b/static/item_search.html @@ -84,7 +84,7 @@ 商品搜索
diff --git a/utils/item_search.py b/utils/item_search.py index 6b1ceca..05a6cb9 100644 --- a/utils/item_search.py +++ b/utils/item_search.py @@ -188,12 +188,20 @@ class XianyuSearcher: await self.close_browser() except Exception as e: - logger.error(f"Playwright 搜索失败: {str(e)}") + error_msg = str(e) + logger.error(f"Playwright 搜索失败: {error_msg}") + + # 检查是否是浏览器安装问题 + if "Executable doesn't exist" in error_msg or "playwright install" in error_msg: + error_msg = "浏览器未安装。请在Docker容器中运行: playwright install chromium" + elif "BrowserType.launch" in error_msg: + error_msg = "浏览器启动失败。请确保Docker容器有足够的权限和资源" + # 如果 Playwright 失败,返回错误信息 return { 'items': [], 'total': 0, - 'error': f'搜索失败: {str(e)}' + 'error': f'搜索失败: {error_msg}' } async def _get_fallback_data(self, keyword: str, page: int, page_size: int) -> Dict[str, Any]: @@ -599,12 +607,20 @@ class XianyuSearcher: await self.close_browser() except Exception as e: - logger.error(f"Playwright 多页搜索失败: {str(e)}") + error_msg = str(e) + logger.error(f"Playwright 多页搜索失败: {error_msg}") + + # 检查是否是浏览器安装问题 + if "Executable doesn't exist" in error_msg or "playwright install" in error_msg: + error_msg = "浏览器未安装。请在Docker容器中运行: playwright install chromium" + elif "BrowserType.launch" in error_msg: + error_msg = "浏览器启动失败。请确保Docker容器有足够的权限和资源" + # 如果 Playwright 失败,返回错误信息 return { 'items': [], 'total': 0, - 'error': f'多页搜索失败: {str(e)}' + 'error': f'多页搜索失败: {error_msg}' } async def _get_multiple_fallback_data(self, keyword: str, total_pages: int) -> Dict[str, Any]: