LoginSignup
11
14

More than 5 years have passed since last update.

面倒な社内ルーティンワークをSeleniumとBeautifulSoupで自動化した話

Last updated at Posted at 2018-11-10

概要

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行目で、入力ボックスに値を入力しています。
最後の行で、ログインボタンをクリックしています。

参考

画面が開くのを待機

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'])

参考

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で報告する部分の自動化の方法も載せようと思います。

11
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
14