Skip to content

Latest commit

 

History

History
758 lines (564 loc) · 23.5 KB

File metadata and controls

758 lines (564 loc) · 23.5 KB

AutoControl

PyPI Python License: MIT

AutoControl 是一個跨平台的 Python GUI 自動化框架,提供滑鼠控制、鍵盤輸入、圖像辨識、螢幕擷取、腳本執行與報告產生等功能 — 透過統一的 API 在 Windows、macOS 和 Linux (X11) 上運作。

English | 简体中文


目錄


功能特色

  • 滑鼠自動化 — 移動、點擊、按下、釋放、拖曳、滾動,支援精確座標控制
  • 鍵盤自動化 — 按下/釋放單一按鍵、輸入字串、組合鍵、按鍵狀態偵測
  • 圖像辨識 — 使用 OpenCV 模板匹配在螢幕上定位 UI 元素,支援可設定的偵測閾值
  • Accessibility 元件搜尋 — 透過作業系統無障礙樹(Windows UIA / macOS AX)依名稱/角色定位按鈕、選單、控制項
  • AI 元件定位(VLM) — 用自然語言描述 UI 元素,交由視覺語言模型(Anthropic / OpenAI)取得螢幕座標
  • OCR — 使用 Tesseract 從螢幕擷取文字,可搜尋、點擊或等待文字出現
  • 剪貼簿 — 於 Windows / macOS / Linux 讀寫系統剪貼簿文字
  • 截圖與螢幕錄製 — 擷取全螢幕或指定區域為圖片,錄製螢幕為影片(AVI/MP4)
  • 動作錄製與回放 — 錄製滑鼠/鍵盤事件並重新播放
  • JSON 腳本執行 — 使用 JSON 動作檔案定義並執行自動化流程(支援 dry-run 與逐步除錯)
  • 排程器 — 以 interval 或 cron 表示式執行腳本,interval 與 cron job 可同時存在
  • 全域熱鍵 — 將 OS 熱鍵綁定到 action 腳本(目前為 Windows,macOS/Linux 保留擴充介面)
  • 事件觸發器 — 偵測到影像出現、視窗出現、像素變化或檔案變動時自動執行腳本
  • 執行歷史 — 以 SQLite 紀錄 scheduler / triggers / hotkeys / REST 的執行結果;錯誤時自動附上截圖
  • 報告產生 — 將測試紀錄匯出為 HTML、JSON 或 XML 報告,包含成功/失敗狀態
  • 遠端自動化 — 同時提供 TCP Socket 伺服器與 REST API 伺服器
  • 外掛載入器 — 將定義 AC_* 可呼叫物的 .py 檔放入目錄,執行時即可註冊成 executor 指令
  • Shell 整合 — 在自動化流程中執行 Shell 命令,支援非同步輸出擷取
  • 回呼執行器 — 觸發自動化函式後自動呼叫回呼函式,實現操作串接
  • 動態套件載入 — 在執行時匯入外部 Python 套件,擴充執行器功能
  • 專案與範本管理 — 快速建立包含 keyword/executor 目錄結構的自動化專案
  • 視窗管理 — 直接將鍵盤/滑鼠事件送至指定視窗(Windows/Linux)
  • GUI 應用程式 — 內建 PySide6 圖形介面,支援即時切換語系(English / 繁體中文 / 简体中文 / 日本語)
  • CLI 執行介面python -m je_auto_control.cli run|list-jobs|start-server|start-rest
  • 跨平台 — 統一 API,支援 Windows、macOS、Linux(X11)

架構

