Seleniumとpywinautoでファイルの自動アップロード
ファイルアップロード処理の自動化
Webアプリケーションへのファイルのアップロード処理をSeleniumを使って自動化した。
環境 :WIndows10、Python3.7、Chrome
アップロード処理の場合、「ファイル選択ボタンを押す⇒ファイル選択⇒アップロード」の流れになると思うが、Seleniumではここがなかなかの鬼門。
ファイル選択ボタンを押して、ファイル選択ダイアログが出た瞬間、OS側の処理となり、Seleniumでは制御できなくなってしまうためである。
send_keysを使った処理
seleniumによるファイルアップロードで検索するとよく出てくるのが、send_keysを使った処理。
まずはこれを試してみたのだが、適用しようとしていたWebアプリではうまく行かなかった。Webアプリのソースを見ると、Javascriptライブラリからファイルアップロード処理をしていた。この場合、単純にsend_keysを使うとうまく行かないようだ。
pywinautoによるファイルアップロード
send_keysでうまく行かず、なかなか焦っていたところ、以下のページにたどり着いた。pywinautoというライブラリを使用すると、制御できるっぽい。試してみたところ、何とか動作させることができました。
seleniumとpywinautoでChromeのWEBページを印刷する。 - とりあえず日記
pywinauto
Windowsの操作を自動化するためのPythonライブラリで、以下の手順でインストールする。
- pywin32(PythonからWindowsAPIにアクセスするためのPythonエクステンション)を入れる https://github.com/mhammond/pywin32/releases
- ライブラリのインストール
pip install pywinauto pywin32
コード
処理の流れ
- (Selenium) ファイル選択ボタンクリック
- (pywinauto) ファイル選択ダイアログのファイル入力欄にフォーカス
- (pywinauto) アップロードするファイルのフルパスを入力
- (pywinauto) ファイル選択ダイアログの「開く」ボタンをクリック
コード
import pywinauto def upload_file(file_path): # アップロードボタンのエレメントを取得 elements = driver.find_elements_by_class_name("xxxxx") element = elements[0] element.click() # pywinautoによる制御 findWindow = lambda: pywinauto.findwindows.find_windows(title='開く')[0] dialog = pywinauto.timings.wait_until_passes(5, 1, findWindow) pwa_app = pywinauto.Application() pwa_app.connect(handle=dialog) window = pwa_app['開く'] window.wait('ready') #ファイル入力(Alt+N) pywinauto.keyboard.send_keys("%N") edit = window.Edit4 edit.set_focus() edit.set_text(file_path) # ダイアログの「開く」ボタンをクリック button = window['開く(&O):'] button.click()
※今回使用したWebアプリはファイルを選択した瞬間、アップロード処理が走ったのでここまでの処理です。通常は、ダイアログが終了し、ファイルアップロードボタンをクリックする流れになると思いますので、その場合は、引き続きSeleniumでボタンクリックする流れになると思います。
※参考