pyautogui.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. """
  2. PyAutoGUI 公共封装:统一 PAUSE / FAILSAFE、移动点击、键入与随机停顿。
  3. 其它脚本请使用「from workplace.pyautogui import …」,勿把 workplace 目录单独插到 sys.path 最前再 `import pyautogui`,以免与 pip 包名冲突。
  4. 依赖:pip install pyautogui
  5. """
  6. from __future__ import annotations
  7. import random
  8. import time
  9. from typing import Any
  10. import pyautogui as _pa
  11. # 可调默认节奏(秒)
  12. DEFAULT_MOVE_DURATION = 0.2
  13. DEFAULT_CLICK_INTERVAL = 0.05
  14. DEFAULT_TYPE_INTERVAL = 0.03
  15. def configure(*, pause: float = 0.05, failsafe: bool = True) -> None:
  16. """每步操作之间的全局暂停;FAILSAFE:鼠标移到屏幕左上角可抛异常中断。"""
  17. _pa.PAUSE = pause
  18. _pa.FAILSAFE = failsafe
  19. def init_singleton(*, pause: float = 0.05, failsafe: bool = True) -> None:
  20. """
  21. 应用入口显式初始化(与 ``main.start`` 开头调用一次);多次调用安全,会再次 ``configure``。
  22. 导入本模块时已 ``configure()`` 一次;此处供流程上「单例就绪」语义。
  23. """
  24. configure(pause=pause, failsafe=failsafe)
  25. configure()
  26. def human_pause(min_s: float = 0.05, max_s: float = 0.22) -> None:
  27. """短随机等待,模拟人手间隔。"""
  28. time.sleep(random.uniform(min_s, max_s))
  29. def sleep_human_pre_click_after_pointer_move() -> None:
  30. """移鼠落稳后、左键前:约 0.12–0.42s(瞄准/制动,常见数百毫秒量级)。"""
  31. time.sleep(random.uniform(0.12, 0.42))
  32. def sleep_human_pointer_poll_step() -> None:
  33. """轮询指针是否到位,非主观停顿;略拉开间隔减轻忙等。"""
  34. time.sleep(random.uniform(0.018, 0.048))
  35. def sleep_human_after_pointer_settled_before_typing() -> None:
  36. """指针已到目标、即将点击聚焦输入框前:约 0.10–0.42s。"""
  37. time.sleep(random.uniform(0.10, 0.42))
  38. def sleep_human_chrome_debug_process_ready() -> None:
  39. """远程调试 Chrome 新进程就绪(非人手,仅拉开方差)。"""
  40. time.sleep(random.uniform(2.35, 3.12))
  41. def sleep_human_screenshot_settled_before_template_match() -> None:
  42. """截屏后等界面静止再跑模板匹配:约 0.72–1.68s。"""
  43. time.sleep(random.uniform(0.72, 1.68))
  44. def sleep_human_ui_scan_short() -> None:
  45. """扫一眼列表/等展开动效:约 0.55–1.45s。"""
  46. time.sleep(random.uniform(0.55, 1.45))
  47. def sleep_human_ui_scan_after_small_cursor_nudge() -> None:
  48. """微移光标(如 move_rel)后接下一步:约 0.32–0.82s。"""
  49. time.sleep(random.uniform(0.32, 0.82))
  50. def sleep_human_between_feed_filter_steps() -> None:
  51. """筛选流里步骤间略读界面:约 0.58–1.48s。"""
  52. time.sleep(random.uniform(0.58, 1.48))
  53. def sleep_human_before_click_sort_or_tab_after_move() -> None:
  54. """已移到排序项/「图文」等目标、按下前:约 0.48–1.28s。"""
  55. time.sleep(random.uniform(0.48, 1.28))
  56. def sleep_human_open_feed_card_before_title_click() -> None:
  57. """列表点开笔记前略读标题区:约 1.05–2.15s。"""
  58. time.sleep(random.uniform(1.05, 2.15))
  59. def sleep_human_after_feed_card_opens_detail() -> None:
  60. """进入详情后等布局稳定:约 0.70–1.58s。"""
  61. time.sleep(random.uniform(0.70, 1.58))
  62. def sleep_human_top_bar_filter_after_detail_before_click() -> None:
  63. """从详情回到顶栏点「筛选」:约 0.26–0.64s。"""
  64. time.sleep(random.uniform(0.26, 0.64))
  65. def sleep_human_extra_after_dom_click_poll(*, base_sec: float) -> None:
  66. """点击后等 DOM/输入值更新:在 ``base_sec`` 上再加一段随机余量。"""
  67. b = float(base_sec)
  68. time.sleep(b + random.uniform(0, min(0.14, max(0.04, b * 0.32))))
  69. def screen_size() -> tuple[int, int]:
  70. """当前屏幕逻辑分辨率 (width, height)。"""
  71. w, h = _pa.size()
  72. return int(w), int(h)
  73. def move_to(x: int, y: int, *, duration: float = DEFAULT_MOVE_DURATION) -> None:
  74. _pa.moveTo(int(x), int(y), duration=duration)
  75. def move_rel(dx: int, dy: int, *, duration: float = DEFAULT_MOVE_DURATION) -> None:
  76. """相对当前光标移动(屏幕像素);与视口内向量配合时通常假设 CSS 像素与屏幕位移一致。"""
  77. _pa.moveRel(int(dx), int(dy), duration=duration)
  78. def click_at(
  79. x: int,
  80. y: int,
  81. *,
  82. duration: float = DEFAULT_MOVE_DURATION,
  83. clicks: int = 1,
  84. interval: float = DEFAULT_CLICK_INTERVAL,
  85. button: str = "left",
  86. ) -> None:
  87. _pa.click(
  88. int(x),
  89. int(y),
  90. clicks=clicks,
  91. interval=interval,
  92. duration=duration,
  93. button=button,
  94. )
  95. def click_here(*, clicks: int = 1, interval: float = DEFAULT_CLICK_INTERVAL) -> None:
  96. """在当前鼠标位置点击。"""
  97. _pa.click(clicks=clicks, interval=interval)
  98. def type_text(text: str, *, interval: float = DEFAULT_TYPE_INTERVAL) -> None:
  99. """逐字符键入(英文/数字为主;中文需系统输入法已就绪)。"""
  100. _pa.write(text, interval=interval)
  101. def press_key(key: str, *, presses: int = 1, interval: float = 0.05) -> None:
  102. _pa.press(key, presses=presses, interval=interval)
  103. def hotkey(*keys: str, interval: float = 0.05) -> None:
  104. _pa.hotkey(*keys, interval=interval)
  105. def scroll_at(
  106. x: int,
  107. y: int,
  108. clicks: int,
  109. *,
  110. duration: float = DEFAULT_MOVE_DURATION,
  111. ) -> None:
  112. """先移到坐标再滚轮;clicks 正数向上、负数向下(与 PyAutoGUI 一致)。"""
  113. move_to(x, y, duration=duration)
  114. _pa.scroll(int(clicks))
  115. # 需要直接调官方 API 时用(如 locateOnScreen)
  116. raw: Any = _pa
  117. __all__ = [
  118. "configure",
  119. "init_singleton",
  120. "human_pause",
  121. "sleep_human_pre_click_after_pointer_move",
  122. "sleep_human_pointer_poll_step",
  123. "sleep_human_after_pointer_settled_before_typing",
  124. "sleep_human_chrome_debug_process_ready",
  125. "sleep_human_screenshot_settled_before_template_match",
  126. "sleep_human_ui_scan_short",
  127. "sleep_human_ui_scan_after_small_cursor_nudge",
  128. "sleep_human_between_feed_filter_steps",
  129. "sleep_human_before_click_sort_or_tab_after_move",
  130. "sleep_human_open_feed_card_before_title_click",
  131. "sleep_human_after_feed_card_opens_detail",
  132. "sleep_human_top_bar_filter_after_detail_before_click",
  133. "sleep_human_extra_after_dom_click_poll",
  134. "screen_size",
  135. "move_to",
  136. "move_rel",
  137. "click_at",
  138. "click_here",
  139. "type_text",
  140. "press_key",
  141. "hotkey",
  142. "scroll_at",
  143. "raw",
  144. ]