33
This commit is contained in:
@@ -6,6 +6,7 @@ import time
|
||||
import random
|
||||
import subprocess
|
||||
import os
|
||||
import platform
|
||||
from contextlib import contextmanager
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
|
||||
@@ -156,22 +157,27 @@ def log_url_change(page, old_url: str, action: str = None):
|
||||
|
||||
|
||||
def cleanup_chrome_processes():
|
||||
"""清理残留的 Chrome 进程 (Windows)"""
|
||||
"""清理残留的 Chrome 进程 (跨平台支持)"""
|
||||
try:
|
||||
# 查找并终止残留的 chrome 进程 (仅限无头或调试模式的)
|
||||
result = subprocess.run(
|
||||
['tasklist', '/FI', 'IMAGENAME eq chrome.exe', '/FO', 'CSV'],
|
||||
capture_output=True, text=True, timeout=5
|
||||
)
|
||||
|
||||
if 'chrome.exe' in result.stdout:
|
||||
# 只清理可能是自动化残留的进程,不影响用户正常使用的浏览器
|
||||
# 通过检查命令行参数来判断
|
||||
if platform.system() == "Windows":
|
||||
# Windows: 使用 tasklist 和 taskkill
|
||||
result = subprocess.run(
|
||||
['tasklist', '/FI', 'IMAGENAME eq chrome.exe', '/FO', 'CSV'],
|
||||
capture_output=True, text=True, timeout=5
|
||||
)
|
||||
|
||||
if 'chrome.exe' in result.stdout:
|
||||
subprocess.run(
|
||||
['taskkill', '/F', '/IM', 'chromedriver.exe'],
|
||||
capture_output=True, timeout=5
|
||||
)
|
||||
log.step("已清理 chromedriver 残留进程")
|
||||
else:
|
||||
# Linux/Mac: 使用 pkill
|
||||
subprocess.run(
|
||||
['taskkill', '/F', '/IM', 'chromedriver.exe'],
|
||||
['pkill', '-f', 'chromedriver'],
|
||||
capture_output=True, timeout=5
|
||||
)
|
||||
log.step("已清理 chromedriver 残留进程")
|
||||
except Exception:
|
||||
pass # 静默处理,不影响主流程
|
||||
|
||||
@@ -186,9 +192,10 @@ def init_browser(max_retries: int = BROWSER_MAX_RETRIES) -> ChromiumPage:
|
||||
ChromiumPage: 浏览器实例
|
||||
"""
|
||||
log.info("初始化浏览器...", icon="browser")
|
||||
|
||||
|
||||
last_error = None
|
||||
|
||||
is_linux = platform.system() == "Linux"
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
# 首次尝试或重试前清理残留进程
|
||||
@@ -196,7 +203,7 @@ def init_browser(max_retries: int = BROWSER_MAX_RETRIES) -> ChromiumPage:
|
||||
log.warning(f"浏览器启动重试 ({attempt + 1}/{max_retries})...")
|
||||
cleanup_chrome_processes()
|
||||
time.sleep(BROWSER_RETRY_DELAY)
|
||||
|
||||
|
||||
co = ChromiumOptions()
|
||||
co.set_argument('--no-first-run')
|
||||
co.set_argument('--disable-infobars')
|
||||
@@ -204,8 +211,31 @@ def init_browser(max_retries: int = BROWSER_MAX_RETRIES) -> ChromiumPage:
|
||||
co.set_argument('--disable-gpu') # 减少资源占用
|
||||
co.set_argument('--disable-dev-shm-usage') # 避免共享内存问题
|
||||
co.set_argument('--no-sandbox') # 服务器环境需要
|
||||
co.auto_port() # 自动分配端口,确保每次都是新实例
|
||||
|
||||
|
||||
# Linux 服务器特殊配置
|
||||
if is_linux:
|
||||
co.set_argument('--disable-software-rasterizer')
|
||||
co.set_argument('--disable-extensions')
|
||||
co.set_argument('--disable-setuid-sandbox')
|
||||
co.set_argument('--single-process') # 某些 Linux 环境需要
|
||||
co.set_argument('--remote-debugging-port=0') # 让系统自动分配端口
|
||||
|
||||
# 尝试查找 Chrome/Chromium 路径
|
||||
chrome_paths = [
|
||||
'/usr/bin/google-chrome',
|
||||
'/usr/bin/google-chrome-stable',
|
||||
'/usr/bin/chromium-browser',
|
||||
'/usr/bin/chromium',
|
||||
'/snap/bin/chromium',
|
||||
]
|
||||
for chrome_path in chrome_paths:
|
||||
if os.path.exists(chrome_path):
|
||||
co.set_browser_path(chrome_path)
|
||||
log.step(f"使用浏览器: {chrome_path}")
|
||||
break
|
||||
else:
|
||||
co.auto_port() # Windows 使用自动分配端口
|
||||
|
||||
# 无头模式 (服务器运行)
|
||||
if BROWSER_HEADLESS:
|
||||
co.set_argument('--headless=new')
|
||||
@@ -213,10 +243,10 @@ def init_browser(max_retries: int = BROWSER_MAX_RETRIES) -> ChromiumPage:
|
||||
log.step("启动 Chrome (无头模式)...")
|
||||
else:
|
||||
log.step("启动 Chrome (无痕模式)...")
|
||||
|
||||
|
||||
# 设置超时
|
||||
co.set_timeouts(base=PAGE_LOAD_TIMEOUT, page_load=PAGE_LOAD_TIMEOUT * 2)
|
||||
|
||||
|
||||
page = ChromiumPage(co)
|
||||
log.success("浏览器启动成功")
|
||||
return page
|
||||
@@ -224,10 +254,10 @@ def init_browser(max_retries: int = BROWSER_MAX_RETRIES) -> ChromiumPage:
|
||||
except Exception as e:
|
||||
last_error = e
|
||||
log.warning(f"浏览器启动失败 (尝试 {attempt + 1}/{max_retries}): {e}")
|
||||
|
||||
|
||||
# 清理可能的残留
|
||||
cleanup_chrome_processes()
|
||||
|
||||
|
||||
# 所有重试都失败
|
||||
log.error(f"浏览器启动失败,已重试 {max_retries} 次: {last_error}")
|
||||
raise last_error
|
||||
|
||||
Reference in New Issue
Block a user