どうもてぃ。
自社開発でseleniumをよく使うのですが、とあるサイトをクローリングしているときに出くわしたエラーを力技で解決したので備忘録として残します。
環境
- wsl2
- ruby 3.1.2p20
- Google Chrome 109.0.5414.74 (wslへinstallしたもの)
コード
require 'selenium-webdriver' options = Selenium::WebDriver::Chrome::Options.new client = Selenium::WebDriver::Remote::Http::Default.new wait = Selenium::WebDriver::Wait.new(timeout: 20) options.add_argument('--headless') options.add_argument('--disable-gpu') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--window-size=1920,1080') options.add_argument('--lang=ja-JP') driver = Selenium::WebDriver.for(:chrome, capabilities: [options], http_client: client) driver.get('https://example.com') footer = driver.find_element(:tag_name, 'footer') footer.location_once_scrolled_into_view
エラー内容
element not interactable (Session info: chrome=109.0.5414.74) #0 0x555fe9d48303 <unknown>: element not interactable (Selenium::WebDriver::Error::ElementNotInteractableError) (Session info: chrome=109.0.5414.74) from #1 0x555fe9b1cbbd <unknown> from #2 0x555fe9b530bc <unknown> from #3 0x555fe9b52669 <unknown> from #4 0x555fe9b79982 <unknown> from #5 0x555fe9b4e22f <unknown> from #6 0x555fe9b79b4e <unknown> from #7 0x555fe9b9188c <unknown> from #8 0x555fe9b79753 <unknown> from #9 0x555fe9b4ca14 <unknown> from #10 0x555fe9b4db7e <unknown> from #11 0x555fe9d9732e <unknown> from #12 0x555fe9d9ac0e <unknown> from #13 0x555fe9d7d610 <unknown> from #14 0x555fe9d9bc23 <unknown> from #15 0x555fe9d6f545 <unknown> from #16 0x555fe9dbc6a8 <unknown> from #17 0x555fe9dbc836 <unknown> from #18 0x555fe9dd7d13 <unknown> from #19 0x7f3bf207e609 start_thread from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/response.rb:56:in `assert_ok' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/response.rb:35:in `initialize' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/http/common.rb:83:in `new' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/http/common.rb:83:in `create_response' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/http/default.rb:103:in `request' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/http/common.rb:59:in `call' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/bridge.rb:625:in `execute' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/bridge.rb:411:in `send_keys_to_element' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/remote/bridge.rb:493:in `element_location_once_scrolled_into_view' from /home/motty/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/selenium-webdriver-4.7.1/lib/selenium/webdriver/common/element.rb:307:in `location_once_scrolled_into_view' from scraping.rb:49:in `block (2 levels) in <main>' from scraping.rb:36:in `each' from scraping.rb:36:in `block in <main>' from scraping.rb:24:in `each' from scraping.rb:24:in `<main>'
よくわからん…
動的な要素だからとか??
力技を実行
jsの力を発動します。
seleniumでjsを実行する場合はexecute_script
を使用します。
require 'selenium-webdriver' options = Selenium::WebDriver::Chrome::Options.new client = Selenium::WebDriver::Remote::Http::Default.new wait = Selenium::WebDriver::Wait.new(timeout: 20) options.add_argument('--headless') options.add_argument('--disable-gpu') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--window-size=1920,1080') options.add_argument('--lang=ja-JP') driver = Selenium::WebDriver.for(:chrome, capabilities: [options], http_client: client) driver.get('https://example.com') footer = driver.find_element(:tag_name, 'footer') driver.execute_script("window.scrollTo(#{footer.location.x}, #{footer.location.y});")
要素の座標はdriver.find_element
して取得した要素に対して、location
にアクセスしてあげればx座標とy座標が入ってるので、この子たちを使ってあげましょう。
終わり
実際のコードは画像をfind_elementしていて、headless modeで起動せずに目視でちゃんと要素が表示されているにも関わらず、タイトルのようなエラーが出ていました。
解決策を探しているうちにissueも上がっていた気がしますが、なんかcloseされてたので今回は力技でひとまず解決。
同じエラーが発生したときの正攻法(?)として誰かの力になればばばば。
おつでした。