Pythonの基礎 - マウス

提供: MochiuWiki : SUSE, EC, PCB

概要

Pythonでは、マウスの操作を自動化、または、マウスイベントを監視することができる。
これにより、GUIアプリケーションの自動テスト、定型作業の自動化、マクロの作成等が可能になる。

主なライブラリとして、以下に示す3つがある。

  • PyAutoGUI
    クロスプラットフォーム対応のGUIオートメーションライブラリ
    マウス・キーボード操作の自動化に最適
  • pynput
    マウス・キーボードの制御と監視が可能なライブラリ
    イベントリスナー機能が充実している。
  • mouse
    シンプルで軽量なマウス操作ライブラリ
    単純なマウス操作やイベントフックに適している。



PyAutoGUIによるマウス操作

PyAutoGUIは、マウスやキーボードを自動で制御するためのライブラリである。
Windows、MacOS、Linuxで動作するクロスプラットフォーム対応である。

インストール

PyAutoGUIは、pipを使用してインストールする。

pip install pyautogui


Linuxの場合、画像認識やスクリーンショット機能を使用するために追加のパッケージが必要である。

# RHEL
sudo dnf install scrot python3-tkinter python3-devel

# SUSE
sudo zypper install scrot python3-tk python3-devel


画面サイズの取得

size 関数を使用すると、画面の解像度を取得できる。

 import pyautogui
 
 width, height = pyautogui.size()
 print(f"画面サイズ: {width} x {height}")


# 出力例
画面サイズ: 1920 x 1080


マウス位置の取得

position 関数を使用すると、現在のマウスカーソルの位置を取得できる。
座標系は画面左上を原点 (0, 0) とし、右方向にX座標、下方向にY座標が増加する。

 import pyautogui
 
 x, y = pyautogui.position()
 print(f"マウス位置: ({x}, {y})")


# 出力例
マウス位置: (500, 300)


マウスの移動

moveTo 関数を使用すると、指定した座標にマウスカーソルを移動できる。
第3引数に秒数を指定すると、その時間をかけてスムーズに移動する。

 import pyautogui
 
 # 座標 (100, 200) に瞬時に移動
 pyautogui.moveTo(100, 200)
 
 # 座標 (500, 400) に2秒かけて移動
 pyautogui.moveTo(500, 400, duration=2)


move関数 (moveRel関数) を使用すると、現在位置からの相対移動ができる。

 import pyautogui
 
 # 現在位置から右に100ピクセル、下に50ピクセル移動
 pyautogui.move(100, 50)
 
 # 現在位置から左に200ピクセル移動 (1秒かけて)
 pyautogui.move(-200, 0, duration=1)


移動時にイージング効果を適用することもできる。

 import pyautogui
 
 # ゆっくり始まり速く終わる
 pyautogui.moveTo(100, 100, duration=2, tween=pyautogui.easeInQuad)
 
 # 速く始まりゆっくり終わる
 pyautogui.moveTo(500, 500, duration=2, tween=pyautogui.easeOutQuad)
 
 # バウンド効果
 pyautogui.moveTo(300, 300, duration=2, tween=pyautogui.easeInBounce)


クリック操作

click 関数を使用すると、マウスのクリック操作ができる。

 import pyautogui
 
 # 現在位置で左クリック
 pyautogui.click()
 
 # 指定座標で左クリック
 pyautogui.click(100, 200)
 
 # 右クリック
 pyautogui.click(button='right')
 
 # 中央ボタンクリック
 pyautogui.click(button='middle')
 
 # ダブルクリック
 pyautogui.click(clicks=2)
 
 # トリプルクリック
 pyautogui.click(clicks=3)
 
 # 0.5秒間隔で3回クリック
 pyautogui.click(clicks=3, interval=0.5)


専用の関数を使用することもできる。

 import pyautogui
 
 # 右クリック
 pyautogui.rightClick()
 
 # 中央ボタンクリック
 pyautogui.middleClick()
 
 # ダブルクリック
 pyautogui.doubleClick()
 
 # トリプルクリック
 pyautogui.tripleClick()


