スリ飯屋MaLankaのフリーエンジニアな日々

IT実務未経験から約1年、東京でフリーランスのRuby on Railsエンジニアに転職。約2年半、大阪中崎町でスリランカカレーの間借りしてました。フリーランスエンジニアになるためのノウハウ、スリランカの事を発信していきます。

【Ruby Selenium】wait.untilブロックでTimeoutしたら外側にraiseされる

【Selenium】wait.untilブロックでTimeoutしたら、waitの外側にraiseされる




今すぐ案件紹介をご希望の方へ


このブログから登録の多いエージェントは下記の3つです★

(リンクをクリックすると公式サイトに飛びます)

【ダントツの1番人気】フォスターフリーランス【案件保有数5000件以上。業界25年の超老舗】

【僅差で2位】フリエン(furien)【実務経験1年未満でも案件アリ!】

【惜しくも3位】レバテックフリーランス【業界最大手。素早く手厚いフォローで案件参画】




こんにちは、現役沖縄フリーランスエンジニアのmahです。


このブログでは、

僕がIT未経験から約1年でフリーランスエンジニアになるまでの過程、

ノウハウなどを書いていきます。


今回は、

  • Seleniumの、wait.untilブロックでTimeoutしたら、waitの外側にraiseされる

についてです。


【Ruby Selenium】wait.untilブロックでTimeoutしたら外側にraiseされる




Seleniumリファレンス


Seleniumクイックリファレンス


概要


Seleniumは、

find_element(s) というメソッドで要素を検索し、

要素が見つからなければエラーが発生します。


Seleniumのブラウザ処理は高速なので、

ページ上に要素が現れていない状態でも、

次々にクリックやページ遷移をしていきます。


ただそれだとエラーになるので、

  • 「特定の要素がページに表示されるまで、一定時間待機する」

という処理を加えて、

エラーを防止するのが定石です。


その待機時間を過ぎた場合は、

Selenium::WebDriver::Error::TimeoutError

が発生します。


このタイムアウトエラーの例外処理でハマりました。


コードで説明します。

ダメだったコードの例


def sample
  driver = Selenium::WebDriver.for :chrome

  # タイムアウトまでの時間
  wait = Selenium::WebDriver::Wait.new(timeout: 60)

  wait.until do
    driver.find_element(:id, 'search-result')&.displayed?
  rescue Selenium::WebDriver::Error::TimeoutError => e
    raise Selenium::WebDriver::Error::NoSuchElementError
  rescue Selenium::WebDriver::Error::NoSuchElementError => e
    Rails.logger.error <<~EOS
      エラー
      #{e}
    EOS
    nil
  end
end


上記のコード、wait.untilブロックの中の

driver.find_element(:id, 'search-result')&.displayed?

で、find_elementで要素が見つからなかった場合、

Selenium::WebDriver::Error::TimeoutError が発生します。


発生したSelenium::WebDriver::Error::TimeoutErrorは、

  • 直下のrescueで補足される

と思っていたが、そうではなかった。


これに気づくのにめちゃくちゃ時間がかかりました笑


調べていくと、

  • wait.untilブロックの外側

にraiseされていました...


なので、下記のようにすれば捕捉出来ました。


修正したコード


def sample
  driver = Selenium::WebDriver.for :chrome

  # タイムアウトまでの時間
  wait = Selenium::WebDriver::Wait.new(timeout: 60)

  wait.until do
    driver.find_element(:id, 'search-result')&.displayed? # ここで例外が発生しても直下のrescueでは捕捉出来ない
  rescue Selenium::WebDriver::Error::TimeoutError => e
    raise Selenium::WebDriver::Error::NoSuchElementError
  rescue Selenium::WebDriver::Error::NoSuchElementError => e
    Rails.logger.error <<~EOS
      エラー
    EOS
    nil
  end

# 外側にrescueを追加。wait.untilブロック内で発生した例外は、ここにraiseされるのでここで捕捉出来る
rescue Selenium::WebDriver::Error::TimeoutError => e
    Rails.logger.error <<~EOS
      waitブロックでのエラー
      #{e}
    EOS
  nil
end


これでタイムアウトした場合も、

スクレイピングがエラーで止まってしまわないよう、

処理を継続するように出来ます。


例外処理は、

  • どこで発生しているのか

  • どこに投げられる(raiseされる)のか

  • どこで捕捉(rescue)出来るのか


これらを意識するのが大事ですね。




以上です。




RailsやRubyを学びたい人へ


RailsやRubyを学びたい人は、

RailsHack(レイルズハック)という、

最近できた新しいプログラミングスクール(今なら通常価格69,800円が、早期割で29,800円!)か、

Udemy で下記のコースを受講すると良いです★


✅1. フルスタックエンジニアが教える 即戦力Railsエンジニア養成講座

✅2. 【はむ式】ハンズオンで学ぶRuby on Rails 6【Dockerにも触れられる】 <- おすすめ。ハムさんはReactやTypeScriptの教材も非常に丁寧。

✅3. はじめてのRuby on Rails入門-RubyとRailsを基礎から学びWebアプリケーションをネットに公開しよう




また、

Udemy は定期的にセールをやっていますし(90%OFFとかもザラ)、

「30日間なら返金できる」ので、

満足できなかった時でも安心です。


f:id:mah666hhh:20201129193352p:plain


【公式】RailsHack(レイルズハック)

【公式】Udemyで学んでみる




最後に


下記の表に、

フリーランスエンジニア向けの人気エージェントをまとめてみました。


エージェント選びで悩んでいる方は是非参考にしてみてくださいね★


エージェント 詳細 最高単価/月 設立
フリエン(furien) 評判をチェック 180万円/月 2011年
ギークスジョブ 評判をチェック 180万円/月 2011年
フォスターフリーランス 評判をチェック 230万円/月 1996年
pe-bank(pebank) 評判をチェック 200万円/月 1989年
Midworks(ミッドワークス) 評判をチェック 200万円/月 2013年
レバテックフリーランス 評判をチェック 140万円/月 2005年




あわせて読みたい


www.malanka.tech


www.malanka.tech


www.malanka.tech


www.malanka.tech