Youtubeでも活動中

チャンネル登録してくれたら喜びます。

このボタンで簡単にチャンネル登録!

【pythonで自動化】最終手段のpyautogui

python-pyautogui-automation-eyecatchPython

pythonで自動化とか聞いて楽しそうだと思いましたね?

これ結構便利な自動化の方法なので、覚えておくと色々なところで使えます。

自動化の1歩目としても最適です。

この記事に書いてあることをマスターすることで、【人の作業】を自動化することが可能です。

ではこの【人の作業】とは具体的に何を表しているかというと、

それは、

  • マウス操作
  • キーボード入力

この2つです。

人間はこの2つの操作をしてパソコンを制御していますよね?

つまり、この2つの操作をプログラミング上で再現することができれば、

【人の作業】を自動化できるというわけです。

いくつか方法はあると思いますが、
今回はPythonを使ってWindowsのPCを制御する方法を紹介します。

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

転職に成功して現在は超大手企業でシステム系の開発をしています。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

Pythonを起動する。

まずはPythonを起動しましょう。

以前の記事でPythonを使うなら、VisualStudioCodeというエディターを使用するのが
おすすめとお伝えしましたが、現在でも変わっていません。

anacondaでもjupiyerでもできますが、
他のプログラミング言語を使用している場合(C#やC++)VisualStudioと似たような使用感なので、
使いやすさという点でオススメできます。

以前の記事を張り付けておきます。↓↓

以前の記事

VisualStudioCodeはMicroSoftが製作しており、無料で提供されていますから、
信頼できる発行元で無償。これは使わない手はないですよね。

pyautoguiでできることを確認する。

では、早速pyautoguiを導入するのですが、
その前にpyautoguiで何ができるのか?それをしっかり把握しておくことが必要です。

Welcome to PyAutoGUI’s documentation! — PyAutoGUI documentation

↑こちらがpyautoguiの公式のページです。

pyatuoguiはpipでインストールしますので、
この公式ページから何かダウンロードする必要はありません。

pyautoguiの公式ページに載っている内容を解説。

pyautoguiの公式ページに書いてあることを抜粋します。↓

PyAutoGUI has several features:

  • Moving the mouse and clicking in the windows of other applications.
  • Sending keystrokes to applications (for example, to fill out forms).
  • Take screenshots, and given an image (for example, of a button or checkbox), and find it on the screen.
  • Locate an application’s window, and move, resize, maximize, minimize, or close it (Windows-only, currently).
  • Display alert and message boxes.
https://pyautogui.readthedocs.io/en/latest/

公式ページは英語です。日本語に翻訳したものを載せてもよかったのですが、
誤った情報を載せるのはまずいので原文そのまま載せています。

ここに書いてある内容をざっくり解説します。

できることは、

  • 他のアプリのウィンドウ内にマウスを動かしたり、クリックをすることができる。
  • 他のアプリ上でキーボード入力を行える。
  • windows限定、アプリのウィンドウの位置の移動、サイズ変更、最小化、クローズが可能。
  • 警告文やメッセージボックスを表示させる。

これだけだとイメージできないかもしれません。ちょっと例を挙げて説明しましょう。

今回は上記のうち、上二つについて解説を行います。

他のアプリのウィンドウ内にマウスを動かしたり、クリックをすることができる。

ここでいう他のアプリとは、pythonで直接操作していないものを指します。

基本的に画面上に表示されているところであればどこでもマウスカーソルを移動できます。

さらに、カーソルを移動させるだけではなく、左クリック、右クリックなども実装されています。

実際にマウスカーソルを自動で動かしている動画はこちら↓↓

マウスカーソルをpyautoguiで移動させている様子

ちょっとクリックする動作をお見せしたかったので簡単なアプリケーションを作成しました。

これはボタンを押すとメッセージボックスを表示させ、

そのメッセージボックスをボタンをクローズさせる動作を自動化しています。

その動画はこちら↓↓↓

マウスクリックをpyautoguiで自動化した様子

他のアプリ上でキーボード入力を行える。

マウス操作ができたので、今度はキーボード入力です。

先ほど作成したアプリにテキストボックスを作成したので、
そちらに文字入力をします。

具体的には、abc123と打ち込みます。

実際に入力している様子はこちら↓↓

キーボード入力をpyautoguiで自動入力している様子

pyautoguiをインストールする。

さて、VisulaStudioCodeを起動したところで、まずはコンソールでpyautoguiを
使えるようにpipをしましょう。

pip install pyautogui

これだけです。

これでpyautoguiを使う準備は完了です。

インストーラのダウンロードなど不要なので簡単ですね。

ちなみにVisulaStuidioCodeの場合は、コンソールタブのところで入力します。

pyautoguiInstall
VisualStudioCodeの場合はここに入力する。

このコマンドを打ち込んで実行することで、
このように自動的にダウンロードとインストールが行われます。

pyautoguiInstall-vscode
ターミナルでpipを使ってpyautoguiをインストール

pipが通らないときは、パスがしっかりpythonの入っているフォルダを指定しているか
確認しましょう。へんなところにいるとpipが通らないことがあります。

環境変数にあらかじめpipを入れておくのもアリだと思います。

実際にpyautoguiを使って自動化してみる。

さて、ここまで来たら後は実際にpyautoguiを使ってみましょう。

その前に注意点があります。かなり重要なので必ず覚えておいてください。

その注意点は、pyautoguiを起動してwile文のような無限ループを実行する場合、
マウスとキーボードの制御をpythonに取られますので、
この方法を知らないと、マウスとキーボード操作ができなくなります。

そんな時は、マウスカーソルのみ制御が取られている場合は、
shiftキー+F5キー

これでVisulaStudioCodeの実行が中断されて制御を取り戻せます。

ただし、VisualStudioCodeのウィンドウがアクティブになっていない場合は、
この方法は使えません。

例えば、マウスクリック機能を使って他のウィンドウをアクティブにしている場合ですね。

そんなときは、

Ctrlキー+Altキー+Deleteキー

同時押しして下さい。すると、ロックや、ログオフなどの選択画面になると思います。

Ctlrキー+Altキー+Deleteキーで表示される画面
Ctlrキー+Altキー+Deleteキーで表示される画面

その状態でキャンセルすると、python側でエラーを強制的に出すことで中断できます。

キャンセルで大丈夫です。ログオフやロックはしなくて大丈夫です。

便利に使おうとして自動化しようとしているのに、
制御を奪われて中断できないというのはちょっとカッコ悪いですからね…

この方法は必ず覚えていてくださいね。結構使いますので。

マウスカーソルを指定の位置に移動する。

動画で紹介していた内容のソースコードです。

マウスカーソルを移動させるには、

pyautogui.moveTo(X座標,Y座標)

このメソッドを使用します。

X座標とY座標に関しては、パソコンのディスプレイ内の座標系です。

さて、ここで疑問に思うのが、押したい座標がどこにあるのか?

という疑問ですよね。それを解決するためには次の章のマウスカーソルの座標を取得する
方法を使うことで解決できます。

マウスカーソルの座標を取得する。

マウスカーソルの座標を取得することで、今マウスカーソルがどこにいるのかわかります。

その機能を使うことで、あらかじめどこにカーソルを持っていくか決めることができます。

使用するには、

pyautogui.position()

このメソッドを使用します。

これだけだとちょっと使いにくいので、コンソールに1秒ごとに
マウスカーソルの座標を表示させるサンプルコードを示しておきます。

import pyautogui
import time

while(True):    
    x, y = pyautogui.position()
    positionStr = 'X: ' + str(x).rjust(4) + ' Y: ' + str(y).rjust(4)
    print(positionStr)
    print('\b' * (len(positionStr) + 2))
    time.sleep(1)

実際に動作させたときの結果を動画にしましたのでご覧ください。↓↓

pyautoguiでマウスカーソルの位置(座標)を自動で取得して表示している様子。

マウスで指定位置をクリックする。

さて、どこを実際にマウスを持っていきたいか分かったところで、
実際にクリックしてみましょう。

マウスで左クリックするのは、

pyautogui.click(X座標,Y座標)

このメソッドを使用します。

引数のX座標とY座標には、先ほどpyautogui.positionで取得した値を入れることになります。

このpyautogui.clickは、移動も含めて行ってくれるので、pyautogui.moveTo()は不要です。

カーソルが瞬時に指定した位置に移動してクリックしてくれます。

実際の動作については先ほど動画でご覧いただいたと思いますので、
ソースコードのサンプルを示しておきます。

import pyautogui
import time

while(True):   
    pyautogui.click(510,350)
    time.sleep(1)
    pyautogui.click(1937,1125)
    time.sleep(1)

この(510,359)はUPのボタンの座標、(1937,1125)はメッセージボックス内のOKボタンの座標です。

ここの数値や、クリックする回数はコピー&ペーストすればいくらでも増やすことが可能です。

キーボード入力を自動で行う。

最後にキーボード入力を自動化しましょう。

キーボード入力は同じキーを押すにしても圧倒的に自動で入力したほうが早いです。

タイプミスも起こりませんし、圧倒的に効率が良いです。

挙動については先ほど動画を上げていますから、そのソースコードについて示します。

キーボード入力には、

pyautogui.write("入力したい文字")

pyautogui.write()という関数を使用します。

具体的な使用方法についてはこちら↓↓

import pyautogui
import time

while(True):   
    pyautogui.click(694,451)
    time.sleep(3)
    pyautogui.write("abc123")
    time.sleep(3)

一回目にpyautogui.click()が入っていますが、
これはテキストボックスをクリックして、テキストボックスをアクティブにする作業です。

もし常にテキストボックスがアクティブになっているようだったら、
このpyautogui.click()は不要です。

もしくは、一度アクティブにして他のところをアクティブにする予定がないのであれば、
pyautogui.click()は1回だけ行えばOKです。

pyautoguiの注意点。

さて、先ほど注意点としてマウスとキーボード操作がpythonに取られてしまう場合の、
対処方法について解説していましたが、これは結構深刻な問題になることがあります。

というのも、自動化は自動化なのですが、実はこの自動化を起動中は、
他の作業ができません。

実行してみればわかりますが、マウスとキーボード操作が決められたタイミングで発動するため、
他に例えばエクセルで数値計算しようかな、パワーポイントで資料作りしようかな。

なんて場合はマウスもキーボードもpythonに制御を取られているのでまともに動かせません。

この注意点が今回の題名にある通り、最終手段と表現している最大の理由です。

自動化するというと、人の代わりに勝手にやってくれるというのが世間一般の理解だと思います。

たしかに人の代わりに自動でやってくれるのですが、
その間同じパソコンで別の作業ができなくなるというのは本当の意味での自動化なのか??

というわけですね。

ただこのpyautoguiを使うことで、実際の人間が行っている作業をトレースすることが可能なので、
外部的に制御不能な、例えばこれを使ってほしいと渡されたアプリケーションなんかを、
自動で動かすためには強力なツールになります。

基本的にはアプリケーションの自動化にもいろいろありますが、
例えば自分で作成したアプリケーションに、別のアプリケーションの動作を行わせるような場合、
別のアプリケーションにライブラリのようなものが発行されていることが多いと思います。

ですから、別のアプリケーションのライブラリを取り込むことで
裏で勝手に動かすということが可能なわけですね。

今回の記事のまとめ。

今回はpyautoguiの基本機能について解説しました。

自動化の第一歩としてこの方法を使うのは良いと思います。

人間が行う作業とまったく同じことをマウスとキーボードを使って再現できるのが、
最大の特徴です。

その分、実行中はマウスとキーボードの制御を取られるということだけ
忘れないようにして下さい。

導入もpythonとpyautoguiをインストールだけで、
どちらも無料で使用することができますしコストも0円です。

ソースコードも示していますが、強力でわかりやすい関数が用意されているので、
プログラミング初心者でも十分に理解できる内容です。

ぜひこの方法を覚えて自動化の引き出しを増やしてもらえると嬉しいです。

コメント

'}},vars:{discoveredBrushes:null,highlighters:{}},brushes:{},regexLib:{multiLineCComments:XRegExp("/\\*.*?\\*/","gs"),singleLineCComments:/\/\/.*$/gm,singleLinePerlComments:/#.*$/gm,doubleQuotedString:/"([^\\"\n]|\\.)*"/g,singleQuotedString:/'([^\\'\n]|\\.)*'/g,multiLineDoubleQuotedString:XRegExp('"([^\\\\"]|\\\\.)*"',"gs"),multiLineSingleQuotedString:XRegExp("'([^\\\\']|\\\\.)*'","gs"),xmlComments:XRegExp("(<|<)!--.*?--(>|>)","gs"),url:/https?:\/\/[\w-.\/?%&=:@;#]*/g,phpScriptTags:{left:/(<|<)\?(?:=|php)?/g,right:/\?(>|>)/g,eof:!0},aspScriptTags:{left:/(<|<)%=?/g,right:/%(>|>)/g},scriptScriptTags:{left:/(<|<)\s*script.*?(>|>)/gi,right:/(<|<)\/\s*script\s*(>|>)/gi}},toolbar:{getHtml:function(e){function t(e,t){return B.toolbar.getButtonHtml(e,t,B.config.strings[t])}for(var n='
',r=B.toolbar.items,i=r.list,a=0,l=i.length;l>a;a++)n+=(r[i[a]].getHtml||t)(e,i[a]);return n+=""},getButtonHtml:function(t,n,r){return n=e(n),''+e(r)+""},handler:function(e){function t(e){var t=RegExp(e+"_(\\w+)"),n=t.exec(r);return n?n[1]:null}var n=e.target,r=n.className||"",i=s(g(n,".syntaxhighlighter").id),a=t("command");i&&a&&B.toolbar.items[a].execute(i),e.preventDefault()},items:{list:["expandSource","help"],expandSource:{getHtml:function(e){if(1!=e.getParam("collapse"))return"";var t=e.getParam("title");return B.toolbar.getButtonHtml(e,"expandSource",t?t:B.config.strings.expandSource)},execute:function(e){var t=o(e.id);r(t,"collapsed")}},help:{execute:function(){var e=x("","_blank",500,250,"scrollbars=0"),t=e.document;t.write(B.config.strings.aboutDialog),t.close(),e.focus()}}}},findElements:function(e,t){var n=t?[t]:i(document.getElementsByTagName(B.config.tagName)),r=B.config,a=[];if(r.useScriptTags&&(n=n.concat(A())),0===n.length)return a;for(var l=0,s=n.length;s>l;l++){var o={target:n[l],params:p(e,E(n[l].className))};null!=o.params.brush&&a.push(o)}return a},highlight:function(e,t){var n=this.findElements(e,t),r="innerHTML",i=null,a=B.config;if(0!==n.length)for(var l=0,s=n.length;s>l;l++){var o,t=n[l],u=t.target,c=t.params,g=c.brush;if(null!=g){if("true"==c["html-script"]||1==B.defaults["html-script"])i=new B.HtmlScript(g),g="htmlscript";else{var h=b(g);if(!h)continue;i=new h}o=u[r],a.useScriptTags&&(o=M(o)),""!=(u.title||"")&&(c.title=u.title),c.brush=g,i.init(c),t=i.getDiv(o),""!=(u.id||"")&&(t.id=u.id),u.parentNode.replaceChild(t,u)}}},all:function(e){m(window,"load",function(){B.highlight(e)})}};return B.Match=function(e,t,n){this.value=e,this.index=t,this.length=e.length,this.css=n,this.brushName=null},B.Match.prototype.toString=function(){return this.value},B.HtmlScript=function(e){function t(e,t){for(var n=0,r=e.length;r>n;n++)e[n].index+=t}function n(e){for(var n,a=e.code,l=[],s=r.regexList,o=e.index+e.left.length,u=r.htmlScript,c=0,g=s.length;g>c;c++)n=L(a,s[c]),t(n,o),l=l.concat(n);null!=u.left&&null!=e.left&&(n=L(e.left,u.left),t(n,e.index),l=l.concat(n)),null!=u.right&&null!=e.right&&(n=L(e.right,u.right),t(n,e.index+e[0].lastIndexOf(e.right)),l=l.concat(n));for(var h=0,g=l.length;g>h;h++)l[h].brushName=i.brushName;return l}var r,i=b(e),a=new B.brushes.Xml,l=this,s="getDiv getHtml init".split(" ");if(null!=i){r=new i;for(var o=0,u=s.length;u>o;o++)(function(){var e=s[o];l[e]=function(){return a[e].apply(a,arguments)}})();return null==r.htmlScript?(v(B.config.strings.brushNotHtmlScript+e),void 0):(a.regexList.push({regex:r.htmlScript.code,func:n}),void 0)}},B.Highlighter=function(){},B.Highlighter.prototype={getParam:function(e,t){var n=this.params[e];return d(null==n?t:n)},create:function(e){return document.createElement(e)},findMatches:function(e,t){var n=[];if(null!=e)for(var r=0,i=e.length;i>r;r++)"object"==typeof e[r]&&(n=n.concat(L(t,e[r])));return this.removeNestedMatches(n.sort(k))},removeNestedMatches:function(e){for(var t=0,n=e.length;n>t;t++)if(null!==e[t])for(var r=e[t],i=r.index+r.length,a=t+1,n=e.length;n>a&&null!==e[t];a++){var l=e[a];if(null!==l){if(l.index>i)break;l.index==r.index&&l.length>r.length?e[t]=null:l.index>=r.index&&i>l.index&&(e[a]=null)}}return e},figureOutLineNumbers:function(e){var t=[],n=parseInt(this.getParam("first-line"));return y(e,function(e,r){t.push(r+n)}),t},isLineHighlighted:function(e){var t=this.getParam("highlight",[]);return"object"!=typeof t&&null==t.push&&(t=[t]),-1!=h(t,""+e)},getLineHtml:function(e,t,n){var r=["line","number"+t,"index"+e,"alt"+(""+(0==t%2?1:2))];return this.isLineHighlighted(t)&&r.push("highlighted"),0==t&&r.push("break"),'
'+n+""},getLineNumbersHtml:function(e,t){var n="",r=a(e).length,i=parseInt(this.getParam("first-line")),l=this.getParam("pad-line-numbers");1==l?l=(""+(i+r-1)).length:1==isNaN(l)&&(l=0);for(var s=0;r>s;s++){var o=t?t[s]:i+s,e=0==o?B.config.space:S(o,l);n+=this.getLineHtml(s,o,e)}return n},getCodeLinesHtml:function(e,t){e=C(e);for(var n=a(e),r=(this.getParam("pad-line-numbers"),parseInt(this.getParam("first-line"))),e="",i=this.getParam("brush"),l=0,s=n.length;s>l;l++){var o=n[l],u=/^( |\s)+/.exec(o),c=null,g=t?t[l]:r+l;null!=u&&(c=""+u[0],o=o.substr(c.length),c=c.replace(" ",B.config.space)),o=C(o),0==o.length&&(o=B.config.space),e+=this.getLineHtml(l,g,(null!=c?''+c+"":"")+o)}return e},getTitleHtml:function(t){return t?""+e(t)+"":""},getMatchesHtml:function(e,t){function n(e){var t=e?e.brushName||a:a;return t?t+" ":""}for(var r=0,i="",a=this.getParam("brush",""),l=0,s=t.length;s>l;l++){var o,u=t[l];null!==u&&0!==u.length&&(o=n(u),i+=N(e.substr(r,u.index-r),o+"plain")+N(u.value,o+u.css),r=u.index+u.length+(u.offset||0))}return i+=N(e.substr(r),n()+"plain")},getHtml:function(t){var n,r,i,a="",s=["syntaxhighlighter"];return 1==this.getParam("light")&&(this.params.toolbar=this.params.gutter=!1),className="syntaxhighlighter",1==this.getParam("collapse")&&s.push("collapsed"),0==(gutter=this.getParam("gutter"))&&s.push("nogutter"),s.push(this.getParam("class-name")),s.push(this.getParam("brush")),t=w(t).replace(/\r/g," "),n=this.getParam("tab-size"),t=1==this.getParam("smart-tabs")?R(t,n):H(t,n),this.getParam("unindent")&&(t=P(t)),gutter&&(i=this.figureOutLineNumbers(t)),r=this.findMatches(this.regexList,t),a=this.getMatchesHtml(t,r),a=this.getCodeLinesHtml(a,i),this.getParam("auto-links")&&(a=I(a)),"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.match(/MSIE/)&&s.push("ie"),a='
'+(this.getParam("toolbar")?B.toolbar.getHtml(this):"")+''+this.getTitleHtml(this.getParam("title"))+""+""+(gutter?'
'+this.getLineNumbersHtml(t)+"":"")+''+'
'+a+""+""+""+""+""+""},getDiv:function(e){null===e&&(e=""),this.code=e;var t=this.create("div");return t.innerHTML=this.getHtml(e),this.getParam("toolbar")&&m(c(t,".toolbar"),"click",B.toolbar.handler),this.getParam("quick-code")&&m(c(t,".code"),"dblclick",X),t},init:function(e){this.id=f(),u(this),this.params=p(B.defaults,e||{}),1==this.getParam("light")&&(this.params.toolbar=this.params.gutter=!1)},getKeywords:function(e){return e=e.replace(/^\s+|\s+$/g,"").replace(/\s+/g,"|"),"\\b(?:"+e+")\\b"},forHtmlScript:function(e){var t={end:e.right.source};e.eof&&(t.end="(?:(?:"+t.end+")|$)"),this.htmlScript={left:{regex:e.left,css:"script"},right:{regex:e.right,css:"script"},code:XRegExp("(?"+e.left.source+")"+"(?.*?)"+"(?"+t.end+")","sgi")}}},B}();"undefined"!=typeof exports?exports.SyntaxHighlighter=SyntaxHighlighter:null;
タイトルとURLをコピーしました