mouseDown 関数 と mouseUp 関数を使用すると、マウスボタンの押下と解放を個別に制御できる。

 import pyautogui
 
 # 左ボタンを押す
 pyautogui.mouseDown()
 
 # 左ボタンを離す
 pyautogui.mouseUp()
 
 # 右ボタンを押す
 pyautogui.mouseDown(button='right')
 
 # 指定座標で右ボタンを離す
 pyautogui.mouseUp(button='right', x=100, y=200)


ドラッグ操作

drag 関数を使用すると、ドラッグ操作ができる。

 import pyautogui
 
 # 現在位置から相対的にドラッグ
 pyautogui.drag(100, 50, duration=1)
 
 # 指定座標へドラッグ
 pyautogui.dragTo(500, 400, duration=1)
 
 # 右ボタンでドラッグ
 pyautogui.drag(100, 0, duration=1, button='right')


スクロール操作

scroll 関数を使用すると、マウスホイールのスクロール操作ができる。
正の値で上方向、負の値で下方向にスクロールする。

 import pyautogui
 
 # 上方向に10クリック分スクロール
 pyautogui.scroll(10)
 
 # 下方向に10クリック分スクロール
 pyautogui.scroll(-10)
 
 # 指定座標でスクロール
 pyautogui.scroll(5, x=100, y=200)


MacOSとLinuxでは、水平スクロールも可能である。

 import pyautogui
 
 # 右方向にスクロール
 pyautogui.hscroll(10)
 
 # 左方向にスクロール
 pyautogui.hscroll(-10)


フェイルセーフ機能

PyAutoGUIには、安全のためにフェイルセーフ機能がデフォルトで有効になっている。
マウスカーソルを画面の四隅のいずれかに移動すると、pyautogui.FailSafeException例外が発生してプログラムが停止する。

 import pyautogui
 
 # フェイルセーフを無効にする (非推奨)
 pyautogui.FAILSAFE = False
 
 # フェイルセーフを有効にする (デフォルト)
 pyautogui.FAILSAFE = True


また、各操作の間には0.1秒の遅延がデフォルトで設定されている。

 import pyautogui
 
 # 操作間の遅延を変更
 pyautogui.PAUSE = 0.5  # 0.5秒に設定


※注意
フェイルセーフを無効にすると、プログラムの暴走時に停止できなくなる可能性がある。
通常は有効のままにしておくことを推奨する。


pynputによるマウス操作

pynputは、マウスやキーボードの制御と監視が可能なライブラリである。
特にイベントリスナー機能が充実しており、マウスイベントの検知に適している。

インストール

pynputは、pipを使用してインストールする。

pip install pynput


Controllerによるマウス制御

Controllerクラスを使用すると、マウスカーソルの移動やクリック操作ができる。

 from pynput.mouse import Button, Controller
 
 mouse = Controller()
 
 # 現在位置の取得
 print(f"マウス位置: {mouse.position}")
 
 # 指定座標に移動
 mouse.position = (100, 200)
 
 # 相対移動
 mouse.move(50, -30)


クリック操作も可能である。

 from pynput.mouse import Button, Controller
 
 mouse = Controller()
 
 # 左クリック
 mouse.click(Button.left)
 
 # 右クリック
 mouse.click(Button.right)
 
 # ダブルクリック
 mouse.click(Button.left, 2)
 
 # ボタンを押す
 mouse.press(Button.left)
 
 # ボタンを離す
 mouse.release(Button.left)


スクロール操作も可能である。

 from pynput.mouse import Controller
 
 mouse = Controller()
 
 # 上方向にスクロール
 mouse.scroll(0, 2)
 
 # 下方向にスクロール
 mouse.scroll(0, -2)
 
 # 右方向にスクロール (水平スクロール)
 mouse.scroll(2, 0)


Listenerによるマウスイベント監視

