概要
Seleniumを使ってログインなどの画面操作を行い、その後スクレイピングすることによってWeb上の情報を取得する方法を紹介します。
それぞれの個別の情報はネットで簡単に見つけられるのですが、どう組み合わせるのか少し迷ったので一連の流れを解説します。
全体のコードは最後に記載しています。
経緯
新人の頃、テスト環境のプロダクトのバージョンを確認して報告するというルーティンワークがありました。
確認する対象のプロダクトが結構な数あったため、面倒に思って自動化しようと思ったのがきっかけです。
その時に作ったコードのメイン部分を抜き出しています。
使用技術
以下のツールやライブラリを使用しています。言語はPythonです。
- 画面操作:Selenium、ChromeDrivr
- スクレイピング:BeautifulSoup
- 正規表現:re
必要なライブラリのインポート
from selenium.webdriver import Chrome, ChromeOptions
from bs4 import BeautifulSoup
import re
import time
Driverの設定
options = ChromeOptions()
options.add_argument('--headless')
driver = Chrome(executable_path="/path/to/your/chromedriver",chrome_options=options)
1,2行目で、画面操作をヘッドレスモード(ブラウザを立ち上げずに画面操作する)で行うためのオプションを設定しています。
3行目で、ChromeDriverの実行を行なっています。
操作している様子を見たい場合は、2行目をコメントアウトしてください。
ログイン操作
#URLを開く
driver.get(LOGIN_URL)
#IDで要素を取得し、ユーザとパスワードを入力する
userNameField = driver.find_element_by_id("userId")
userNameField.send_keys(USER)
passwordField = driver.find_element_by_id("password")
passwordField.send_keys(PASS)
submitButton = driver.find_element_by_id("loginBtn")
submitButton.click()
4行目で、HTMLのタグであるIDを指定して入力ボックスの要素を取得します。
SeleniumにはIDタグだけでなく、CLASSタグや、CSSセレクタやxPathで指定できる関数もあるので見てみてください。
5行目で、入力ボックスに値を入力しています。
最後の行で、ログインボタンをクリックしています。
参考
- Selenium Python Bindings 2 ドキュメント
画面が開くのを待機
time.sleep(1)
実はこの書き方、本当はあまりよくないです。理由は以下です。
- 他の実行ファイルがあった場合、sleep関数はそれも停止してしまう
- 無駄な待ち時間が発生して、実行時間が長くなる
今回は他に何も実行していないのと、待つ時間が短い&頻度が少ないためでこの書き方にしましたが、
本来であればSeleniumの
- wait関数
- waitUntil関数
などを使用することをお勧めします。
スクレイピングする
#対象の画面を開く
driver.get(TARGET_URL)
#ソースを取得し、パーサーにかける
data = driver.page_source
soup = BeautifulSoup(data,"lxml")
#対象のソースを絞り込む
target_value = soup.find('meta', content=re.compile('xxx'))
print(target_value)
7行目では、HTMLのmetaタグのcontentの中身にある、xxxに該当する値を取得しています。
BeautifulSoupだけで取れる要素は限界があるため、対象をさらに絞り込むためには正規表現ライブラリであるreを使います。
reを使い慣れている人であれば、以下の方が使いやすいかもしれません。
取得方法が違うだけで、上記の7行目と同じです。お好みでどうぞ。
target_value = re.search('xxx', soup.meta['content'])
参考
- Beautiful Soup Documentation (公式リファレンス)
- PythonとBeautiful Soupでスクレイピング
Driverを終了する
driver.close()
ブラウザが閉じ、Driverが終了します。
コード全体
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from selenium.webdriver import Chrome, ChromeOptions
from bs4 import BeautifulSoup
import re
import time
LOGIN_URL = "xxx"
TARGET_URL = "xxx"
USER = "xxx"
PASS = "xxx"
options = ChromeOptions()
#options.add_argument('--headless')
driver = Chrome(executable_path="/path/to/your/chromedriver", chrome_options=options)
driver.get(LOGIN_URL)
userNameField = driver.find_element_by_id("userId")
userNameField.send_keys(USER)
passwordField = driver.find_element_by_id("password")
passwordField.send_keys(PASS)
submitButton = driver.find_element_by_id("loginBtn")
submitButton.click()
time.sleep(1)
driver.get(TARGET_URL)
data = driver.page_source
soup = BeautifulSoup(data,"lxml")
target_value = soup.find('meta', content=re.compile('xxx'))
print(target_value)
driver.close()
最後に
解説は以上です。間違いや不明な点などあればご指摘ください。
そのうち気が向いたら、Slackで報告する部分の自動化の方法も載せようと思います。