94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
|
|
# coding: utf-8
|
||
|
|
"""
|
||
|
|
Selenium 驱动工厂
|
||
|
|
提供统一的浏览器驱动创建接口
|
||
|
|
"""
|
||
|
|
|
||
|
|
import logging
|
||
|
|
import sys
|
||
|
|
from typing import Optional
|
||
|
|
|
||
|
|
from selenium import webdriver
|
||
|
|
from selenium.webdriver.chrome.options import Options
|
||
|
|
from selenium.webdriver.chrome.service import Service
|
||
|
|
|
||
|
|
logger = logging.getLogger("damai.driver")
|
||
|
|
|
||
|
|
|
||
|
|
def create_driver(
|
||
|
|
driver_path: str,
|
||
|
|
mobile_emulation: bool = True,
|
||
|
|
headless: bool = False,
|
||
|
|
disable_images: bool = True,
|
||
|
|
page_load_strategy: str = "eager",
|
||
|
|
) -> webdriver.Chrome:
|
||
|
|
"""
|
||
|
|
创建配置好的 Chrome 驱动
|
||
|
|
|
||
|
|
Args:
|
||
|
|
driver_path: chromedriver 可执行文件路径
|
||
|
|
mobile_emulation: 是否模拟移动设备
|
||
|
|
headless: 是否无头模式
|
||
|
|
disable_images: 是否禁用图片加载
|
||
|
|
page_load_strategy: 页面加载策略 (normal/eager/none)
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
配置好的 Chrome WebDriver 实例
|
||
|
|
"""
|
||
|
|
options = Options()
|
||
|
|
|
||
|
|
# 移动端模拟
|
||
|
|
if mobile_emulation:
|
||
|
|
options.add_experimental_option(
|
||
|
|
"mobileEmulation", {"deviceName": "Nexus 6"}
|
||
|
|
)
|
||
|
|
|
||
|
|
# 反检测
|
||
|
|
options.add_argument("--disable-blink-features=AutomationControlled")
|
||
|
|
options.add_experimental_option("excludeSwitches", ["enable-automation"])
|
||
|
|
options.add_experimental_option("useAutomationExtension", False)
|
||
|
|
|
||
|
|
# 性能优化
|
||
|
|
if disable_images:
|
||
|
|
prefs = {
|
||
|
|
"profile.managed_default_content_settings.images": 2,
|
||
|
|
"profile.managed_default_content_settings.fonts": 2,
|
||
|
|
}
|
||
|
|
options.add_experimental_option("prefs", prefs)
|
||
|
|
|
||
|
|
# 页面加载策略
|
||
|
|
options.page_load_strategy = page_load_strategy
|
||
|
|
|
||
|
|
# 无头模式
|
||
|
|
if headless:
|
||
|
|
options.add_argument("--headless=new")
|
||
|
|
|
||
|
|
# Linux 环境
|
||
|
|
if sys.platform != "win32":
|
||
|
|
options.add_argument("--no-sandbox")
|
||
|
|
options.add_argument("--disable-dev-shm-usage")
|
||
|
|
options.add_argument("--disable-gpu")
|
||
|
|
|
||
|
|
service = Service(executable_path=driver_path)
|
||
|
|
driver = webdriver.Chrome(service=service, options=options)
|
||
|
|
|
||
|
|
# 隐藏 webdriver 痕迹
|
||
|
|
driver.execute_cdp_cmd(
|
||
|
|
"Page.addScriptToEvaluateOnNewDocument",
|
||
|
|
{
|
||
|
|
"source": """
|
||
|
|
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
|
||
|
|
window.navigator.chrome = {runtime: {}};
|
||
|
|
Object.defineProperty(navigator, 'plugins', {
|
||
|
|
get: () => [1, 2, 3, 4, 5],
|
||
|
|
});
|
||
|
|
Object.defineProperty(navigator, 'languages', {
|
||
|
|
get: () => ['zh-CN', 'en-US', 'en'],
|
||
|
|
});
|
||
|
|
"""
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
logger.info(f"Chrome 驱动已创建 | mobile={mobile_emulation} headless={headless}")
|
||
|
|
return driver
|