Python+Seleniumを使ったスクレイピングその1(2023年10月時点)
今回はスクレイピングに関するメモです。Pythonでスクレイピングするといえば、urllib+BeautifulSoupがよく検索で出てきますが、最近のwebページはJavaScriptによってレンダリングされていることが多く、うまくスクレイピングできません。
そこで、Seleniumというブラウザ(ChromeとかFireFoxとか)の自動操作用ライブラリを活用することで、上記の問題をうまくかわしてスクレイピングを行うことができます。数年ぶりに久しぶりに使おうとしたら色々と状況が変わっていたので備忘録として使い方を残しておきます。ついでに、Ajaxなどを使った、動的なwebページに対応するための待機処理に関するTipsもまとめておきます。なお、今回もWindows環境が前提です。
なお、スクレイピング自体が著作権・サーバーへの負荷等の問題が生じうる行為なので、ルール・マナーを守った運用が必要です。自分への戒めも兼ねて、注意事項として記載しておきます。
Seleniumについて、状況が変わっていたこと
数年前の時点ではSeleniumを扱う際に、以下のように別のものをインストールする必要があり、ハマることが多かったです。
- Chromeを使いたい→Seleniumとは別に、chromedriverのインストールが必要
- Seleniumを使う際に、操作するブラウザが表示されないようにしたい→Seleniumとは別にPhantomJSが必要
しかし、最近バージョンアップされたSeleniumではそれ単体で上記のやりたいことを実現できるようになっていました。今回は4.14.0のバージョンのSeleniumを使って、実際に試していきます。
使い方その1|基本的な使い方
まずはライブラリをインポートします。
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By
インポートした後は、次のようにコードを記述することで、スクレイピングを行うことができます。 今回はPythonの公式ページにアクセスしてみます。
# アクセスしたいURLを指定 url = "http://www.python.org" # ブラウザを操作するためのwebdriverを設定 options = Options() options.add_argument("--headless") # このオプション設定により、ブラウザが表示されなくなる driver = webdriver.Chrome(options=options) # chromedriverを別でインストールする必要なし # ブラウザを起動し、URLにアクセス driver.get(url) # HTMLの要素を取得 elem = driver.find_element(By.CSS_SELECTOR, "div.introduction") print(elem.text) # ブラウザを閉じる driver.close()
# 実行結果 Python is a programming language that lets you work quickly and integrate systems more effectively. Learn More
Pythonの公式ページにアクセスし、要素を取得できていることが確認できました。
使い方その2|待機処理を意識した使い方
Ajaxを利用したJavaScriptのレンダリングなどがある場合、URLにアクセスしてから(あるいは何かしらSeleniumでwebページの操作を行ってから)HTMLの要素が全てレンダリングされるまでに時間がかかることがあります。
※もちろん、JavaScript以外の理由として、ネット回線の速度やサーバー側の負荷が問題になる場合もあります。
time.sleep(5)
など、URLにアクセスしてから要素を取得するまでの間に明示的に待ち時間を設けることも可能ですが、待ち時間が不十分でレンダリングが間に合わずに要素の取得時にエラーとなってしまったり、逆にレンダリングがすぐに終わってしまい、無駄な時間がかかってしまう恐れがあります。
そこで、WebDriverWait
とexpected_conditions
を活用することで上記の問題を解決しながらスクレイピングを行うことが可能になります。
それでは、基本的な使い方のときと同様に、まずは必要なライブラリをインポートします。
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait # 追加 from selenium.webdriver.support import expected_conditions as EC # 追加
WebDriverWait
とexpected_conditions
を利用して、先程のコードを書き直してみます。横にコメントが記載されている行が変更点です。
# アクセスしたいURLを指定 url = "http://www.python.org" # ブラウザを操作するためのwebdriverを設定 options = Options() options.add_argument("--headless") driver = webdriver.Chrome(options=options) wait = WebDriverWait(driver=driver, timeout=30) # 最大待ち時間の設定 # ブラウザを起動し、URLにアクセス driver.get(url) wait.until(EC.presence_of_all_elements_located) # HTMLの要素が全てレンダリングされるまで待つ # HTMLの要素を取得 elem = driver.find_element(By.CSS_SELECTOR, "div.introduction") print(elem.text) # ブラウザを閉じる driver.close()
# 実行結果 Python is a programming language that lets you work quickly and integrate systems more effectively. Learn More
問題なく動作していることを確認できました!
要素の取得方法について、更に詳細は次の記事でメモしておきます。
参考にさせていただいた記事
- https://qiita.com/memakura/items/20a02161fa7e18d8a693
- https://selenium-python.readthedocs.io/getting-started.html#simple-usage
- https://yuki.world/python-selenium-quickest-setup/
- https://www.harubears.com/ja/tech-ja/how-to-enable-headlesschrome-with-python/
- https://office54.net/python/scraping/selenium-wait-time