|
|
@@ -1,119 +1,73 @@
|
|
|
import os
|
|
|
+import random
|
|
|
import time
|
|
|
from typing import Optional
|
|
|
from DrissionPage import Chromium, ChromiumOptions, ChromiumPage
|
|
|
from pathlib import Path
|
|
|
-from config.settings import OUTPUT_DIR, WORK_DIR, BROWSER_CONFIG_DIR
|
|
|
-from utils.logu import logger
|
|
|
-from pydantic import BaseModel
|
|
|
+from .logu import logger
|
|
|
+from DrissionPage._elements.chromium_element import ChromiumElement
|
|
|
+def create_browser(address='127.0.0.1:16800', user_data_dir='', browser_path=''):
|
|
|
|
|
|
-BROWSER_PATH=r"C:\Program Files\Google\Chrome\Application\chrome.exe"
|
|
|
-
|
|
|
-def genarate_chrome_ini(address="localhost:9321"):
|
|
|
- port = address.split(':')[1]
|
|
|
- chrome_options = ChromiumOptions().set_browser_path(BROWSER_PATH)
|
|
|
+ chrome_options = ChromiumOptions(read_file=False)
|
|
|
+ # 务必不能小于10000,否则可能由于环境问题导致错误
|
|
|
chrome_options.set_address(address)
|
|
|
- chrome_options.set_user_data_path(str(OUTPUT_DIR / f'user_data_dir_{port}'))
|
|
|
- # chrome_options.no_imgs(True).mute(True)
|
|
|
- # chrome_options.incognito(True)
|
|
|
- path = chrome_options.save(BROWSER_CONFIG_DIR / f'{port}.ini')
|
|
|
- return path
|
|
|
-
|
|
|
-class ChromeOptions(BaseModel):
|
|
|
- ini_path: Optional[str] = BROWSER_CONFIG_DIR / '9321.ini'
|
|
|
- browser_path: Optional[str] = None
|
|
|
- user_data_dir: Optional[str] = None
|
|
|
- address: Optional[str] = None
|
|
|
- headless: Optional[bool] = False
|
|
|
- proxy: Optional[str] = None
|
|
|
- no_imgs: Optional[bool] = False
|
|
|
- auto_port: Optional[bool] = False
|
|
|
- save: Optional[bool] = False
|
|
|
-
|
|
|
-def load_chrome_from_ini(options:ChromeOptions):
|
|
|
- chrome_options = ChromiumOptions(ini_path=options.ini_path)
|
|
|
- if options.browser_path:
|
|
|
- chrome_options.set_browser_path(options.browser_path)
|
|
|
- if options.proxy:
|
|
|
- chrome_options.set_proxy(options.proxy)
|
|
|
- if options.user_data_dir:
|
|
|
- chrome_options.set_user_data_path(options.user_data_dir)
|
|
|
- # 如果存在代理环境变量
|
|
|
- elif 'HTTP_PROXY' in os.environ:
|
|
|
- chrome_options.set_proxy(os.environ['HTTP_PROXY'])
|
|
|
- if options.auto_port:
|
|
|
- chrome_options.auto_port(options.auto_port)
|
|
|
- if options.no_imgs:
|
|
|
- chrome_options.no_imgs(options.no_imgs)
|
|
|
- if options.address:
|
|
|
- chrome_options.headless(options.headless)
|
|
|
- if options.address:
|
|
|
- chrome_options.set_address(options.address)
|
|
|
- if options.save:
|
|
|
- chrome_options.save(options.ini_path)
|
|
|
- logger.info(f"proxy {options.proxy}")
|
|
|
- page = ChromiumPage(chrome_options)
|
|
|
- return page
|
|
|
-
|
|
|
-def fake_ua():
|
|
|
-
|
|
|
- # 创建一个 UserAgent 对象
|
|
|
- ua = UserAgent()
|
|
|
+ if user_data_dir:
|
|
|
+ chrome_options.set_user_data_path(user_data_dir)
|
|
|
+ if browser_path:
|
|
|
+ chrome_options.set_browser_path(browser_path)
|
|
|
+ driver = ChromiumPage(addr_or_opts=chrome_options)
|
|
|
+ return driver
|
|
|
|
|
|
- # 生成支持的浏览器的 User-Agent 字符串
|
|
|
- chrome_ua = ua.chrome # Chrome 浏览器
|
|
|
- firefox_ua = ua.firefox # Firefox 浏览器
|
|
|
- safari_ua = ua.safari # Safari 浏览器
|
|
|
- edge_ua = ua.edge # Chromium Edge 浏览器
|
|
|
|
|
|
- # 打印生成的 User-Agent 字符串
|
|
|
- print("Chrome User-Agent:", chrome_ua)
|
|
|
- print("Firefox User-Agent:", firefox_ua)
|
|
|
- print("Safari User-Agent:", safari_ua)
|
|
|
- print("Edge User-Agent:", edge_ua)
|
|
|
- return chrome_ua
|
|
|
|
|
|
-def load_random_ua_chrome(headless=False):
|
|
|
- chrome_options = ChromiumOptions()
|
|
|
- chrome_options.auto_port(True)
|
|
|
- chrome_options.no_imgs(False)
|
|
|
- chrome_options.set_user_agent(fake_ua())
|
|
|
- chrome_options.arguments.append("--lang=en")
|
|
|
- chrome_options.headless(headless)
|
|
|
- page = ChromiumPage(chrome_options)
|
|
|
- # page.set.auto_handle_alert(True)
|
|
|
- return page
|
|
|
+def click_random_pos(ele:ChromiumElement, delay_random=(0,5), safe_zone=0.2, wait_timeout=35):
|
|
|
|
|
|
-def test_random_ua_chrome():
|
|
|
- page = load_random_ua_chrome()
|
|
|
- tab = page.latest_tab
|
|
|
- keyword = "Acalypha rivularis essential oil"
|
|
|
- url = f"https://www.google.com/search?q={keyword}"
|
|
|
- # url = f"https://www.google.com/"
|
|
|
- # url = "https://bot.sannysoft.com/"
|
|
|
- tab.get(url)
|
|
|
- print(tab.url)
|
|
|
- if page.browser._chromium_options.is_headless:
|
|
|
- tab.get_screenshot('./1.png')
|
|
|
- # page.quit()
|
|
|
+ """在元素中心区域随机点击
|
|
|
+
|
|
|
+ Args:
|
|
|
+ ele: 要点击的元素
|
|
|
+ delay_random: 点击前的随机延迟时间范围(秒)
|
|
|
+ safe_zone: 安全区域比例,0.2表示在中心80%区域内随机点击
|
|
|
+ wait_timeout: 等待元素出现并具有可点击矩形区域的超时时间(秒)
|
|
|
+ """
|
|
|
+ # 等待元素出现并具有可点击的矩形区域
|
|
|
+ logger.debug(f"等待元素出现并具有可点击矩形区域,超时时间:{wait_timeout}秒")
|
|
|
+ ele.wait.has_rect(timeout=wait_timeout)
|
|
|
+
|
|
|
+ # 获取元素大小和位置信息
|
|
|
+ width, height = ele.rect.size
|
|
|
+ logger.debug(f"元素大小:{width}x{height}")
|
|
|
+ center_x, center_y = width/2, height/2
|
|
|
+
|
|
|
+ max_offset_x = width * safe_zone
|
|
|
+ max_offset_y = height * safe_zone
|
|
|
+
|
|
|
+ # 在中心点附近生成随机偏移量
|
|
|
+ offset_x = center_x + random.uniform(-max_offset_x, max_offset_x)
|
|
|
+ offset_y = center_y + random.uniform(-max_offset_y, max_offset_y)
|
|
|
+ logger.debug(f"中心点:{center_x},{center_y}")
|
|
|
+ logger.debug(f"偏移量:{offset_x},{offset_y}")
|
|
|
+ # 执行带偏移量的点击
|
|
|
+ time.sleep(random.uniform(*delay_random))
|
|
|
+ ele.click.at(offset_x, offset_y)
|
|
|
|
|
|
-def test_normal_chrome():
|
|
|
- # genarate_chrome_ini()
|
|
|
- page = load_chrome_from_ini(proxy='http://localhost:1881')
|
|
|
- tab = page.latest_tab
|
|
|
- keyword = "Acalypha rivularis essential oil"
|
|
|
- url = f"https://www.google.com/search?q={keyword}"
|
|
|
- url = "https://bot.sannysoft.com/"
|
|
|
- # recaptcha 验证码检测
|
|
|
- # url = "https://patrickhlauke.github.io/recaptcha/"
|
|
|
- tab.get(url)
|
|
|
- tab.scroll.to_bottom()
|
|
|
- # tab.get_screenshot('./1.png')
|
|
|
- # page.quit()
|
|
|
+def find_and_click_random(driver:ChromiumElement|ChromiumPage, locator, *args, **kwargs):
|
|
|
+ """查找元素并随机点击
|
|
|
+
|
|
|
+ Args:
|
|
|
+ driver: 浏览器驱动或元素
|
|
|
+ locator: 元素定位器
|
|
|
+ *args: 传递给 ele() 方法的位置参数
|
|
|
+ **kwargs: 传递给 click_random_pos() 方法的关键字参数
|
|
|
+ """
|
|
|
+ ele = driver.ele(locator, *args)
|
|
|
+ return click_random_pos(ele, **kwargs)
|
|
|
|
|
|
def main():
|
|
|
- test_random_ua_chrome()
|
|
|
- # test_normal_chrome()
|
|
|
+ page = create_browser()
|
|
|
+ page._driver._websocket_url
|
|
|
+ page.get("chrome://version")
|
|
|
+ print(page._driver._websocket_url)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
main()
|