je_auto_control/
├── wrapper/                    # 平台無關 API 層
│   ├── platform_wrapper.py     # 自動偵測作業系統並載入對應後端
│   ├── auto_control_mouse.py   # 滑鼠操作
│   ├── auto_control_keyboard.py# 鍵盤操作
│   ├── auto_control_image.py   # 圖像辨識(OpenCV 模板匹配)
│   ├── auto_control_screen.py  # 截圖、螢幕大小、像素顏色
│   └── auto_control_record.py  # 動作錄製/回放
├── windows/                    # Windows 專用後端(Win32 API / ctypes)
├── osx/                        # macOS 專用後端(pyobjc / Quartz)
├── linux_with_x11/             # Linux 專用後端(python-Xlib)
├── gui/                        # PySide6 GUI 應用程式
└── utils/
    ├── executor/               # JSON 動作執行引擎
    ├── callback/               # 回呼函式執行器
    ├── cv2_utils/              # OpenCV 截圖、模板匹配、影片錄製
    ├── accessibility/          # UIA (Windows) / AX (macOS) 元件搜尋
    ├── vision/                 # VLM 元件定位(Anthropic / OpenAI)
    ├── ocr/                    # Tesseract 文字定位
    ├── clipboard/              # 跨平台剪貼簿
    ├── scheduler/              # Interval + cron 排程器
    ├── hotkey/                 # 全域熱鍵守護程序
    ├── triggers/               # 影像/視窗/像素/檔案 觸發器
    ├── run_history/            # SQLite 執行紀錄 + 錯誤截圖
    ├── rest_api/               # 純 stdlib HTTP/REST 伺服器
    ├── plugin_loader/          # 動態 AC_* 外掛搜尋與註冊
    ├── socket_server/          # TCP Socket 伺服器(遠端自動化)
    ├── shell_process/          # Shell 命令管理器
    ├── generate_report/        # HTML / JSON / XML 報告產生器
    ├── test_record/            # 測試動作紀錄
    ├── script_vars/            # 腳本變數插值
    ├── watcher/                # 滑鼠 / 像素 / log 監看器(Live HUD)
    ├── recording_edit/         # 錄製內容的修剪、過濾、縮放
    ├── json/                   # JSON 動作檔案讀寫
    ├── project/                # 專案建立與範本
    ├── package_manager/        # 動態套件載入
    ├── logging/                # 日誌紀錄
    └── exception/              # 自訂例外類別

platform_wrapper.py 模組會自動偵測目前的作業系統並匯入對應的後端,因此所有 wrapper 函式在不同平台上的行為完全一致。


安裝

基本安裝

pip install je_auto_control

安裝 GUI 支援(PySide6)

pip install je_auto_control[gui]

Linux 前置需求

在 Linux 上安裝前,請先安裝以下系統套件:

sudo apt-get install cmake libssl-dev

系統需求

  • Python >= 3.10
  • pip >= 19.3

相依套件

套件 用途
je_open_cv 圖像辨識(OpenCV 模板匹配)
pillow 截圖擷取
mss 快速多螢幕截圖
pyobjc macOS 後端(在 macOS 上自動安裝)
python-Xlib Linux X11 後端(在 Linux 上自動安裝)
PySide6 GUI 應用程式(選用,使用 [gui] 安裝)
qt-material GUI 主題(選用,使用 [gui] 安裝)
uiautomation Windows Accessibility 後端(選用,首次使用時載入)
pytesseract + Tesseract OCR 文字辨識(選用,首次使用時載入)
anthropic VLM 定位 — Anthropic 後端(選用,首次使用時載入)
openai VLM 定位 — OpenAI 後端(選用,首次使用時載入)

完整第三方相依套件與授權資訊請見 Third_Party_License.md


快速開始

滑鼠控制

import je_auto_control

# 取得目前滑鼠位置
x, y = je_auto_control.get_mouse_position()
print(f"滑鼠位置: ({x}, {y})")

# 移動滑鼠到指定座標
je_auto_control.set_mouse_position(500, 300)

# 在目前位置左鍵點擊(使用按鍵名稱)
je_auto_control.click_mouse("mouse_left")

# 在指定座標右鍵點擊
je_auto_control.click_mouse("mouse_right", x=800, y=400)

# 向下滾動
je_auto_control.mouse_scroll(scroll_value=5)

