148 lines
3.9 KiB
Python
148 lines
3.9 KiB
Python
import logging
|
|
import time
|
|
from typing import Optional
|
|
from playwright.sync_api import Page, TimeoutError as PlaywrightTimeoutError
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class BrowserUtils:
|
|
"""浏览器操作工具类"""
|
|
|
|
@staticmethod
|
|
def wait_for_element(page: Page, selector: str, timeout: int = 30000) -> bool:
|
|
"""
|
|
等待元素出现
|
|
|
|
Args:
|
|
page: Playwright页面对象
|
|
selector: CSS选择器
|
|
timeout: 超时时间(毫秒)
|
|
|
|
Returns:
|
|
bool: 成功返回True,超时返回False
|
|
"""
|
|
try:
|
|
page.wait_for_selector(selector, timeout=timeout)
|
|
return True
|
|
except PlaywrightTimeoutError:
|
|
logger.warning(f"等待元素超时: {selector}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def fill_input(
|
|
page: Page, selector: str, text: str, clear_first: bool = True
|
|
) -> bool:
|
|
"""
|
|
填充输入框
|
|
|
|
Args:
|
|
page: Playwright页面对象
|
|
selector: CSS选择器
|
|
text: 要填充的文本
|
|
clear_first: 是否先清除原有内容
|
|
|
|
Returns:
|
|
bool: 成功返回True,失败返回False
|
|
"""
|
|
try:
|
|
# 等待元素出现
|
|
if not BrowserUtils.wait_for_element(page, selector):
|
|
return False
|
|
|
|
# 如果需要先清除原有内容
|
|
if clear_first:
|
|
page.fill(selector, "")
|
|
|
|
# 填充文本
|
|
page.fill(selector, text)
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"填充输入框时出错: {str(e)}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def click_element(page: Page, selector: str, timeout: int = 30000) -> bool:
|
|
"""
|
|
点击元素
|
|
|
|
Args:
|
|
page: Playwright页面对象
|
|
selector: CSS选择器
|
|
timeout: 超时时间(毫秒)
|
|
|
|
Returns:
|
|
bool: 成功返回True,失败返回False
|
|
"""
|
|
try:
|
|
# 等待元素出现
|
|
if not BrowserUtils.wait_for_element(page, selector, timeout):
|
|
return False
|
|
|
|
# 点击元素
|
|
page.click(selector)
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"点击元素时出错: {str(e)}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def get_text(page: Page, selector: str) -> Optional[str]:
|
|
"""
|
|
获取元素文本内容
|
|
|
|
Args:
|
|
page: Playwright页面对象
|
|
selector: CSS选择器
|
|
|
|
Returns:
|
|
str or None: 元素文本内容或None
|
|
"""
|
|
try:
|
|
# 等待元素出现
|
|
if not BrowserUtils.wait_for_element(page, selector):
|
|
return None
|
|
|
|
# 获取文本内容
|
|
return page.text_content(selector)
|
|
except Exception as e:
|
|
logger.error(f"获取元素文本内容时出错: {str(e)}")
|
|
return None
|
|
|
|
@staticmethod
|
|
def take_screenshot(page: Page, path: str) -> bool:
|
|
"""
|
|
截取屏幕截图
|
|
|
|
Args:
|
|
page: Playwright页面对象
|
|
path: 截图保存路径
|
|
|
|
Returns:
|
|
bool: 成功返回True,失败返回False
|
|
"""
|
|
try:
|
|
page.screenshot(path=path)
|
|
logger.info(f"已保存截图: {path}")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"截图时出错: {str(e)}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def is_element_visible(page: Page, selector: str) -> bool:
|
|
"""
|
|
检查元素是否可见
|
|
|
|
Args:
|
|
page: Playwright页面对象
|
|
selector: CSS选择器
|
|
|
|
Returns:
|
|
bool: 可见返回True,不可见返回False
|
|
"""
|
|
try:
|
|
return page.is_visible(selector)
|
|
except Exception:
|
|
return False
|