[Python3]Seleniumでスクレピング。基本操作、問題に陥った時の対応策のまとめ

[Python3]Seleniumでスクレピング。基本操作、問題に陥った時の対応策のまとめ

この記事は、2020年3月2日に編集し、約 6 分で読めます。

ども、KANEです。

最近スクレピング案件が増え、どんどんSeleniumの知識が増えている今日この頃、、

今回はそんな培ったスクレピング知識、困ったときの対応策などを記事にしてまとめてみました!

Seleniumとは

Selenium は、Web ベースアプリケーションのテスト自動化の高速開発をサポートした堅牢なツール群です。Selenium は、Web アプリケーションのテストニーズに特化したテスト機能を豊富に備えています。テスト操作の柔軟性は高く、UI 要素を特定したり、テストの期待値と実際のアプリケーションの動作を比較したりするための多数のオプションを利用できます。
(oss.infoscience.co.jp/seleniumhq/docs/01_introducing_selenium.htmlより引用)

元々はテスト自動化のためのツールだったようで、柔軟にカスタマイズができることからスクレピングする上で非常に有効なツールです。
ブラウザの要素を操作し、データ取得、ページ遷移などさまざまな動きをすることができます。またサポートしているブラウザも多く

  • Firefox 2~3
  • IE 7~8
  • Safari 2~3
  • Opera 8~9
  • Google Chrome

などがあります。

簡単なスクレピング例

今回はPython3+Selenium+Chromeブラウザを使ってI-SEEDブログを自動操作、スクレピングしてみたいと思います。

環境

  • Ubuntu 18.04.3
  • Python 3.6.9
  • selenium 3.141.0
  • chrome 79.0.3945.88
  • chromedriver 78.0.3904.70
  • chromedriver_binary 78.0.3904.70.0

chromedriver_binaryはchromedriverのパスを自動で通してくれます。

準備

seleniumにはChromeブラウザのバージョンにあったchromedriverインストール必要があります。

またchromedriver_binaryもchromedriverと同じバージョンでインストールしてください。

$ pip install selenium
$ pip install chromedriver_binary

実践


import chromedriver_binary from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument('--headless') #ヘッドレスで起動する driver = webdriver.Chrome(options=options) driver.get('https://iseed.jp/blog/') #ページ遷移 driver.save_screenshot("./iseed-blog.png") #現在のページをスクリーンショットする text = driver.find_element_by_xpath('//*[@id="container"]/div[1]/section/div[1]/div/div/h2').text #ページ内の要素を取得 print(driver.title) #ブログ – 株式会社I-SEED(アイシード)|大阪・心斎橋のWEB制作集団 print(text) #BLOG driver.quit()#全てのウィンドウを閉じる

以上のコードだけで、簡単にスクリーンショット、サイトタイトルが取得できます。

コマンドについてはドキュメントに色々記載されているのでここでは割愛します。

次は僕が実際遭遇した問題の対応策をまとめています。

陥った問題・対策

エラーが出たときに、Chromeプロセスが止まらない

Chromeのプロセスが継続して動いていると、コードを修正してChromeを動かしたときに正常に動作してくれない場合があります。


import chromedriver_binary from selenium import webdriver driver = webdriver.Chrome() driver.get('https://iseed.jp/blog/') print(driver.title) print(test) #ここでエラー driver.quit()

このままではdriver.quit()がまで行かず、プロセスが残ります。

 8484 pts/0    00:00:00 chromedriver
 8490 pts/0    00:00:01 chrome <defunct>

killコマンドなどでプロセスを削除して対応はできますが、なにかとめんどくさい。。。

そんなときは例外処理で対応します。

import logging
import chromedriver_binary
from selenium import webdriver

try:
    driver = webdriver.Chrome()
    driver.get('https://iseed.jp/blog/')

    print(driver.title)
    print(test) #ここでエラー

except:
    logging.error("traceback",exc_info=True)

finally:
    driver.quit()

finallyにdriver.quit()をおいて必ず最終的にChromeを終了させます。
エラー内容も見れるようloggingを追加しています。

.textで取得すると文字が空になる

CSSプロパティがdisplay: noneになっているタグなどを取得する際に起きました。

driver.find_element_by_xpath('//*[@id="hoge"]/div[1]/section/div[1]/div/div/h2').text

そんなときは.get_attribute(“textContent”)で回避できます。

driver.find_element_by_xpath('//*[@id="hoge"]/div[1]/section/div[1]/div/div/h2').get_attribute("textContent")

.textではページ上に表示されている(見える)要素しか取得してくれないので、.get_attribute(“textContent”)を使いましょう。

参考:https://qiita.com/riikunn1004/items/68c7621baaa54cf27230

Sleepしすぎて処理が遅い

要素を取得する際にページ遷移など、ページの表示を待たなければならないとき、sleepを使いがちです。
しかし、そのsleepで設定したタイムは余分な時間ができる可能性があります。

そんなときはオプションで予め最大のスリープ時間を設定しましょう。

driver.implicitly_wait(5)

上のコードで各要素が見つかるまで5秒待ちます。

Chromeが重く、メモリクラッシュが起きる

DockerやHerokuからChromeを動かす機会があるときに起こる問題です。
Chromeの処理は非常に重く、デフォルトのDockerやHeorkuではメモリ不足が原因で正常に動作してくれない場合があります。

そんなときには以下のオプションをを追加しましょう。

options.add_argument('--disable-dev-shm-usage')

デフォルトでDockerやHeorkuでは/dev/shmにメモリを使用するようで64MB、512MBでプログラムによっては足りない場合があります。

上のオプションを使用することで/tmpを使用するようになり、メモリ不足を回避できるようです。

終わりに

一応、僕が遭遇した問題に対する解決策をまとめましたが、もっとベストな方法があるはずです。
他にもっといいのがあれば、コメントよろしくお願いします!

システム開発やWebサイトのことでお悩みなら I-SEED にご相談ください!

I-SEED ではWebシステムやスマホアプリなどのシステム開発から、コーポレートサイトやECサイトなどのWeb制作、SEO対策やオウンドメディア構築・運用などのWebマーケティングまで、Webに関するさまざまなお悩みを解決します。

I-SEED では随時採用も行っています。エンジニア、ディレクター、デザイナー、ライター、マーケターなどの職種にご興味がある方は以下のページもご覧ください。

ブログページに戻る