| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- """
- PyAutoGUI 公共封装:统一 PAUSE / FAILSAFE、移动点击、键入与随机停顿。
- 其它脚本请使用「from workplace.pyautogui import …」,勿把 workplace 目录单独插到 sys.path 最前再 `import pyautogui`,以免与 pip 包名冲突。
- 依赖:pip install pyautogui
- """
- from __future__ import annotations
- import random
- import time
- from typing import Any
- import pyautogui as _pa
- # 可调默认节奏(秒)
- DEFAULT_MOVE_DURATION = 0.2
- DEFAULT_CLICK_INTERVAL = 0.05
- DEFAULT_TYPE_INTERVAL = 0.03
- def configure(*, pause: float = 0.05, failsafe: bool = True) -> None:
- """每步操作之间的全局暂停;FAILSAFE:鼠标移到屏幕左上角可抛异常中断。"""
- _pa.PAUSE = pause
- _pa.FAILSAFE = failsafe
- def init_singleton(*, pause: float = 0.05, failsafe: bool = True) -> None:
- """
- 应用入口显式初始化(与 ``main.start`` 开头调用一次);多次调用安全,会再次 ``configure``。
- 导入本模块时已 ``configure()`` 一次;此处供流程上「单例就绪」语义。
- """
- configure(pause=pause, failsafe=failsafe)
- configure()
- def human_pause(min_s: float = 0.05, max_s: float = 0.22) -> None:
- """短随机等待,模拟人手间隔。"""
- time.sleep(random.uniform(min_s, max_s))
- def sleep_human_pre_click_after_pointer_move() -> None:
- """移鼠落稳后、左键前:约 0.12–0.42s(瞄准/制动,常见数百毫秒量级)。"""
- time.sleep(random.uniform(0.12, 0.42))
- def sleep_human_pointer_poll_step() -> None:
- """轮询指针是否到位,非主观停顿;略拉开间隔减轻忙等。"""
- time.sleep(random.uniform(0.018, 0.048))
- def sleep_human_after_pointer_settled_before_typing() -> None:
- """指针已到目标、即将点击聚焦输入框前:约 0.10–0.42s。"""
- time.sleep(random.uniform(0.10, 0.42))
- def sleep_human_chrome_debug_process_ready() -> None:
- """远程调试 Chrome 新进程就绪(非人手,仅拉开方差)。"""
- time.sleep(random.uniform(2.35, 3.12))
- def sleep_human_screenshot_settled_before_template_match() -> None:
- """截屏后等界面静止再跑模板匹配:约 0.72–1.68s。"""
- time.sleep(random.uniform(0.72, 1.68))
- def sleep_human_ui_scan_short() -> None:
- """扫一眼列表/等展开动效:约 0.55–1.45s。"""
- time.sleep(random.uniform(0.55, 1.45))
- def sleep_human_ui_scan_after_small_cursor_nudge() -> None:
- """微移光标(如 move_rel)后接下一步:约 0.32–0.82s。"""
- time.sleep(random.uniform(0.32, 0.82))
- def sleep_human_between_feed_filter_steps() -> None:
- """筛选流里步骤间略读界面:约 0.58–1.48s。"""
- time.sleep(random.uniform(0.58, 1.48))
- def sleep_human_before_click_sort_or_tab_after_move() -> None:
- """已移到排序项/「图文」等目标、按下前:约 0.48–1.28s。"""
- time.sleep(random.uniform(0.48, 1.28))
- def sleep_human_open_feed_card_before_title_click() -> None:
- """列表点开笔记前略读标题区:约 1.05–2.15s。"""
- time.sleep(random.uniform(1.05, 2.15))
- def sleep_human_after_feed_card_opens_detail() -> None:
- """进入详情后等布局稳定:约 0.70–1.58s。"""
- time.sleep(random.uniform(0.70, 1.58))
- def sleep_human_top_bar_filter_after_detail_before_click() -> None:
- """从详情回到顶栏点「筛选」:约 0.26–0.64s。"""
- time.sleep(random.uniform(0.26, 0.64))
- def sleep_human_extra_after_dom_click_poll(*, base_sec: float) -> None:
- """点击后等 DOM/输入值更新:在 ``base_sec`` 上再加一段随机余量。"""
- b = float(base_sec)
- time.sleep(b + random.uniform(0, min(0.14, max(0.04, b * 0.32))))
- def screen_size() -> tuple[int, int]:
- """当前屏幕逻辑分辨率 (width, height)。"""
- w, h = _pa.size()
- return int(w), int(h)
- def move_to(x: int, y: int, *, duration: float = DEFAULT_MOVE_DURATION) -> None:
- _pa.moveTo(int(x), int(y), duration=duration)
- def move_rel(dx: int, dy: int, *, duration: float = DEFAULT_MOVE_DURATION) -> None:
- """相对当前光标移动(屏幕像素);与视口内向量配合时通常假设 CSS 像素与屏幕位移一致。"""
- _pa.moveRel(int(dx), int(dy), duration=duration)
- def click_at(
- x: int,
- y: int,
- *,
- duration: float = DEFAULT_MOVE_DURATION,
- clicks: int = 1,
- interval: float = DEFAULT_CLICK_INTERVAL,
- button: str = "left",
- ) -> None:
- _pa.click(
- int(x),
- int(y),
- clicks=clicks,
- interval=interval,
- duration=duration,
- button=button,
- )
- def click_here(*, clicks: int = 1, interval: float = DEFAULT_CLICK_INTERVAL) -> None:
- """在当前鼠标位置点击。"""
- _pa.click(clicks=clicks, interval=interval)
- def type_text(text: str, *, interval: float = DEFAULT_TYPE_INTERVAL) -> None:
- """逐字符键入(英文/数字为主;中文需系统输入法已就绪)。"""
- _pa.write(text, interval=interval)
- def press_key(key: str, *, presses: int = 1, interval: float = 0.05) -> None:
- _pa.press(key, presses=presses, interval=interval)
- def hotkey(*keys: str, interval: float = 0.05) -> None:
- _pa.hotkey(*keys, interval=interval)
- def scroll_at(
- x: int,
- y: int,
- clicks: int,
- *,
- duration: float = DEFAULT_MOVE_DURATION,
- ) -> None:
- """先移到坐标再滚轮;clicks 正数向上、负数向下(与 PyAutoGUI 一致)。"""
- move_to(x, y, duration=duration)
- _pa.scroll(int(clicks))
- # 需要直接调官方 API 时用(如 locateOnScreen)
- raw: Any = _pa
- __all__ = [
- "configure",
- "init_singleton",
- "human_pause",
- "sleep_human_pre_click_after_pointer_move",
- "sleep_human_pointer_poll_step",
- "sleep_human_after_pointer_settled_before_typing",
- "sleep_human_chrome_debug_process_ready",
- "sleep_human_screenshot_settled_before_template_match",
- "sleep_human_ui_scan_short",
- "sleep_human_ui_scan_after_small_cursor_nudge",
- "sleep_human_between_feed_filter_steps",
- "sleep_human_before_click_sort_or_tab_after_move",
- "sleep_human_open_feed_card_before_title_click",
- "sleep_human_after_feed_card_opens_detail",
- "sleep_human_top_bar_filter_after_detail_before_click",
- "sleep_human_extra_after_dom_click_poll",
- "screen_size",
- "move_to",
- "move_rel",
- "click_at",
- "click_here",
- "type_text",
- "press_key",
- "hotkey",
- "scroll_at",
- "raw",
- ]
|