drission_page.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import os
  2. import random
  3. import time
  4. from typing import Optional
  5. from pydantic import BaseModel
  6. from DrissionPage import Chromium, ChromiumOptions, ChromiumPage
  7. from pathlib import Path
  8. from .logu import logger
  9. from DrissionPage._elements.chromium_element import ChromiumElement
  10. from config.settings import OUTPUT_DIR, WORK_DIR, BROWSER_CONFIG_DIR
  11. class ChromeOptions(BaseModel):
  12. ini_path: Optional[str] = BROWSER_CONFIG_DIR / '9321.ini'
  13. browser_path: Optional[str] = None
  14. user_data_dir: Optional[str] = None
  15. address: Optional[str] = None
  16. headless: Optional[bool] = False
  17. proxy: Optional[str] = None
  18. no_imgs: Optional[bool] = False
  19. auto_port: Optional[bool] = False
  20. save: Optional[bool] = False
  21. def load_chrome_from_ini(options:ChromeOptions):
  22. chrome_options = ChromiumOptions(ini_path=options.ini_path)
  23. if options.browser_path:
  24. chrome_options.set_browser_path(options.browser_path)
  25. if options.proxy:
  26. chrome_options.set_proxy(options.proxy)
  27. if options.user_data_dir:
  28. chrome_options.set_user_data_path(options.user_data_dir)
  29. # 如果存在代理环境变量
  30. elif 'HTTP_PROXY' in os.environ:
  31. chrome_options.set_proxy(os.environ['HTTP_PROXY'])
  32. if options.auto_port:
  33. chrome_options.auto_port(options.auto_port)
  34. if options.no_imgs:
  35. chrome_options.no_imgs(options.no_imgs)
  36. if options.address:
  37. chrome_options.headless(options.headless)
  38. if options.address:
  39. chrome_options.set_address(options.address)
  40. if options.save:
  41. chrome_options.save(options.ini_path)
  42. logger.info(f"proxy {options.proxy}")
  43. page = ChromiumPage(chrome_options)
  44. return page
  45. def create_browser(address='127.0.0.1:16800', user_data_dir='', browser_path=''):
  46. chrome_options = ChromiumOptions(read_file=False)
  47. # 务必不能小于10000,否则可能由于环境问题导致错误
  48. chrome_options.set_address(address)
  49. if user_data_dir:
  50. chrome_options.set_user_data_path(user_data_dir)
  51. if browser_path:
  52. chrome_options.set_browser_path(browser_path)
  53. driver = ChromiumPage(addr_or_opts=chrome_options)
  54. return driver
  55. def click_random_pos(ele:ChromiumElement, delay_random=(0,5), safe_zone=0.2, wait_timeout=35):
  56. """在元素中心区域随机点击
  57. Args:
  58. ele: 要点击的元素
  59. delay_random: 点击前的随机延迟时间范围(秒)
  60. safe_zone: 安全区域比例,0.2表示在中心80%区域内随机点击
  61. wait_timeout: 等待元素出现并具有可点击矩形区域的超时时间(秒)
  62. """
  63. # 等待元素出现并具有可点击的矩形区域
  64. logger.debug(f"等待元素出现并具有可点击矩形区域,超时时间:{wait_timeout}秒")
  65. ele.wait.has_rect(timeout=wait_timeout)
  66. # 获取元素大小和位置信息
  67. width, height = ele.rect.size
  68. logger.debug(f"元素大小:{width}x{height}")
  69. center_x, center_y = width/2, height/2
  70. max_offset_x = width * safe_zone
  71. max_offset_y = height * safe_zone
  72. # 在中心点附近生成随机偏移量
  73. offset_x = center_x + random.uniform(-max_offset_x, max_offset_x)
  74. offset_y = center_y + random.uniform(-max_offset_y, max_offset_y)
  75. logger.debug(f"中心点:{center_x},{center_y}")
  76. logger.debug(f"偏移量:{offset_x},{offset_y}")
  77. # 执行带偏移量的点击
  78. time.sleep(random.uniform(*delay_random))
  79. ele.click.at(offset_x, offset_y)
  80. def find_and_click_random(driver:ChromiumElement|ChromiumPage, locator, *args, **kwargs):
  81. """查找元素并随机点击
  82. Args:
  83. driver: 浏览器驱动或元素
  84. locator: 元素定位器
  85. *args: 传递给 ele() 方法的位置参数
  86. **kwargs: 传递给 click_random_pos() 方法的关键字参数
  87. """
  88. ele = driver.ele(locator, *args)
  89. return click_random_pos(ele, **kwargs)
  90. def main():
  91. page = create_browser()
  92. page._driver._websocket_url
  93. page.get("chrome://version")
  94. print(page._driver._websocket_url)
  95. if __name__ == "__main__":
  96. main()