PyAutoGUIは、Pythonからマウスとキーボードを操作して画面上の手作業を自動化するライブラリです。pip install pyautoguiで入り、Windows・macOS・Linuxで動きます。作者はAl Sweigart氏で、ライセンスはBSDです。
現行版は2023年5月24日公開の0.9.54です。PyPIにはその後の版が無く、GitHubのリポジトリも2023年6月7日のコミットが最後です。一方で、依存ライブラリのPyScreezeとPillowは更新が続いています。この記事では、OS別のインストール手順と主要関数の使い方に加えて、止まったままの0.9.54を今のPythonで使うと詰まる点(Pillowが入らない・画像が見つからないと例外になる・日本語やJIS配列の記号が正しく入力されない)を、2026年10月28日にPython 3.11〜3.14で実行した結果と0.9.54のソースコードで確かめた内容に沿って説明します。
まとめ:PyAutoGUIでできることと導入の要点
- できること:マウスの移動・クリック・ドラッグ・スクロール、キー入力とショートカット、スクリーンショット、画面上の画像検索と色の判定、確認ダイアログの表示。
- 導入:
pip install pyautogui。Python 3.12以降ではPillowが自動で入らないので、スクリーンショットと画像検索を使うならpip install pillowを足します(3.14でも同じ)。 - 画像が見つからないと例外になる:今入るPyScreeze 1.0.1との組み合わせでは、
locateOnScreen()はNoneを返さずpyautogui.ImageNotFoundExceptionを送出します。if pos is Noneで書いた古いコードは動きません。 - 日本語と一部の記号は
write()で打てない:日本語は黙って無視され、JIS配列のWindowsでは@・^・:が別の文字になります。pyperclipでクリップボードに入れてhotkey('ctrl', 'v')で貼り付けます。 - 止め方を先に覚える:マウスを画面の四隅へ動かすと
FailSafeExceptionで停止します。クリックやキー入力の関数の後には、既定で0.1秒の待ち(PAUSE)が入ります。 - 向かない場面:ブラウザ操作はSeleniumやPlaywright、Windowsアプリのボタン操作はpywinautoなどUI Automation系のほうが、座標のずれに強く壊れにくくなります。
PyAutoGUIでできること・できないこと
PyAutoGUIは、OSに「マウスがここへ動いた」「このキーが押された」という入力イベントを送るだけのライブラリです。アプリの内部構造(ボタンの名前やHTMLの要素)は見ていません。そのため、どのアプリでも座標さえ分かれば操作できる反面、ウィンドウの位置や解像度が変わると同じスクリプトが別の場所をクリックします。
| やりたいこと | 主な関数 | 補足 |
|---|---|---|
| マウス移動 | moveTo()・move() |
絶対座標・相対移動 |
| クリック | click()・doubleClick()・rightClick() |
回数・ボタン指定可 |
| ドラッグ | dragTo()・drag() |
押したまま移動 |
| スクロール | scroll()・hscroll() |
横はmacOS・Linux |
| キー入力 | press()・write() |
英数字・記号のみ |
| 同時押し | hotkey()・hold() |
ショートカット再現 |
| 座標の取得 | position()・size() |
主モニタ基準 |
| 画面キャプチャ | screenshot() |
要Pillow |
| 画像検索 | locateOnScreen() |
要Pillow |
| 色の判定 | pixel()・pixelMatchesColor() |
要Pillow |
| ダイアログ | alert()・confirm()・prompt() |
PyMsgBox経由 |
できないことも公式に明記されています。READMEには「PyAutoGUIは現在プライマリモニタでしか動かない」とあり、2台目のモニタでのマウス操作は「OSとバージョンによって動くこともあれば動かないこともある」という扱いです。モバイルOSは対象外で、最小化されたウィンドウや画面ロック中の操作もできません。
PyAutoGUIのインストール手順(Windows・macOS・Linux)
PyPIのpyautoguiを入れると、PyMsgBox・PyTweening・PyScreeze・PyGetWindow・MouseInfoが一緒に入ります。macOSではpyobjc-coreとpyobjc-framework-Quartz、Linuxではpython3-Xlibも自動で追加されます。2026年10月28日時点で一緒に入る版は、PyScreeze 1.0.1・PyMsgBox 2.0.1・PyTweening 1.2.0・MouseInfo 0.1.3です。
python -m pip install pyautogui pillow pyperclip
python -c "import pyautogui; print(pyautogui.__version__)"
2行目で0.9.54と表示されれば導入は完了です。以下、OSごとの差分です。
Windowsでのインストールと表示スケールの扱い
Windowsは追加パッケージなしで動きます。複数のPythonを入れている場合は、py -3.13 -m pip install pyautoguiのようにPythonランチャーで入れ先を指定すると、「インストールしたのにModuleNotFoundError」を避けられます。
表示スケールを125%や150%にしている環境でも、座標は実際のピクセル単位で扱われます。0.9.54のWindows実装は読み込み時にSetProcessDPIAware()を呼んでいます。ソースのコメントによれば、スケーリングで画面の解像度を誤って報告する問題への対処です。
macOSでのインストールとアクセシビリティ権限
macOSではpython3 -m pip install pyautoguiで入ります。インストール自体は通っても、最初の実行でマウスやキーが動かないことがあります。原因はOSの権限で、スクリプトを起動するアプリ(ターミナル・iTerm2・VS Codeなど)に「システム設定 → プライバシーとセキュリティ → アクセシビリティ」の許可が要ります。スクリーンショットと画像検索には、同じ画面の「画面収録とシステムオーディオ録音」の許可も必要です。
macOSのスクリーンショットは、PyScreezeが呼ぶPillowのImageGrab.grab()が内部でscreencaptureコマンドを実行して取得します。画面を取得できない状態で実行すると、subprocess.CalledProcessError(screencapture -xが終了コード1)で止まります。今回の検証環境(macOSのバックグラウンド実行)でも、Python 3.11とPillow 13.0.0の組み合わせでこのエラーになりました。ショートカットはctrlではなくcommandで指定します。
LinuxでのインストールとX11の前提
Linuxの実装はXlibでX Window Systemへ入力を送ります。0.9.54のソースは読み込み時に環境変数DISPLAYの画面へ接続するため、DISPLAYが無いSSHセッションやcronからimport pyautoguiすると、その時点でKeyErrorになります。操作対象のX11デスクトップにログインした同じユーザーで実行してください。SSHやcronから接続する場合は、対象セッションのDISPLAYの値とXサーバーへの認証情報が必要で、DISPLAY=:0の指定だけでは接続できるとは限りません。
公式のインストール手順は、Debian・Ubuntu系で次のパッケージの追加を求めています。python3-tkはMouseInfoの座標表示ウィンドウとダイアログ、scrotはスクリーンショットに使われます。Ubuntu 23.04以降はシステムのPythonへ直接pip installするとexternally-managed-environmentのエラーで止まるため、仮想環境を作ってから入れます。
sudo apt-get install scrot python3-tk python3-dev python3-venv
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install pyautogui pillow
Ubuntuの既定セッションはWaylandです。PyScreezeはXDG_SESSION_TYPEかWAYLAND_DISPLAYでWaylandを検知するとスクリーンショットをgnome-screenshot経由に切り替えますが、マウスとキーの入力はXlib経由のままです。「Ubuntu on Xorg」が用意されている環境では、ログイン時に選択してX11セッションで実行します。Ubuntu 25.10のリリースノートは「Ubuntu on X.org」セッションの提供終了を明記しており、25.10以降の標準デスクトップではこの切り替えができません。自分のセッションがどちらかはecho $XDG_SESSION_TYPEで分かります。両者の違いはWaylandとX11の違いとは|構造・セキュリティ・確認方法と2026年の移行状況を解説にまとめています。
Python 3.12以降でのPillowの追加インストール
PyScreeze 1.0.1は、Pillowの依存をpython_version == "3.11"までしか書いていません(PyPIのpyscreezeのメタデータのRequires-Distも同じ)。Python 3.12以降でpip install pyautoguiしてもPillowは入りません。
2026年10月28日に、macOS上のPython 3.11・3.12・3.13・3.14の新規仮想環境へpyautoguiを入れて確かめた結果は次のとおりです。
| Python | 一緒に入ったPillow | screenshot()の結果 |
|---|---|---|
| 3.11 | 13.0.0 | 画面取得へ進む |
| 3.12 | 入らない | PyAutoGUIException |
| 3.13 | 入らない | PyAutoGUIException |
| 3.14 | 入らない | PyAutoGUIException |
3.11で入ったのは、2026年10月16日に公開されたPillow 13.0.0です。13.0.0はPython 3.11以上が条件なので、3.10ではpipが12系を選びます。
Pillowが無くてもimport pyautoguiは通り、マウスとキーボードの関数は使えます。スクリーンショット・画像検索・pixel()を呼んだ瞬間に初めて、次の例外が出ます(3.14で同じ文面を確認)。
pyautogui.PyAutoGUIException: PyAutoGUI was unable to import pyscreeze. (This is likely because you're running a version of Python that Pillow (which pyscreeze depends on) doesn't support currently.) Please install this module to enable the function you tried to call.
今回の新規仮想環境では、原因はPillowの未導入でした。ただし、このメッセージはPyScreezeの読み込みでImportErrorが起きた場合にも表示されるため、原因が常にPillowの未導入とは限りません。Pillowが入っていないだけならpip install pillowで解消します。
PyAutoGUIのマウス操作:座標の調べ方と移動・クリック
座標は画面左上が(0, 0)で、右へ行くほどx、下へ行くほどyが増えます。基準はプライマリモニタで、pyautogui.size()がその幅と高さを返します。
position()による現在のマウス座標の取得
クリック位置を決めるには、まず目的の場所の座標を知る必要があります。次のスクリプトを動かしたままマウスを目的の位置へ動かすと、座標が1行に上書き表示されます。Ctrl+Cで終了します。
import pyautogui
print('画面サイズ:', pyautogui.size())
try:
while True:
x, y = pyautogui.position()
print(f'X={x:5d} Y={y:5d}', end='\r', flush=True)
pyautogui.sleep(0.05)
except KeyboardInterrupt:
print()
PyAutoGUIに同梱のMouseInfoを使う方法もあります。pyautogui.mouseInfo()を呼ぶと、座標を表示するウィンドウが開き、値をクリップボードへコピーできます。MouseInfo 0.1.3では、Pillowが利用できるWindows・Linuxの主モニタ上ではRGB値も表示しますが、macOSのRGB欄はNA_on_macOSとなります。Linuxではpython3-tkが必要です。
moveTo()とclick()による移動・クリック
import pyautogui
pyautogui.moveTo(500, 300, duration=0.5) # 0.5秒かけて(500, 300)へ移動
pyautogui.move(0, 100) # 今の位置から下へ100px
pyautogui.click() # 今の位置を左クリック
pyautogui.click(800, 400, clicks=2, interval=0.2) # 指定座標をダブルクリック
pyautogui.rightClick(800, 400) # 右クリック
durationを省略すると瞬時に移動します。0.9.54ではMINIMUM_DURATIONが0.1秒に設定されていて、0.1秒以下を指定した場合も瞬時移動になります。ホバーでメニューが開くアプリのように、動きを見て反応する画面ではdurationを0.3〜0.5秒ほど取ると取りこぼしが減ります。
dragTo()とscroll()によるドラッグ・スクロール
pyautogui.dragTo(900, 500, duration=1, button='left') # 押したまま(900, 500)へ
pyautogui.scroll(-5) # 下へ5ノッチ
pyautogui.scroll(5, x=600, y=400) # (600, 400)へ移動してから上へ5ノッチ
pyautogui.hscroll(3) # 右へ(macOS・Linuxのみ)
scroll()の引数は画素数ではなく「ホイールの刻み数」です。1刻みで動く量はOSとアプリの設定で変わるため、スクロール後の位置に依存する処理は、画像検索で目印を探し直すほうが安定します。
PyAutoGUIのキーボード操作:press・write・hotkeyの使い分け
キー名はpyautogui.KEYBOARD_KEYSに定義されていて、0.9.54では194個です。pyautogui.isValidKey('enter')で、名前が有効かどうかを確かめられます。
press()とwrite()による単独キー・文字列の入力
pyautogui.press('enter') # 1回押す
pyautogui.press('tab', presses=3, interval=0.1) # 3回押す
pyautogui.press(['left', 'left', 'backspace']) # 順に押す
pyautogui.write('Hello, PyAutoGUI', interval=0.05) # 1文字ずつ入力
write()とtypewrite()は同じ関数です。ソースにはwrite = typewriteとあり、コメントで「1.0でwrite()がtypewrite()を置き換える」と予告されています。新しく書くコードは、短い別名のwrite()に統一できます。
hotkey()とhold()による同時押し・連続操作
hotkey()は、渡したキーを順に押し下げ、逆順に離します。hotkey('ctrl', 'shift', 'esc')ならCtrl→Shift→Escの順に押し、Esc→Shift→Ctrlの順に離します。修飾キーを押したまま複数の操作を続けたいときは、コンテキストマネージャのhold()を使います。
pyautogui.hotkey('ctrl', 'c') # コピー(macOSは 'command', 'c')
pyautogui.hotkey('alt', 'tab') # ウィンドウ切り替え
with pyautogui.hold('shift'): # Shiftを押したまま
pyautogui.press(['right'] * 5) # 右へ5文字選択
pyautogui.keyDown('ctrl') # 押し下げと解放を個別に書く方法
pyautogui.click(300, 200)
pyautogui.keyUp('ctrl')
keyDown()を使う場合は、途中で例外が起きるとkeyUp()に届かず、キーが押しっぱなしになります。hold()はwithブロックを例外で抜けた場合もキーを解放するので、こちらを優先してください。ただし、0.9.54では解放前にもフェイルセーフを確認するため、画面の四隅で停止した場合にはキーが解放されないことがあります。
JIS配列のWindowsで@・^・:が別の文字になる原因
日本語キーボード(JIS配列)のWindowsでwrite('[email protected]')を実行すると、@が別の文字に置き換わります。原因は0.9.54のWindows実装にあります。
_pyautogui_win.pyは、読み込み時にVkKeyScanA()で、その時点のキーボード配列での仮想キーコードとShiftの要否を文字ごとに引いています。ここまでは配列に追従します。ところが押す直前に、isShiftCharacter()が判定する記号~!@#$%^&*()_+{}|:"<>?にはShiftを足します。これはUS配列でShiftが要る記号の一覧で、__init__.pyの同関数には「QWERTY以外の配列では違う」というTODOコメントが付いたままです。同じ問題は2019年にフランス語配列の利用者がGitHub Issue #330で「正しいキーコードに誤った修飾キーを付けて送る」と報告していて、2026年10月28日時点で未解決(open)です。
JIS配列で@・^・:はShiftなしで打つキーなので、Shiftを付けて送られると、同じキーのShift側の文字(`・~・*)になります。ソースの処理をJIS配列に当てはめた結果で、ほかの記号はこのずれが起きません。メールアドレスやURLのように記号を含む文字列は、次の日本語と同じくクリップボード経由で入れるのが確実です。
pyperclipによる日本語の貼り付け
write('こんにちは')は何も入力しません。エラーも出ません。0.9.54のWindows・macOS・Linuxの各実装は、キー名の対応表に無い文字を受け取ると何もせずに戻るからです(pyautogui.isValidKey('あ')はFalseを返します)。日本語はクリップボード経由で入れます。Linuxでコピー機能が見つからないというエラーが出る場合は、X11環境ならxclipまたはxselなどのクリップボード用コマンドも導入してください。
import pyautogui
import pyperclip
pyperclip.copy('2026年10月分の売上データ [email protected]')
pyautogui.hotkey('ctrl', 'v') # macOSは hotkey('command', 'v')
pyperclipはMouseInfoの依存として自動で入りますが(2026年10月28日時点で1.11.0)、自分のコードで使うならpip install pyperclipで明示しておきます。IMEがオンのまま英字をwrite()すると変換候補として入力されるため、英字を打つ前にIMEをオフにする手順も入れてください。
PyAutoGUIの画像認識:スクリーンショットとlocateOnScreen
座標の固定値に頼らず、「このボタンの画像が画面のどこにあるか」を探してクリックできます。スクリーンショットと画像検索はPyScreezeの機能で、PyAutoGUIからそのまま呼べます。
im = pyautogui.screenshot() # 画面全体(PIL.Image)
pyautogui.screenshot(region=(0, 0, 400, 300)).save('area.png') # 左上400x300を保存
box = pyautogui.locateOnScreen('ok_button.png') # Box(left, top, width, height)
x, y = pyautogui.locateCenterOnScreen('ok_button.png')
pyautogui.click(x, y)
ファイルへの保存は、戻り値の画像に.save()を呼んで行います。PyScreeze 1.0.1のソースでは、macOSでscreenshot('area.png')のようにファイル名を渡しても保存処理に使われず、LinuxではPillow 9.2.0以上かつgnome-screenshotが存在する分岐で、regionと一緒にファイル名を渡すと切り出す前の全画面が保存されます。scrotなどを直接呼ぶ分岐では、切り出した画像が保存されます。
探す画像(ok_button.png)は、実行する画面と同じ解像度・同じ表示倍率で切り出しておきます。倍率が違う画面で切り出した画像は、見た目が同じでもピクセルが一致しません。macOSのRetinaディスプレイでは、pyautogui.size()の値とscreenshot().sizeの値が一致するか先に確かめてください。一致しない場合は、見つかった座標をその倍率で割ってからクリックします。
PyScreeze 0.1.30以降の画像未検出時の例外
古い解説には「見つからなければNoneが返る」と書かれていますが、今の組み合わせでは違います。挙動を決めているのはPyAutoGUIではなくPyScreezeのUSE_IMAGE_NOT_FOUND_EXCEPTIONで、PyAutoGUI 0.9.54はPyScreezeの例外をpyautogui.ImageNotFoundExceptionに包み直して送出します。PyAutoGUIを0.9.54に固定したままPyScreezeだけ入れ替えて、画面にない画像をlocate()させたところ、0.1.28と0.1.29はNoneを返し、0.1.30と1.0.1は例外を送出しました。PyScreezeのリポジトリのCHANGELOG.mdにも、この既定値の変更は「後方互換性を壊す変更」と書かれています。
公式ドキュメントのスクリーンショットのページには「0.9.41から例外を送出する」とあります。ただ、実際に既定で例外になるのは、PyScreeze 0.1.30(2023年11月10日公開)以降と組み合わせたときです。今pip install pyautoguiすればPyScreeze 1.0.1が入るので、新しく作る環境では例外になると考えてください。
try:
x, y = pyautogui.locateCenterOnScreen('ok_button.png')
except pyautogui.ImageNotFoundException:
print('OKボタンが見つかりません')
else:
pyautogui.click(x, y)
既存のスクリプトを直す時間がないなら、先頭でpyautogui.useImageNotFoundException(False)を呼ぶと、以前と同じくNoneを返す動作に戻せます(これも実行して確認しました)。ただしNoneをx, y =で受けると別のTypeErrorになるだけなので、長く使うスクリプトは例外で書き直すほうが原因を追いやすくなります。
confidenceによる一致判定のしきい値調整とOpenCVの導入
アンチエイリアスや配色の微差で完全一致しないときは、confidence=0.9のように一致度の下限を指定します。この引数はOpenCVが入っているときだけ使えます。未導入で指定するとNotImplementedError: The confidence keyword argument is only available if OpenCV is installed.になります。
python -m pip install opencv-python
OpenCV版の検索はcv2.matchTemplateを使い、正規化相関の値がconfidenceを超えた位置を一致とみなします。値の意味と下げすぎたときの誤検出はテンプレートマッチングとは?matchTemplateの仕組みと類似度指標の選び方を解説で詳しく扱っています。PyScreeze 1.0.1は既定で白黒化して検索するため、grayscale=Trueを足しても動作は変わりません。色も比較するにはgrayscale=Falseを指定します。白黒化した場合、色だけが違うボタン(有効・無効の切り替えなど)は区別できなくなります。
pixel()とpixelMatchesColor()による色の判定
ボタンの有効・無効や処理中の表示のように、画像全体ではなく1点の色だけで状態が分かる場面では、画像検索よりpixelMatchesColor()のほうが軽く済みます。pixel(x, y)はその位置の色を(R, G, B)で返し、pixelMatchesColor()は指定色と一致するかをTrue・Falseで返します。
print(pyautogui.pixel(100, 200)) # 例: (130, 135, 144)
ok = pyautogui.pixelMatchesColor(100, 200, (130, 135, 144), tolerance=10)
toleranceは、R・G・Bのそれぞれの差がこの値以下なら一致とみなす幅です(PyScreeze 1.0.1のソースで確認)。既定は0で、1段階違うだけでFalseになります。座標はpixelMatchesColor(100, 200, rgb)のように2つの引数で渡します。『Automate the Boring Stuff with Python』第2版のpixelMatchesColor((100, 200), rgb)という書き方は、PyScreeze 1.0.1ではTypeErrorになるとソースに明記されています。
暴走を止めるFAILSAFEとPAUSEの設定
座標を間違えたスクリプトは、止めようとしたマウスを奪い返して動き続けます。PyAutoGUIはこれに備えて2つの仕組みを既定で有効にしています。
pyautogui.FAILSAFE = True:関数を呼んだ時点でマウスがプライマリモニタの四隅のどこかにあると、pyautogui.FailSafeExceptionを送出して止まります。pyautogui.PAUSE = 0.1:click()やwrite()などの入力操作関数は、実行後に0.1秒待ちます。その間にマウスを四隅へ移動すると、次の関数を呼んだ時点のフェイルセーフ確認で停止します。position()や画像検索のように、この待機と確認を持たない関数もあります。macOSではDARWIN_CATCH_UP_TIMEとして、さらに0.01秒が加わります。
FAILSAFEをFalseにするのは避けてください。ソースのdocstringもFailSafeExceptionを「捕まえるべきではない」例外と定めています。アプリの反応が遅くて操作を取りこぼすなら、PAUSEを0.3〜0.5秒に上げるか、画面の変化を画像検索で待つ処理を挟みます。time.sleep()を増やすより、「目印が出るまで待つ」ほうが処理時間も安定します。
alert()・confirm()・prompt()による実行前の確認と入力
自動操作を始める前に「対象の画面を前に出したか」を人に確かめたり、処理に使う値を入力してもらったりするには、PyAutoGUIのダイアログ関数を使います。中身はPyMsgBoxで、公式ドキュメントのダイアログのページに4つの関数があります。
| 関数 | 表示 | 戻り値 |
|---|---|---|
alert() |
OKボタン1つ | 押したボタンの文字列 |
confirm() |
OK・Cancel(変更可) | 押したボタンの文字列 |
prompt() |
入力欄+OK・Cancel | 入力文字列、CancelでNone |
password() |
伏せ字の入力欄 | 入力文字列、CancelでNone |
answer = pyautogui.confirm('対象のアプリを前面に出しましたか?', title='実行前の確認',
buttons=['OK', 'Cancel'])
if answer != 'OK':
raise SystemExit('中止しました')
month = pyautogui.prompt('処理する月を入力してください', default='2026-10')
reply = pyautogui.alert('10秒後に自動で閉じます', timeout=10000) # 時間切れは 'Timeout'
PyMsgBox 2.0.1のソースでは、timeoutの単位はミリ秒で、時間切れのときは文字列'Timeout'が返ります。Windowsではalert()とconfirm()がOS標準のダイアログで表示され、timeoutを指定したときや標準に無いボタン名を指定したときはTkinter版に切り替わります。macOSとLinuxは常にTkinter版なので、Linuxではpython3-tkが無いと表示できません。
PyAutoGUIの実用例:画像検索によるボタン操作と入力・保存
ここまでの関数を組み合わせた例です。この例は、「新規」ボタンのクリック後に件名欄へフォーカスが移り、保存ショートカットが使えるアプリを前提とします。実行前に対象アプリを表示し、同じ表示倍率で切り出したnew_button.pngを作業ディレクトリへ置いてください。この例は、画面キャプチャとマウス操作の座標倍率が等しく、対象画像が主モニタ内に見えている環境を前提とします。Retinaなどで倍率が異なる場合は、検索結果の座標を補正してからクリックしてください。
import sys
import time
import pyautogui
import pyperclip
pyautogui.PAUSE = 0.3
MOD = 'command' if sys.platform == 'darwin' else 'ctrl' # macOSはcommand
def wait_and_click(image, timeout=10):
"""画像が画面に出るまで待ってから中心をクリックする"""
end = time.monotonic() + timeout
while time.monotonic() < end:
try:
x, y = pyautogui.locateCenterOnScreen(image, confidence=0.9)
except pyautogui.ImageNotFoundException:
time.sleep(0.5)
continue
pyautogui.click(x, y)
return
raise TimeoutError(f'{image} が待機時間の目安 {timeout} 秒を超えても見つかりません')
if pyautogui.confirm('対象のアプリを前面に出してからOKを押してください') != 'OK':
sys.exit('中止しました')
wait_and_click('new_button.png')
pyperclip.copy('2026年10月 月次報告')
pyautogui.hotkey(MOD, 'v')
pyautogui.hotkey(MOD, 's')
confidenceを使っているのでopencv-pythonが必要です。画像の加工(切り出し・縮小)にはPillowとは?Pythonの画像処理ライブラリの使い方をコード付きで解説【13.0.0対応】の手順が使えます。
PyAutoGUIを選ばない方がよい場面と代替ツール
PyAutoGUIが一番強いのは、APIもアクセシビリティ情報も持たない古い業務アプリやゲーム画面を、見た目だけを頼りに動かす場面です。逆に、操作対象の中身を読み取れる手段があるなら、そちらを使うべきです。固定座標による操作はウィンドウ位置の変更でずれ、画像検索による操作は表示倍率やテーマの変更で一致しなくなります。
| 操作対象 | 選ぶツール | 理由 |
|---|---|---|
| Webブラウザ | Selenium・Playwright | 要素をIDやセレクタで指定 |
| Windowsアプリ | pywinauto・UI Automation | ボタン名で操作 |
| Excelのデータ処理 | openpyxl・pandas | 画面を開かずに処理 |
| 社内の定型業務全体 | Power Automate Desktop等 | 非開発者も保守できる |
| 中身が読めないアプリ | PyAutoGUI | 画面の見た目で操作 |
ブラウザ操作をPyAutoGUIで書くのは失敗パターンの典型です。ページの読み込み時間や広告の差し込みでボタンの位置が毎回変わり、画面を最小化すれば動きません。Seleniumなら要素の出現を待ってから操作でき、ヘッドレスで裏でも動きます。書き方はSeleniumとは?使い方をPythonで解説|4.51対応・ChromeDriverの手動設定が要らない書き方を参照してください。
Windowsのデスクトップアプリも、多くはUI Automationでボタンや入力欄を名前で取れます。PythonからはpywinautoのUIAバックエンドで扱えます。仕組みはUIAutomationとは|Windows UI自動化の仕組みとC#・Python・VBA実装【2026年版】で解説しています。PyAutoGUIを、これらで要素が取れなかった部分に絞ると、座標や画像の変更に合わせて修正する箇所を減らせます。
画面の見た目に頼る自動化が壊れやすいのは、市販のRPAでも同じです。画像認識に寄せたシナリオが保守で行き詰まる理由はWinActorが使えないと言われる理由|画像認識依存・属人化・端末専有の実像と回避策で扱っています。部署をまたぐ定型業務を、開発者以外も保守できる形へ移したい場合は、弊社のPower Automate導入支援・RPA移行でスクリプトからの置き換えを支援しています。
座標を人が決める代わりにAIが画面から推定する方式もあります。動作原理はComputer Useとは?AIが画面を見て操作する仕組みとClaude・OpenAI・Geminiの違い【2026年10月】にまとめています。
よくある質問
PyAutoGUIで何ができますか?
マウスの移動・クリック・ドラッグ・スクロール、キー入力とショートカット、スクリーンショット、画面上の画像検索と色の判定、確認ダイアログの表示ができます。操作対象のアプリの種類は問いませんが、動くのはプライマリモニタで、画面に見えている範囲だけです。
「PyAutoGUI was unable to import pyscreeze」と出るのはなぜですか?
Python 3.12以降では、依存するPyScreeze 1.0.1がPillowを自動で入れないためです。2026年10月28日の実測では3.12・3.13・3.14のどれでもPillowが入りませんでした。pip install pillowを実行してください。confidence引数を使うならopencv-pythonも必要です。
PyAutoGUIとpywinautoの違いは何ですか?
PyAutoGUIは画面の座標と見た目を頼りにマウスとキーの入力を送り、Windows・macOS・Linuxで動きます。pywinautoはWindows専用で、UI Automationなどを通してボタン名や入力欄を要素として指定します。Windowsアプリで要素が取れるならpywinautoのほうがウィンドウ位置や解像度の変化に強く、要素が取れない画面だけPyAutoGUIで補う使い分けになります。
Pythonでマウスカーソルを動かすには?
pyautogui.moveTo(x, y)で絶対座標へ、pyautogui.move(dx, dy)で今の位置から相対的に動かします。duration=0.5を付けると0.5秒かけて動きます。移動先の座標はpyautogui.position()で調べられます。
PyAutoGUIで日本語を入力できますか?
write()では入力できません。対応表に無い文字は、エラーを出さずに無視されます。pyperclip.copy('日本語')でクリップボードへ入れ、pyautogui.hotkey('ctrl', 'v')(macOSは'command')で貼り付けてください。JIS配列のWindowsで@などの記号が化けるときも同じ方法で入れられます。