鍵盤控制

import je_auto_control

# 按下並釋放單一按鍵
je_auto_control.type_keyboard("a")

# 逐字輸入整個字串
je_auto_control.write("Hello World")

# 組合鍵(例如 Ctrl+C)
je_auto_control.hotkey(["ctrl_l", "c"])

# 檢查某個按鍵是否正在被按下
is_pressed = je_auto_control.check_key_is_press("shift_l")

圖像辨識

import je_auto_control

# 在螢幕上找出所有符合的圖像
positions = je_auto_control.locate_all_image("button.png", detect_threshold=0.9)
# 回傳: [[x1, y1, x2, y2], ...]

# 找出單一圖像並取得其中心座標
cx, cy = je_auto_control.locate_image_center("icon.png", detect_threshold=0.85)
print(f"找到位置: ({cx}, {cy})")

# 找出圖像並自動點擊
je_auto_control.locate_and_click("submit_button.png", mouse_keycode="mouse_left")

Accessibility 元件搜尋

透過作業系統無障礙樹依名稱/角色/App 搜尋控制項(Windows UIA,via uiautomation;macOS AX)。

import je_auto_control

# 列出 Calculator 中所有可見按鈕
elements = je_auto_control.list_accessibility_elements(app_name="Calculator")

# 搜尋特定元件
ok = je_auto_control.find_accessibility_element(name="OK", role="Button")
if ok is not None:
    print(ok.bounds, ok.center)

# 一步定位並點擊
je_auto_control.click_accessibility_element(name="OK", app_name="Calculator")

若當前平台無可用後端,會拋出 AccessibilityNotAvailableError

AI 元件定位(VLM)

當模板匹配與 Accessibility 都失效時,可用自然語言描述元件,交給視覺 語言模型取得座標。

import je_auto_control

# 預設偏好 Anthropic(若有設定 ANTHROPIC_API_KEY),否則用 OpenAI
x, y = je_auto_control.locate_by_description("綠色的 Submit 按鈕")

# 一次定位並點擊
je_auto_control.click_by_description(
    "Cookie 橫幅中的『全部接受』按鈕",
    screen_region=[0, 800, 1920, 1080],   # 可選:只在此區域找
)

設定(僅從環境變數讀取 — 金鑰不會被寫入程式碼或日誌):

