PythonのSeleniumを使って面倒な作業は自動化させています。
とくにブログに画像ファイルをアップロードさせる作業などは、予め自動でサーバーに載せておいたほうが後々楽だったりするので、そういうときにもSeleniumのプログラムは役に立ちますね。
アップロードをさせるのにファイル選択のボタンから、自PCのフォルダからファイルを選択してアップロードボタンを押して、というのを繰り返すのも面倒だったりするので。
そんな作業をプログラムするときによく躓くのが、「element not interactable」というエラー。
クリックしたいのに出来ない、とか、情報を送り込んでくれない、とかそういう系統です。
エレメントは見つかっているのに何でダメかなぁ、と言いたくなりますが、大抵の場合、次の2つのパティーンに分けられます。
1.複数のエレメントがあって、望みのものじゃない方を選択してしている
例えばこんな文。
element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'admin_common_positive_btn'))) element.click()
「admin_common_positive_btn」というクラスで見つけ出したelemenntをクリックさせたい。
なのに「element not interactable」と返ってくる。
いやいやいや、ボタンって書いてあるやん。
押せるでしょ。押させてよ。と思うわけですが…。
何度やっても無理。
もしかして、このクラスが複数ある?
ということで
elements = driver.find_elements_by_class_name('admin_common_positive_btn') print(len(elements))
としてみたら、2とか3とか、複数の数字が返ってきまして、そういうことか、と。
elements = driver.find_elements_by_class_name('admin_common_positive_btn') elements[1].click()
としてみたらとりあえずは動いたのでヨシ。
必ずしも常に2番めに望みのボタンがあるとは限らないので、本当はもう少し詰めないといけないのでしょうが、とりあえずはこれで。
実務的には、クラスでなく常にページ内で一つに絞れる何かを見つけられれば、それを使うほうが良いとは思います。
IDとか。
2.インプットできないクラスにインプットさせようとしている。
例えばこんなHTMLで書かれたアップロード先。
<div class="FileUploader_header"> <span><span id="spanButtonPlaceHolder">ファイル選択</span> <input name="upfile[]" type="file" multiple="true"> </span> <p>Ctrlキーを押しながらファイルを同時に選択できます。</p> </div>
Chromeで開いた見え方はこんな感じです。
アップロード先のクラスは「FileUploader_header」なんだな、ということで
drop_btn = driver.find_element_by_id('spanButtonPlaceHolder') drop_btn.send_keys(ImgFlePath + flename)
こんな文章でアップロードさせようとして失敗。
同様にクラスで指定し「FileUploader_header」を選択しても失敗。
これを、
drop_btn = driver.find_element_by_name('upfile[]') drop_btn.send_keys(ImgFlePath + flename)
としたら成功しました。
インプットを受け付ける要素でないと受け付けない、というシンプルな結論でした。
少しググって、「divタグに入力は出来ませんよ」という書き込みを見て気づいたのでした。