Selenium WebDriverをPythonで動かしているときにファイルの選択のsend_keysでフリーズする【PhantomJS】


結論

(少なくとも)
inputタグのdisplaynoneの場合、うまくファイルを設定できない。

なので、ファイルを指定する前に、styleをいじって可視化してやるとうまくいく。

driver.execute_script("document.getElementsByName('datafile')[0].style.display = '';")

検証環境

  • Linux(調べるとよくWindows環境が出てきます)
  • Python 2.7.5
  • selenium (2.53.6)
  • phantomjs 2.1.1

3系じゃないのとかHeadless Chromeじゃないんですかとかは気にしないで。

検証サイトは
<INPUT type="file">-HTMLタグリファレンス
inputを使わせてもらいます。

コード

成功するやつ
from selenium import webdriver
from selenium.common.exceptions import TimeoutException

if __name__ == '__main__':
    try:
        driver = webdriver.PhantomJS()
        driver.get('http://www.htmq.com/html/input_file.shtml')
        elm = driver.find_element_by_name("datafile")
        print('get')
        elm.send_keys('./test.jpg')
        print('send')
    except TimeoutException as e:
        print(e)
    finally:
        driver.quit()
失敗するやつ
from selenium import webdriver
from selenium.common.exceptions import TimeoutException

if __name__ == '__main__':
    try:
        driver = webdriver.PhantomJS()
        driver.get('http://www.htmq.com/html/input_file.shtml')
        # new!
        driver.execute_script("document.getElementsByName('datafile')[0].style.display = 'none';")
        elm = driver.find_element_by_name("datafile")
        print('get')
        elm.send_keys('./test.jpg')
        print('send')
    except TimeoutException as e:
        print(e)
    finally:
        driver.quit()

この例では正常に動くものをわざと動かないようにしている。
翻って、失敗するもの=style.display = 'none'なものはこれを取り除かないといけない。

driver.execute_script("document.getElementsByName('datafile')[0].style.display = '';")

遭遇したサイトは隠したinputを内包したdivでボタンを作っていた。
手動でもSeleniumIDEでも問題なく動いていたので、問題の特定にかなり手間取った…