From dacf9ee3cf05c4ec9e10d007a87129869a6bace0 Mon Sep 17 00:00:00 2001 From: zhinianboke <115088296+zhinianboke@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:10:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 + utils/item_search.py | 75 +++++++++++++++++++++++++++++----- utils/order_detail_fetcher.py | 76 ++++++++++++++++++++++++++++++----- 3 files changed, 134 insertions(+), 19 deletions(-) diff --git a/Dockerfile b/Dockerfile index ba65030..69e2faa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,8 @@ WORKDIR /app ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 ENV TZ=Asia/Shanghai +ENV DOCKER_ENV=true +ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright # 安装系统依赖(包括Playwright浏览器依赖) RUN apt-get update && \ diff --git a/utils/item_search.py b/utils/item_search.py index 05a6cb9..bdacd70 100644 --- a/utils/item_search.py +++ b/utils/item_search.py @@ -7,10 +7,30 @@ import asyncio import json import time +import sys +import os from datetime import datetime from typing import Dict, List, Any, Optional 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: from playwright.async_api import async_playwright PLAYWRIGHT_AVAILABLE = True @@ -45,17 +65,54 @@ class XianyuSearcher: if not self.browser: playwright = await async_playwright().start() 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( headless=True, # 无头模式 - args=[ - '--no-sandbox', - '--disable-setuid-sandbox', - '--disable-dev-shm-usage', - '--disable-accelerated-2d-canvas', - '--no-first-run', - '--no-zygote', - '--disable-gpu' - ] + args=browser_args ) 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" diff --git a/utils/order_detail_fetcher.py b/utils/order_detail_fetcher.py index 6541f81..52311fa 100644 --- a/utils/order_detail_fetcher.py +++ b/utils/order_detail_fetcher.py @@ -5,10 +5,30 @@ import asyncio import time +import sys +import os from typing import Optional, Dict, Any from playwright.async_api import async_playwright, Browser, BrowserContext, Page 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: """闲鱼订单详情获取器""" @@ -43,18 +63,54 @@ class OrderDetailFetcher: try: 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( headless=headless, - args=[ - '--no-sandbox', - '--disable-setuid-sandbox', - '--disable-dev-shm-usage', - '--disable-accelerated-2d-canvas', - '--no-first-run', - '--no-zygote', - '--disable-gpu' - ] + args=browser_args ) # 创建浏览器上下文