camoufox_broswer.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from camoufox import Camoufox
  2. from camoufox.server import launch_server
  3. from camoufox.async_api import AsyncCamoufox
  4. from playwright.async_api import Browser,Page
  5. import asyncio
  6. import signal
  7. import os
  8. import datetime
  9. from typing import Optional, Dict
  10. import logging
  11. from pydantic import BaseModel
  12. from typing import Optional, Dict
  13. from config.settings import OUTPUT_DIR, WORK_DIR
  14. class BrowserConfig(BaseModel):
  15. """浏览器配置参数模型"""
  16. headless: bool = False
  17. geoip: bool = True
  18. proxy: Optional[Dict] = {'server': 'http://localhost:1881'}
  19. init_url: str = "https://www.browserscan.net"
  20. screenshot_dir: str = OUTPUT_DIR / "screenshots"
  21. class PageOperations:
  22. """封装页面交互操作"""
  23. def __init__(self, page: Page, config: BrowserConfig):
  24. self.page = page
  25. self.config = config
  26. async def search_element(self, selector: str, timeout: float = 30.0):
  27. """等待并返回指定元素"""
  28. return await self.page.wait_for_selector(selector, timeout=timeout)
  29. async def click_element(self, selector: str):
  30. """点击指定选择器的元素"""
  31. element = await self.search_element(selector)
  32. await element.click()
  33. async def take_screenshot(self, filename: str):
  34. """带时间戳的截图保存"""
  35. os.makedirs(self.config.screenshot_dir, exist_ok=True)
  36. timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
  37. path = os.path.join(self.config.screenshot_dir, f"{timestamp}_{filename}")
  38. await self.page.screenshot(path=path, full_page=True)
  39. return path
  40. async def fill_input(self, selector: str, text: str):
  41. """在指定输入框填充文本"""
  42. element = await self.search_element(selector)
  43. await element.fill(text)
  44. async def press_enter(self):
  45. """执行键盘回车操作"""
  46. await self.page.keyboard.press("Enter")
  47. class CamoufoxManager:
  48. """管理浏览器实例的生命周期"""
  49. def __init__(self, config: BrowserConfig = BrowserConfig()):
  50. self.config = config
  51. self.browser:Browser = None
  52. self.page:Page = None
  53. self.page_ops: PageOperations = None
  54. async def __aenter__(self):
  55. """异步上下文管理器入口"""
  56. self.browser = await AsyncCamoufox(
  57. headless=self.config.headless,
  58. geoip=self.config.geoip,
  59. proxy=self.config.proxy
  60. ).__aenter__()
  61. # 自动创建新页面并导航到初始URL
  62. self.page = await self.browser.new_page()
  63. await self.page.goto(self.config.init_url)
  64. self.page_ops = PageOperations(self.page, self.config)
  65. logging.info(f"Browser initialized with page: {self.page.url}")
  66. return self
  67. async def __aexit__(self, exc_type, exc, tb):
  68. """异步上下文管理器退出"""
  69. await self.browser.__aexit__(exc_type, exc, tb)
  70. async def aio_main(config: BrowserConfig = BrowserConfig(init_url="https://www.google.com")):
  71. """新版主运行函数(测试自动页面创建)"""
  72. async with CamoufoxManager(config) as manager:
  73. logging.info(f"当前页面URL: {manager.page.url}")
  74. # 保持页面存活直到手动关闭
  75. try:
  76. while not manager.page.is_closed():
  77. await asyncio.sleep(1)
  78. except KeyboardInterrupt:
  79. logging.info("接收到终止信号,关闭浏览器...")
  80. finally:
  81. await manager.page.close()
  82. logging.info("测试完成")
  83. async def task():
  84. pass
  85. def main():
  86. asyncio.run(aio_main())
  87. if __name__ == "__main__":
  88. main()