#スクレイピングのために Selenium+ChromeDriver を導入
現在開発中のWEBアプリのためにあるサイトの検索ボックスにキーを代入してスクレイピングていうやつをしようと思い、Selenium と ChromeDriver をインストール。
アプリ開発って、python だけできればいいってわけじゃないって改めて実感。
逆に、できることの幅は広がる広がる。
#で、検索ボックスに send_keys で入力しようとしたら、element not interactable とエラーになって怒られる
ネットに落ちてる情報をかき集めて何とか目的のサイトの目的の検索ボックスにアクセスする方法を見出して、send_keys で値を入力しようとしたら、なぜかエラー・・・
>>> from selenium import webdriver
>>> driver = webdriver.Chrome()
DevTools listening on ws:....
>>> driver.get('https://xxxxxxx..../')
>>> search_box = driver.find_element_by_name("value")
>>> search_box.send_keys('test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\webelement.py", line 477, in send_keys
self._execute(Command.SEND_KEYS_TO_ELEMENT,
File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
(Session info: chrome=89.0.4389.128)
>>>
なんでや!!!!
同じことを google でやったら普通にできました。
>>> from selenium import webdriver
>>> driver = webdriver.Chrome()
DevTools listening on ws:....
>>> driver.get('https://www.google.com/')
>>> search_box = driver.find_element_by_name("q")
>>> search_box.send_keys('test')
>>> search_box.submit()
>>>
コードに問題はない。ということはサイト依存でエラーになるかならないか決まるってことですね。
#原因は探したい要素の name が2つ以上あったこと
色々調べた結果、探そうとしている要素が2つ以上あるとうまく取得できないようでした。
上記のエラーになったサイトでは、目的としている検索ボックスの name="value" が2つめの "value" だったようで、1つめの "value" が指定された部分に send_keys が有効ではなかったようです。
#find_element_by_name を find_elements_by_name にして list で取得することでエラー回避
複数の要素を抽出したいときは、find_element を find_elements にすることで、list で抽出できるとのこと。
試してみたらうまくいきました!
>>> from selenium import webdriver
>>> driver = webdriver.Chrome()
DevTools listening on ws:....
>>> driver.get('https://www.google.com/')
>>> search_box = driver.find_element_by_name("q")
>>> search_box.send_keys('ChromeDriver')
>>> search_box.submit()
>>> driver.get('https://xxxxxxx..../')
>>> search_box = driver.find_elements_by_name("value")
>>> search_box[1].send_keys('test')
>>> search_box[1].submit()
>>>
要素の2番目を指定するあたり不細工ですが、css セレクターとかいうのもよくわからなかったので、ローカルで使用するだけのプログラムだし今のところいいか~ということでこれで実行!
#まとめ
こういう細かいバグ取りって、同じようなエラーをしている場合と、検索してもなかなかでてこないエラーもありますよね。
こうして記録しておくことで、同じようなことで悩まれる人が減ったらいいなと思います。