Listener クラスを使用すると、マウスイベントを監視できる。

 from pynput import mouse
 
 def on_move(x, y):
    print(f"マウス移動: ({x}, {y})")
 
 def on_click(x, y, button, pressed):
    action = "押された" if pressed else "離された"
    print(f"{button} が ({x}, {y}) で{action}")
    if button == mouse.Button.right and pressed:
       # 右クリックでリスナーを停止
       return False
 
 def on_scroll(x, y, dx, dy):
    direction = "上" if dy > 0 else "下"
    print(f"スクロール {direction}: ({x}, {y})")
 
 # リスナーを開始
 with mouse.Listener(
    on_move=on_move,
    on_click=on_click,
    on_scroll=on_scroll
 ) as listener:
    listener.join()


# 実行例 :

マウス移動: (512, 384)
マウス移動: (520, 390)
Button.left が (520, 390) で押された
Button.left が (520, 390) で離された
スクロール 上: (520, 390)
Button.right が (525, 400) で押された


リスナーをスレッドとして起動することもできる。

 from pynput import mouse
 import time
 
 def on_click(x, y, button, pressed):
    if pressed:
       print(f"{button} クリック: ({x}, {y})")
 
 # リスナーを非ブロッキングで開始
 listener = mouse.Listener(on_click=on_click)
 listener.start()
 
 # 他の処理を実行
 print("5秒間マウスイベントを監視します...")
 time.sleep(5)
 
 # リスナーを停止
 listener.stop()
 print("監視終了")


同期的なイベント読み取り

Events クラスを使用すると、同期的にマウスイベントを読み取ることができる。

 from pynput import mouse
 
 # イベントを1つずつ読み取る
 with mouse.Events() as events:
    for event in events:
       print(event)
       if isinstance(event, mouse.Events.Click):
          if event.button == mouse.Button.right:
             break



mouseライブラリによるマウス操作

mouseライブラリは、シンプルで軽量なマウス操作ライブラリである。
グローバルなマウスイベントのフックやシミュレーションが可能である。

インストール

mouseライブラリは、pipを使用してインストールする。

pip install mouse


マウス位置の取得

get_position 関数を使用すると、現在のマウス位置を取得できる。

 import mouse

 x, y = mouse.get_position()
 print(f"マウス位置: ({x}, {y})")


マウスの移動

move 関数を使用すると、マウスカーソルを移動できる。

 import mouse
 
 # 指定座標に移動
 mouse.move(100, 200)
 
 # 相対移動
 mouse.move(50, 30, absolute=False)
 
 # 時間をかけて移動
 mouse.move(500, 400, duration=1)


クリック操作

click 関数を使用すると、クリック操作ができる。

 import mouse
 
 # 左クリック
 mouse.click()
 
 # 右クリック
 mouse.click(button='right')
 
 # 中央ボタンクリック
 mouse.click(button='middle')
 
 # ダブルクリック
 mouse.double_click()


ドラッグ操作

drag 関数を使用すると、ドラッグ操作ができる。

 import mouse
 
 # 始点から終点へドラッグ
 mouse.drag(100, 100, 300, 300, duration=1)


スクロール操作

wheel 関数を使用すると、スクロール操作ができる。

 import mouse
 
 # 上方向にスクロール
 mouse.wheel(1)
 
 # 下方向にスクロール
 mouse.wheel(-1)


イベントフック

hook 関数 や on_click 関数を使用すると、マウスイベントを監視できる。

 import mouse
 
 # 左クリック時のコールバック
 mouse.on_click(lambda: print("左クリックされました"))
 
 # 右クリック時のコールバック
 mouse.on_right_click(lambda: print("右クリックされました"))
 
 # 中央ボタンクリック時のコールバック
 mouse.on_middle_click(lambda: print("中央ボタンがクリックされました"))
 
 # プログラムを待機
 mouse.wait()


全てのマウスイベントを監視する場合は、hook関数を使用する。

 import mouse
 
 def callback(event):
    print(event)
 
 # 全てのマウスイベントをフック
 mouse.hook(callback)
 
 # 右クリックまで待機
 mouse.wait(button='right')
 
 # フックを解除
 mouse.unhook_all()