變數 作用
ANTHROPIC_API_KEY 啟用 Anthropic 後端
OPENAI_API_KEY 啟用 OpenAI 後端
AUTOCONTROL_VLM_BACKEND 強制指定 anthropicopenai
AUTOCONTROL_VLM_MODEL 覆寫預設模型(如 claude-opus-4-7gpt-4o-mini

若兩個 SDK 皆未安裝或未設定 API key,會拋出 VLMNotAvailableError

OCR 螢幕文字辨識

import je_auto_control as ac

# 找出所有吻合的文字位置
matches = ac.find_text_matches("Submit")

# 取得第一個吻合位置的中心座標(找不到則回傳 None)
cx, cy = ac.locate_text_center("Submit")

# 一步定位並點擊
ac.click_text("Submit")

# 等待文字出現(或 timeout)
ac.wait_for_text("載入完成", timeout=15.0)

若 Tesseract 不在 PATH 中,可手動指定路徑:

ac.set_tesseract_cmd(r"C:\Program Files\Tesseract-OCR\tesseract.exe")

剪貼簿

import je_auto_control as ac
ac.set_clipboard("hello")
text = ac.get_clipboard()

後端:Windows(Win32 + ctypes)、macOS(pbcopy/pbpaste)、Linux (xclipxsel)。

截圖

import je_auto_control

# 擷取全螢幕截圖並儲存
je_auto_control.pil_screenshot("screenshot.png")

# 擷取指定區域的截圖 [x1, y1, x2, y2]
je_auto_control.pil_screenshot("region.png", screen_region=[100, 100, 500, 400])

# 取得螢幕解析度
width, height = je_auto_control.screen_size()

# 取得指定座標的像素顏色
color = je_auto_control.get_pixel(500, 300)

動作錄製與回放

import je_auto_control
import time

# 開始錄製滑鼠和鍵盤事件
je_auto_control.record()

time.sleep(10)  # 錄製 10 秒

# 停止錄製並取得動作列表
actions = je_auto_control.stop_record()

# 重新播放錄製的動作
je_auto_control.execute_action(actions)

JSON 腳本執行器

建立 JSON 動作檔案(actions.json):

[
    ["AC_set_mouse_position", {"x": 500, "y": 300}],
    ["AC_click_mouse", {"mouse_keycode": "mouse_left"}],
    ["AC_write", {"write_string": "Hello from AutoControl"}],
    ["AC_screenshot", {"file_path": "result.png"}],
    ["AC_hotkey", {"key_code_list": ["ctrl_l", "s"]}]
]

執行方式:

import je_auto_control

# 從檔案執行
je_auto_control.execute_action(je_auto_control.read_action_json("actions.json"))

# 或直接從列表執行
je_auto_control.execute_action([
    ["AC_set_mouse_position", {"x": 100, "y": 200}],
    ["AC_click_mouse", {"mouse_keycode": "mouse_left"}]
])

可用的動作命令:

類別 命令
滑鼠 AC_click_mouse, AC_set_mouse_position, AC_get_mouse_position, AC_press_mouse, AC_release_mouse, AC_mouse_scroll, AC_mouse_left, AC_mouse_right, AC_mouse_middle
鍵盤 AC_type_keyboard, AC_press_keyboard_key, AC_release_keyboard_key, AC_write, AC_hotkey, AC_check_key_is_press
圖像 AC_locate_all_image, AC_locate_image_center, AC_locate_and_click
螢幕 AC_screen_size, AC_screenshot
Accessibility AC_a11y_list, AC_a11y_find, AC_a11y_click
VLM(AI 定位) AC_vlm_locate, AC_vlm_click
OCR AC_locate_text, AC_click_text, AC_wait_text
剪貼簿 AC_clipboard_get, AC_clipboard_set
錄製 AC_record, AC_stop_record
報告 AC_generate_html, AC_generate_json, AC_generate_xml, AC_generate_html_report, AC_generate_json_report, AC_generate_xml_report
專案 AC_create_project
Shell AC_shell_command
程序 AC_execute_process
執行器 AC_execute_action, AC_execute_files

排程器(Interval & Cron)

import je_auto_control as ac

# Interval:每 30 秒執行一次
job = ac.default_scheduler.add_job(
    script_path="scripts/poll.json", interval_seconds=30, repeat=True,
)

# Cron:週一到週五 09:00(欄位為 minute hour dom month dow)
cron_job = ac.default_scheduler.add_cron_job(
    script_path="scripts/daily.json", cron_expression="0 9 * * 1-5",
)

ac.default_scheduler.start()

兩種排程可同時存在,可由 job.is_cron 判斷類型。

全域熱鍵

將 OS 熱鍵綁定到 action JSON 腳本(Windows 後端;macOS / Linux 的 start() 目前會拋出 NotImplementedError,介面已依 Strategy pattern 預留)。

from je_auto_control import default_hotkey_daemon

default_hotkey_daemon.bind("ctrl+alt+1", "scripts/greet.json")
default_hotkey_daemon.start()

事件觸發器

輪詢式觸發器,偵測到條件成立時自動執行腳本:

from je_auto_control import (
    default_trigger_engine, ImageAppearsTrigger,
    WindowAppearsTrigger, PixelColorTrigger, FilePathTrigger,
)

default_trigger_engine.add(ImageAppearsTrigger(
    trigger_id="", script_path="scripts/click_ok.json",
    image_path="templates/ok_button.png", threshold=0.85, repeat=True,
))
default_trigger_engine.start()

執行歷史

排程器、觸發器、熱鍵、REST API 與 GUI 手動回放的每一次執行都會被寫入 ~/.je_auto_control/history.db。錯誤時會自動在 ~/.je_auto_control/artifacts/run_{id}_{ms}.png 附上截圖以便除錯。

from je_auto_control import default_history_store

for run in default_history_store.list_runs(limit=20):
    print(run.id, run.source, run.status, run.artifact_path)

GUI 執行歷史 分頁提供篩選 / 更新 / 清除功能,並可雙擊截圖欄位開啟 附件。

報告產生

import je_auto_control

# 先啟用測試紀錄
je_auto_control.test_record_instance.set_record_enable(True)

# ... 執行自動化動作 ...
je_auto_control.set_mouse_position(100, 200)
je_auto_control.click_mouse("mouse_left")

# 產生報告
je_auto_control.generate_html_report("test_report")   # -> test_report.html
je_auto_control.generate_json_report("test_report")   # -> test_report.json
je_auto_control.generate_xml_report("test_report")    # -> test_report.xml

# 或取得報告內容為字串
html_string = je_auto_control.generate_html()
json_string = je_auto_control.generate_json()
xml_string = je_auto_control.generate_xml()

報告內容包含:每個紀錄動作的函式名稱、參數、時間戳記及例外資訊(如有)。HTML 報告中成功的動作以青色顯示,失敗的動作以紅色顯示。

遠端自動化(Socket / REST)

提供兩種伺服器:原始 TCP socket 與純 stdlib HTTP/REST。預設均綁定 127.0.0.1,綁定到 0.0.0.0 須明確指定。

import je_auto_control as ac

# TCP Socket 伺服器(預設:127.0.0.1:9938)
ac.start_autocontrol_socket_server(host="127.0.0.1", port=9938)

# REST API 伺服器(預設:127.0.0.1:9939)
ac.start_rest_api_server(host="127.0.0.1", port=9939)
# 端點:
#   GET  /health           存活檢查
#   GET  /jobs             列出排程工作
#   POST /execute          body: {"actions": [...]}

外掛載入器

將定義頂層 AC_* 可呼叫物的 .py 檔放進一個目錄,執行時即可註冊成 executor 指令:

from je_auto_control import (
    load_plugin_directory, register_plugin_commands,
)

commands = load_plugin_directory("./my_plugins")
register_plugin_commands(commands)

# 之後任何 JSON 腳本都能使用:
# [["AC_greet", {"name": "world"}]]

警告: 外掛檔案會直接執行任意 Python,請僅載入自己信任的目錄。

Shell 命令執行

import je_auto_control

# 使用預設的 Shell 管理器
je_auto_control.default_shell_manager.exec_shell("echo Hello")
je_auto_control.default_shell_manager.pull_text()  # 輸出擷取的結果

# 或建立自訂的 ShellManager
shell = je_auto_control.ShellManager(shell_encoding="utf-8")
shell.exec_shell("ls -la")
shell.pull_text()
shell.exit_program()

螢幕錄製

import je_auto_control
import time

# 方法一:ScreenRecorder(管理多個錄影)
recorder = je_auto_control.ScreenRecorder()
recorder.start_new_record(
    recorder_name="my_recording",
    path_and_filename="output.avi",
    codec="XVID",
    frame_per_sec=30,
    resolution=(1920, 1080)
)
time.sleep(10)
recorder.stop_record("my_recording")

# 方法二:RecordingThread(簡易單一錄影,輸出 MP4)
recording = je_auto_control.RecordingThread(video_name="my_video", fps=20)
recording.start()
time.sleep(10)
recording.stop()

回呼執行器

執行自動化函式後自動觸發回呼函式:

import je_auto_control

def my_callback():
    print("動作完成!")

# 執行 set_mouse_position 後呼叫 my_callback
je_auto_control.callback_executor.callback_function(
    trigger_function_name="AC_set_mouse_position",
    callback_function=my_callback,
    x=500, y=300
)

# 帶有參數的回呼
def on_done(message):
    print(f"完成: {message}")

je_auto_control.callback_executor.callback_function(
    trigger_function_name="AC_click_mouse",
    callback_function=on_done,
    callback_function_param={"message": "點擊完成"},
    callback_param_method="kwargs",
    mouse_keycode="mouse_left"
)

套件管理器

在執行時動態載入外部 Python 套件到執行器中:

import je_auto_control

# 將套件的所有函式/類別加入執行器
je_auto_control.package_manager.add_package_to_executor("os")

# 現在可以在 JSON 動作腳本中使用 os 函式:
# ["os_getcwd", {}]
# ["os_listdir", {"path": "."}]

專案管理

快速建立包含範本檔案的專案目錄結構:

import je_auto_control

# 建立專案結構
je_auto_control.create_project_dir(project_path="./my_project", parent_name="AutoControl")

# 會建立以下結構:
# my_project/
# └── AutoControl/
#     ├── keyword/
#     │   ├── keyword1.json        # 範本動作檔案
#     │   ├── keyword2.json        # 範本動作檔案
#     │   └── bad_keyword_1.json   # 錯誤處理範本
#     └── executor/
#         ├── executor_one_file.py  # 執行單一檔案範例
#         ├── executor_folder.py    # 執行資料夾範例
#         └── executor_bad_file.py  # 錯誤處理範例

視窗管理

直接將事件送至指定視窗(僅限 Windows 和 Linux):

import je_auto_control

# 透過視窗標題送出鍵盤事件
je_auto_control.send_key_event_to_window("Notepad", keycode="a")

# 透過視窗 handle 送出滑鼠事件
je_auto_control.send_mouse_event_to_window(window_handle, mouse_keycode="mouse_left", x=100, y=50)

GUI 應用程式

啟動內建圖形介面(需安裝 [gui] 擴充):

import je_auto_control
je_auto_control.start_autocontrol_gui()

或透過命令列:

python -m je_auto_control

命令列介面

AutoControl 可直接從命令列使用:

# 執行單一動作檔案
python -m je_auto_control -e actions.json

# 執行目錄中所有動作檔案
python -m je_auto_control -d ./action_files/

# 直接執行 JSON 字串
python -m je_auto_control --execute_str '[["AC_screenshot", {"file_path": "test.png"}]]'

# 建立專案範本
python -m je_auto_control -c ./my_project

另外還有以 headless API 為基礎的子命令 CLI:

# 執行腳本(可帶變數或 dry-run)
python -m je_auto_control.cli run script.json
python -m je_auto_control.cli run script.json --var name=alice --dry-run

# 列出排程工作
python -m je_auto_control.cli list-jobs

# 啟動 Socket / REST 伺服器
python -m je_auto_control.cli start-server --port 9938
python -m je_auto_control.cli start-rest   --port 9939

--var name=value 會優先以 JSON 解析(count=10 會變成 int),失敗 則視為字串。


平台支援

平台 狀態 後端 備註
Windows 10 / 11 支援 Win32 API (ctypes) 完整功能支援
macOS 10.15+ 支援 pyobjc / Quartz 不支援動作錄製;不支援 send_key_event_to_window / send_mouse_event_to_window
Linux(X11) 支援 python-Xlib 完整功能支援
Linux(Wayland) 尚未支援 未來版本可能加入支援
Raspberry Pi 3B / 4B 支援 python-Xlib 在 X11 上運行

開發

環境設定

git clone https://github.com/Intergration-Automation-Testing/AutoControl.git
cd AutoControl
pip install -r dev_requirements.txt

執行測試

# 單元測試
python -m pytest test/unit_test/

# 整合測試
python -m pytest test/integrated_test/

專案連結


授權條款

MIT License © JE-Chen。 第三方相依套件之授權請見 Third_Party_License.md