mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-08-10 00:07:36 +08:00
Compare commits
4 Commits
f9a3881b74
...
b73d52ef50
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b73d52ef50 | ||
![]() |
d1812a859c | ||
![]() |
6a44815af7 | ||
![]() |
dacf9ee3cf |
@ -14,6 +14,8 @@ WORKDIR /app
|
|||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
ENV PYTHONDONTWRITEBYTECODE=1
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
|
ENV DOCKER_ENV=true
|
||||||
|
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
|
||||||
|
|
||||||
# 安装系统依赖(包括Playwright浏览器依赖)
|
# 安装系统依赖(包括Playwright浏览器依赖)
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# ================================
|
|
||||||
# 闲鱼自动回复系统 - Docker重新构建脚本
|
|
||||||
# ================================
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🐳 闲鱼自动回复系统 - Docker重新构建"
|
|
||||||
echo "=================================="
|
|
||||||
|
|
||||||
# 检查Docker是否运行
|
|
||||||
if ! docker info > /dev/null 2>&1; then
|
|
||||||
echo "❌ Docker未运行,请先启动Docker"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "📋 步骤1: 停止并删除现有容器"
|
|
||||||
echo "--------------------------------"
|
|
||||||
|
|
||||||
# 停止现有容器
|
|
||||||
if docker ps -q --filter "name=xianyu-auto-reply" | grep -q .; then
|
|
||||||
echo "🛑 停止现有容器..."
|
|
||||||
docker stop xianyu-auto-reply
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 删除现有容器
|
|
||||||
if docker ps -aq --filter "name=xianyu-auto-reply" | grep -q .; then
|
|
||||||
echo "🗑️ 删除现有容器..."
|
|
||||||
docker rm xianyu-auto-reply
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "📋 步骤2: 删除现有镜像"
|
|
||||||
echo "--------------------------------"
|
|
||||||
|
|
||||||
# 删除现有镜像
|
|
||||||
if docker images -q xianyu-auto-reply | grep -q .; then
|
|
||||||
echo "🗑️ 删除现有镜像..."
|
|
||||||
docker rmi xianyu-auto-reply
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "📋 步骤3: 重新构建镜像"
|
|
||||||
echo "--------------------------------"
|
|
||||||
|
|
||||||
echo "🔨 开始构建新镜像..."
|
|
||||||
docker build -t xianyu-auto-reply .
|
|
||||||
|
|
||||||
echo "📋 步骤4: 启动新容器"
|
|
||||||
echo "--------------------------------"
|
|
||||||
|
|
||||||
echo "🚀 启动新容器..."
|
|
||||||
docker run -d \
|
|
||||||
--name xianyu-auto-reply \
|
|
||||||
--restart unless-stopped \
|
|
||||||
-p 8080:8080 \
|
|
||||||
-v "$(pwd)/data:/app/data" \
|
|
||||||
-v "$(pwd)/logs:/app/logs" \
|
|
||||||
-v "$(pwd)/backups:/app/backups" \
|
|
||||||
-e DOCKER_ENV=true \
|
|
||||||
xianyu-auto-reply
|
|
||||||
|
|
||||||
echo "📋 步骤5: 检查容器状态"
|
|
||||||
echo "--------------------------------"
|
|
||||||
|
|
||||||
# 等待容器启动
|
|
||||||
echo "⏳ 等待容器启动..."
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# 检查容器状态
|
|
||||||
if docker ps --filter "name=xianyu-auto-reply" --filter "status=running" | grep -q xianyu-auto-reply; then
|
|
||||||
echo "✅ 容器启动成功"
|
|
||||||
|
|
||||||
echo "📋 容器信息:"
|
|
||||||
docker ps --filter "name=xianyu-auto-reply" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
|
||||||
|
|
||||||
echo "📋 最近日志:"
|
|
||||||
docker logs --tail 20 xianyu-auto-reply
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🎉 Docker重新构建完成!"
|
|
||||||
echo "=================================="
|
|
||||||
echo "📱 Web界面: http://localhost:8080"
|
|
||||||
echo "📊 健康检查: http://localhost:8080/health"
|
|
||||||
echo "📋 查看日志: docker logs -f xianyu-auto-reply"
|
|
||||||
echo "🛑 停止容器: docker stop xianyu-auto-reply"
|
|
||||||
echo "🗑️ 删除容器: docker rm xianyu-auto-reply"
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "❌ 容器启动失败"
|
|
||||||
echo "📋 错误日志:"
|
|
||||||
docker logs xianyu-auto-reply
|
|
||||||
exit 1
|
|
||||||
fi
|
|
Binary file not shown.
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 143 KiB |
Binary file not shown.
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 164 KiB |
@ -7,10 +7,30 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Dict, List, Any, Optional
|
from typing import Dict, List, Any, Optional
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
# 修复Docker环境中的asyncio事件循环策略问题
|
||||||
|
if sys.platform.startswith('linux') or os.getenv('DOCKER_ENV'):
|
||||||
|
try:
|
||||||
|
# 在Linux/Docker环境中设置事件循环策略
|
||||||
|
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"设置事件循环策略失败: {e}")
|
||||||
|
|
||||||
|
# 确保在Docker环境中使用正确的事件循环
|
||||||
|
if os.getenv('DOCKER_ENV'):
|
||||||
|
try:
|
||||||
|
# 强制使用SelectorEventLoop(在Docker中更稳定)
|
||||||
|
if hasattr(asyncio, 'SelectorEventLoop'):
|
||||||
|
loop = asyncio.SelectorEventLoop()
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"设置SelectorEventLoop失败: {e}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from playwright.async_api import async_playwright
|
from playwright.async_api import async_playwright
|
||||||
PLAYWRIGHT_AVAILABLE = True
|
PLAYWRIGHT_AVAILABLE = True
|
||||||
@ -45,17 +65,54 @@ class XianyuSearcher:
|
|||||||
if not self.browser:
|
if not self.browser:
|
||||||
playwright = await async_playwright().start()
|
playwright = await async_playwright().start()
|
||||||
logger.info("正在启动浏览器...")
|
logger.info("正在启动浏览器...")
|
||||||
|
# Docker环境优化的浏览器启动参数
|
||||||
|
browser_args = [
|
||||||
|
'--no-sandbox',
|
||||||
|
'--disable-setuid-sandbox',
|
||||||
|
'--disable-dev-shm-usage',
|
||||||
|
'--disable-accelerated-2d-canvas',
|
||||||
|
'--no-first-run',
|
||||||
|
'--no-zygote',
|
||||||
|
'--disable-gpu',
|
||||||
|
'--disable-background-timer-throttling',
|
||||||
|
'--disable-backgrounding-occluded-windows',
|
||||||
|
'--disable-renderer-backgrounding',
|
||||||
|
'--disable-features=TranslateUI',
|
||||||
|
'--disable-ipc-flooding-protection',
|
||||||
|
'--disable-extensions',
|
||||||
|
'--disable-default-apps',
|
||||||
|
'--disable-sync',
|
||||||
|
'--disable-translate',
|
||||||
|
'--hide-scrollbars',
|
||||||
|
'--mute-audio',
|
||||||
|
'--no-default-browser-check',
|
||||||
|
'--no-pings',
|
||||||
|
'--single-process' # 在Docker中使用单进程模式
|
||||||
|
]
|
||||||
|
|
||||||
|
# 在Docker环境中添加额外参数
|
||||||
|
if os.getenv('DOCKER_ENV'):
|
||||||
|
browser_args.extend([
|
||||||
|
'--disable-background-networking',
|
||||||
|
'--disable-background-timer-throttling',
|
||||||
|
'--disable-client-side-phishing-detection',
|
||||||
|
'--disable-default-apps',
|
||||||
|
'--disable-hang-monitor',
|
||||||
|
'--disable-popup-blocking',
|
||||||
|
'--disable-prompt-on-repost',
|
||||||
|
'--disable-sync',
|
||||||
|
'--disable-web-resources',
|
||||||
|
'--metrics-recording-only',
|
||||||
|
'--no-first-run',
|
||||||
|
'--safebrowsing-disable-auto-update',
|
||||||
|
'--enable-automation',
|
||||||
|
'--password-store=basic',
|
||||||
|
'--use-mock-keychain'
|
||||||
|
])
|
||||||
|
|
||||||
self.browser = await playwright.chromium.launch(
|
self.browser = await playwright.chromium.launch(
|
||||||
headless=True, # 无头模式
|
headless=True, # 无头模式
|
||||||
args=[
|
args=browser_args
|
||||||
'--no-sandbox',
|
|
||||||
'--disable-setuid-sandbox',
|
|
||||||
'--disable-dev-shm-usage',
|
|
||||||
'--disable-accelerated-2d-canvas',
|
|
||||||
'--no-first-run',
|
|
||||||
'--no-zygote',
|
|
||||||
'--disable-gpu'
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
self.context = await self.browser.new_context(
|
self.context = await self.browser.new_context(
|
||||||
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||||
|
@ -5,10 +5,30 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
from typing import Optional, Dict, Any
|
from typing import Optional, Dict, Any
|
||||||
from playwright.async_api import async_playwright, Browser, BrowserContext, Page
|
from playwright.async_api import async_playwright, Browser, BrowserContext, Page
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
# 修复Docker环境中的asyncio事件循环策略问题
|
||||||
|
if sys.platform.startswith('linux') or os.getenv('DOCKER_ENV'):
|
||||||
|
try:
|
||||||
|
# 在Linux/Docker环境中设置事件循环策略
|
||||||
|
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"设置事件循环策略失败: {e}")
|
||||||
|
|
||||||
|
# 确保在Docker环境中使用正确的事件循环
|
||||||
|
if os.getenv('DOCKER_ENV'):
|
||||||
|
try:
|
||||||
|
# 强制使用SelectorEventLoop(在Docker中更稳定)
|
||||||
|
if hasattr(asyncio, 'SelectorEventLoop'):
|
||||||
|
loop = asyncio.SelectorEventLoop()
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"设置SelectorEventLoop失败: {e}")
|
||||||
|
|
||||||
|
|
||||||
class OrderDetailFetcher:
|
class OrderDetailFetcher:
|
||||||
"""闲鱼订单详情获取器"""
|
"""闲鱼订单详情获取器"""
|
||||||
@ -43,18 +63,54 @@ class OrderDetailFetcher:
|
|||||||
try:
|
try:
|
||||||
playwright = await async_playwright().start()
|
playwright = await async_playwright().start()
|
||||||
|
|
||||||
# 启动浏览器
|
# 启动浏览器(Docker环境优化)
|
||||||
|
browser_args = [
|
||||||
|
'--no-sandbox',
|
||||||
|
'--disable-setuid-sandbox',
|
||||||
|
'--disable-dev-shm-usage',
|
||||||
|
'--disable-accelerated-2d-canvas',
|
||||||
|
'--no-first-run',
|
||||||
|
'--no-zygote',
|
||||||
|
'--disable-gpu',
|
||||||
|
'--disable-background-timer-throttling',
|
||||||
|
'--disable-backgrounding-occluded-windows',
|
||||||
|
'--disable-renderer-backgrounding',
|
||||||
|
'--disable-features=TranslateUI',
|
||||||
|
'--disable-ipc-flooding-protection',
|
||||||
|
'--disable-extensions',
|
||||||
|
'--disable-default-apps',
|
||||||
|
'--disable-sync',
|
||||||
|
'--disable-translate',
|
||||||
|
'--hide-scrollbars',
|
||||||
|
'--mute-audio',
|
||||||
|
'--no-default-browser-check',
|
||||||
|
'--no-pings',
|
||||||
|
'--single-process' # 在Docker中使用单进程模式
|
||||||
|
]
|
||||||
|
|
||||||
|
# 在Docker环境中添加额外参数
|
||||||
|
if os.getenv('DOCKER_ENV'):
|
||||||
|
browser_args.extend([
|
||||||
|
'--disable-background-networking',
|
||||||
|
'--disable-background-timer-throttling',
|
||||||
|
'--disable-client-side-phishing-detection',
|
||||||
|
'--disable-default-apps',
|
||||||
|
'--disable-hang-monitor',
|
||||||
|
'--disable-popup-blocking',
|
||||||
|
'--disable-prompt-on-repost',
|
||||||
|
'--disable-sync',
|
||||||
|
'--disable-web-resources',
|
||||||
|
'--metrics-recording-only',
|
||||||
|
'--no-first-run',
|
||||||
|
'--safebrowsing-disable-auto-update',
|
||||||
|
'--enable-automation',
|
||||||
|
'--password-store=basic',
|
||||||
|
'--use-mock-keychain'
|
||||||
|
])
|
||||||
|
|
||||||
self.browser = await playwright.chromium.launch(
|
self.browser = await playwright.chromium.launch(
|
||||||
headless=headless,
|
headless=headless,
|
||||||
args=[
|
args=browser_args
|
||||||
'--no-sandbox',
|
|
||||||
'--disable-setuid-sandbox',
|
|
||||||
'--disable-dev-shm-usage',
|
|
||||||
'--disable-accelerated-2d-canvas',
|
|
||||||
'--no-first-run',
|
|
||||||
'--no-zygote',
|
|
||||||
'--disable-gpu'
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建浏览器上下文
|
# 创建浏览器上下文
|
||||||
|
Loading…
x
Reference in New Issue
Block a user