68 lines
2.4 KiB
Python
68 lines
2.4 KiB
Python
"""
|
||
UI 自动化基类占位 (推荐使用 Playwright)
|
||
"""
|
||
from playwright.sync_api import sync_playwright
|
||
from framework.core.logger import get_logger
|
||
import time
|
||
|
||
logger = get_logger("BaseUI")
|
||
|
||
class BaseUI:
|
||
def __init__(self, headless=False):
|
||
self.playwright = None
|
||
self.browser = None
|
||
self.context = None
|
||
self.page = None
|
||
self.headless = headless
|
||
|
||
def start(self):
|
||
"""启动浏览器并伪装"""
|
||
self.playwright = sync_playwright().start()
|
||
# 增加伪装配置
|
||
self.browser = self.playwright.chromium.launch(
|
||
headless=self.headless,
|
||
args=["--disable-blink-features=AutomationControlled"]
|
||
)
|
||
# 设置真实的 User-Agent
|
||
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
|
||
self.context = self.browser.new_context(user_agent=user_agent)
|
||
self.page = self.context.new_page()
|
||
|
||
# 实时打印浏览器控制台日志,方便排查白屏
|
||
self.page.on("console", lambda msg: logger.info(f"[BROWSER LOG] {msg.text}"))
|
||
self.page.on("pageerror", lambda exc: logger.error(f"[BROWSER ERROR] {exc}"))
|
||
|
||
logger.info("Browser started with spoofing and logging")
|
||
return self.page
|
||
|
||
def stop(self):
|
||
"""关闭浏览器"""
|
||
if self.browser:
|
||
self.browser.close()
|
||
if self.playwright:
|
||
self.playwright.stop()
|
||
logger.info("Browser stopped")
|
||
|
||
def navigate(self, url):
|
||
logger.info(f"Navigate to {url}")
|
||
# 使用更稳健的加载策略:DOM 加载完即继续,后续靠 wait_for_selector
|
||
self.page.goto(url, wait_until="domcontentloaded", timeout=30000)
|
||
# 给 2 秒缓冲时间让脚本执行
|
||
time.sleep(2)
|
||
|
||
def click(self, selector, timeout=5000):
|
||
try:
|
||
logger.info(f"Clicking: {selector}")
|
||
self.page.click(selector, timeout=timeout)
|
||
except Exception as e:
|
||
self.page.screenshot(path="click_failed.png")
|
||
logger.error(f"Click failed on {selector}, saved screenshot to click_failed.png")
|
||
raise e
|
||
|
||
def fill(self, selector, value):
|
||
logger.info(f"Filling {selector} with value")
|
||
self.page.fill(selector, value)
|
||
|
||
def wait_for_selector(self, selector, timeout=10000):
|
||
self.page.wait_for_selector(selector, timeout=timeout)
|