Python × Selenium で自動化

元素周期表の覚え方「水兵リーベ僕の船...」懐かしいですね。
その元素記号の34番目は「Se」(Selenium)です。

一方、ITにおけるSelenium

  1. Webページにアクセスしてログイン

  2. 対象データを検索

  3. 必要な情報を入力して登録

というような、普段Webブラウザで行っている操作を自動化することができます。
PythonでもこのSeleniumを利用することができます。

最新ニュース記事取得

最近気になるニュースは?

就活の面接でも良く聞かれます。選んだニュースにより、その人の感性や価値観、人柄、知的好奇心が分かるので、効果的な質問だと思います。

さて、今回は最新ニュース記事の取得・収集を自動化する方法をご紹介します。(スクレイピングと言われているものです)

1時間毎にGoogleの「AI」最新ニュース記事を取得。それをSlackに投稿し、Excelに保存する。
の流れです。皆さんもサクッと試してみましょう。

1. 初期設定

pipコマンドを使って、Seleniumをインストールします。
$ pip install selenium

Google Chrome版のWebDriverをダウンロードします。
ChromeDriver - WebDriver for Chrome

2. ライブラリの定義

ここからはプログラミングです。
PythonSeleniumを使うために必要なライブラリを定義します。

  • Slackに投稿
  • Excelに保存
  • 定期実行

これらの処理のために必要なライブラリもあわせて定義します。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

import requests
import datetime
import time
import cv2
import openpyxl
import schedule

3. WebDriverのオプション設定

Google Chrome版のWebDriverの設定です。headlessモードにすると、画面表示なしで動作します。自分のPC作業に影響せずに裏で動いてくれるので助かります。

DRIVER_PATH = './chromedriver'
options = Options()
options.add_argument('--headless')
driver = webdriver.Chrome(executable_path=DRIVER_PATH, options=options)

4. 定数の定義

検索キーを変更すれば、別のニュース記事を取得できます。

SearchKey = 'AI' #ニュースの検索キー
Token = 'XXXX-XXXX-XXXX-XXXX' #Slackで取得したトークン
Channel = 'XXXX' #SlackのチャンネルID
Excelfile = 'LatestNews.xlsx' #Excelファイル名

5. メイン処理

URL指定で最初からニュース一覧の画面に遷移させることもできますが、テンプレートとして他でも流用できるようにあえて検索キーを入力しての画面遷移としております!

def job():
  # Googleのページを開く
  driver.get("https://www.google.co.jp/")

  # 検索Boxのelementを取得
  search_box = driver.find_element_by_class_name("gLFyf")

  # 検索Boxにキーを入力
  search_box.send_keys(SearchKey)

  # Enterキーを入力
  search_box.send_keys(Keys.ENTER)

  # Google検索結果画面のニュースタブのelementを取得
  link_news = driver.find_element_by_class_name("q")

  # ニュースタブをクリック
  link_news.click()

  # 最新ニュース記事のリンクのelementを取得
  link_news_latest = driver.find_element_by_class_name("l")

  # 最新ニュース記事のリンクをクリック
  link_news_latest.click()

  # 最新ニュース記事画面の幅と高さを取得(全画面のスクショを撮るため)
  page_width = driver.execute_script('return document.body.scrollWidth')
  page_height = driver.execute_script('return document.body.scrollHeight')

  # 最新ニュース記事画面の幅と高さをセット
  driver.set_window_size(page_width, page_height)

  # 画面読み込みのため待機
  time.sleep(20)

  # 現在日時取得
  dt_now = datetime.datetime.now()
  
  # スクショのファイル名定義
  screenshot_path = "Pictures/" + str(dt_now) + ".png"

  # スクショ保存
  driver.save_screenshot(screenshot_path)

  # スクショのPNG画像を圧縮
  img = cv2.imread(screenshot_path)
  cv2.imwrite(screenshot_path, img, [cv2.IMWRITE_PNG_COMPRESSION, 9])

  # 画面タイトルを取得
  cur_url_title = driver.title

  # 画面URLを取得
  cur_url = driver.current_url

  # Slackに投稿(画面タイトル, 画面URL, スクショ)
  files = {'file': open(screenshot_path, 'rb')}
  param = {
    'token':Token,
    'channels':Channel,
    'initial_comment': SearchKey + "最新ニュース" + "\n\n" + cur_url_title + "\n\n" + cur_url,
    'title': screenshot_path
  }
  requests.post(url="https://slack.com/api/files.upload",params=param, files=files)

  # Excelの最終行に追記(時間, 画面タイトル, 画面URL, 検索キー)
  wb=openpyxl.load_workbook(Excelfile)
  sheet = wb.active
  max_row = sheet.max_row
   
  list = [dt_now, cur_url_title, cur_url, SearchKey]
  for index, item in enumerate(list):
    sheet.cell(row=max_row+1,column=index+1).value = item
  wb.save(Excelfile)

6. 定期実行処理

scheduleライブラリを使用すると手軽にジョブの設定ができます。

# 3分毎に実行
# schedule.every(3).minutes.do(job)
# 1時間毎に実行
schedule.every().hour.do(job)

while True:
  schedule.run_pending()
  time.sleep(1)

以上です!シンプルですね。

最後に

今回は、最新ニュース記事取得(スクレイピング)を例としてご紹介しましたが、WebシステムのUIテスト自動化にも使えます。画面遷移や、項目が多い入力フォームの検証にはもってこいです。単純な繰り返し作業はSeleniumにお任せしちゃいましょう!

株式会社ブリスウェル