ボタンの状態確認

is_pressed 関数を使用すると、ボタンが押されているかどうかを確認できる。

 import mouse
 
 if mouse.is_pressed(button='left'):
    print("左ボタンが押されています")
 
 if mouse.is_pressed(button='right'):
    print("右ボタンが押されています")



ライブラリの比較と使い分け

各ライブラリには特徴があり、用途に応じて使い分けることが重要である。

マウス操作ライブラリの比較
機能 PyAutoGUI pynput mouse
マウス移動
クリック操作
ドラッグ操作
スクロール操作
イベント監視 ×
画像認識 × ×
キーボード操作 × (別ライブラリ)
クロスプラットフォーム


用途別の推奨ライブラリを以下に示す。

  • GUIオートメーション (自動化スクリプト)
    PyAutoGUI
    画像認識機能があり、マウスとキーボードの両方を扱える。
  • イベント監視・マクロ作成
    pynput
    リスナー機能が充実しており、低レベルなイベント制御が可能
  • シンプルなマウス操作
    mouse
    軽量で使いやすく、単純なマウス操作やフックに適している。



実践例

画面上の特定位置を自動クリック

以下の例では、5秒後に現在のマウス位置をクリックする。

 import pyautogui
 import time
 
 print("5秒後に現在のマウス位置をクリックします...")
 print("クリックしたい位置にマウスを移動してください")
 
 time.sleep(5)
 x, y = pyautogui.position()
 print(f"位置 ({x}, {y}) をクリックします")
 pyautogui.click()


マウス位置の連続記録

以下の例では、マウスの位置を1秒間隔で記録する。

 import pyautogui
 import time
 
 positions = []
 
 print("10秒間マウス位置を記録します...")
 for i in range(10):
    x, y = pyautogui.position()
    positions.append((x, y))
    print(f"{i + 1}秒目: ({x}, {y})")
    time.sleep(1)
 
 print(f"記録された位置: {positions}")


クリック位置の取得

以下の例では、ユーザがクリックした位置を取得する。

 from pynput import mouse
 
 positions = []
 
 def on_click(x, y, button, pressed):
    if pressed and button == mouse.Button.left:
       positions.append((x, y))
       print(f"クリック位置 {len(positions)}: ({x}, {y})")
       if len(positions) >= 5:
          return False
 
 print("5箇所をクリックしてください...")
 
 with mouse.Listener(on_click=on_click) as listener:
    listener.join()
 
 print(f"記録された位置: {positions}")


自動スクロール

以下の例では、Webページを自動的に下方向にスクロールする。

 import pyautogui
 import time
 
 print("3秒後に自動スクロールを開始します...")
 time.sleep(3)
 
 for i in range(10):
    pyautogui.scroll(-3)  # 下方向にスクロール
    print(f"スクロール {i + 1}/10")
    time.sleep(0.5)
 
 print("スクロール完了")



トラブルシューティング

Linuxでの権限エラー

Linuxでマウス操作ライブラリを使用する際に権限エラーが発生する場合がある。

pynputの場合、X11セッションで実行する必要がある。

# 環境変数の設定
export DISPLAY=:0


mouseライブラリの場合、root権限が必要な場合がある。

sudo python3 script.py


Windows DPIスケーリングの問題

Windowsで高DPI設定を使用している場合、座標がずれることがある。
アプリケーションにDPI対応を宣言することで解決できる場合がある。

 import ctypes
 
 # DPI対応を宣言
 try:
    ctypes.windll.shcore.SetProcessDpiAwareness(2)
 except:
    pass


MacOSでのアクセシビリティ権限

MacOSでは、システム環境設定からアクセシビリティ権限を付与する必要がある。

[システム環境設定] - [セキュリティとプライバシー] - [プライバシー] - [アクセシビリティ] で、実行するアプリケーション (ターミナルやPython) にチェックを入力する。