機械の中の学習日誌

社畜によるIT技術メモです。今日も元気です。

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ライブラリで、以下の手順でインストールする。

  1. pywin32(PythonからWindowsAPIにアクセスするためのPythonエクステンション)を入れる https://github.com/mhammond/pywin32/releases
  2. ライブラリのインストール
  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でボタンクリックする流れになると思います。

※参考

pywinauto.readthedocs.io