【超便利】PythonとSeleniumでブラウザを自動操作する方法まとめ

こんにちは、ハッカー見習いのたぬ(@tanuhack)です!

Pythonの『Selenium』というライブラリを用いれば、ブラウザを簡単にハックすることができます。

selenium-default
Seleniumの実行サンプル|Googleで『Amazon』と検索して、Chromeを終了させるプログラム

Seleniumを使えば、今まで手作業で行っていた作業を全て、コンピュータに丸投げできる可能性があります。

極論を言えば、ブラウザでやってる全ての作業は、Seleniumで実現可能です。

煩雑な手作業はコンピュータにやらせて、コンピュータが苦手な頭脳活動を仕事で広げたい…!

今回の記事は、Seleniumの導入から私自身がよく使うSeleniumのベストプラクティスまでの総集編です。自分への備忘録も含め、Python初学者の参考になれば嬉しいなと切に願ってます。

[aside]「Seleniumのことは大体分かるから、応用テクニックだけ知りたいわ」という方は、こちらからどうぞ

  1. 時間を遅延させる
  2. ウィンドウを最大化する
  3. 操作するウィンドウを切り替える
  4. テーブルすべてをPandasのデータフレームに格納する
  5. display:none;で隠された要素を表示する
  6. アラートダイアログ・BASIC認証を突破する
  7. 2段階認証プロセスを突破する
  8. reCAPTCHAを突破する
[/aside]

それでは、どうぞ!

開発環境
  • OS:MacOS High Sierra
  • Chrome:70
  • ChromeDriver:2.43
  • Python:3.6.5
  • Jupyter Notebook:4.4.0
[aside]Pythonのインストールがまだ終わってない人は、こちらを参考にインストールしてみて下さい!
[Mac]未経験者向け!Pythonの『導入・初期設定』から『実行』まで紹介 [/aside]

初期設定

PythonでSeleniumを動かすためにする初期設定は2つあります。

この記事を読み進める上での前提条件
  1. Seleniumをインストールする
  2. WebDriverが任意の階層にダウンロードする

Seleniumをインストールする

ターミナル
pip install selenium

WebDriverをダウンロードする

Seleniumを使うには、操作するブラウザに対応したWebDriverのダウンロードが必要です。

今回は、Google Chromeでブラウザの自動操作をしてみましょう。

ということで、Google Chrome用のWebDriverをダウンロードします!

STEP1:Seleniumの公式サイトからWebDriverをダウンロードする

公式サイトからChromeのWebDriverの最新版をダウンロードします。

selenium-default1

Latest Releaseの隣をクリックすると、下の画面に遷移します。

selenium-default2

今回はMacで実行するので、Mac用のドライブをダウンロードします。

STEP2:WebDriverの保存場所を整理する

selenium-default3

今回はデスクトップに『Selenium』というフォルダを新規作成して、その中にSTEP1でダウンロードしたWebDriverを格納します。

以上を持ちまして、PythonでSeleniumを使う初期設定が終わりました。

基本設定

Seleniumモジュールで、実際にブラウザを操作する流れは、下記の5ステップです。

開始
STEP.1
操作したいブラウザを開く
Google Chromeを開きます。
STEP.2
操作したいページを開く
スクレイピングしたいページのURLを設定します。
STEP.3
操作したい要素を指定する
idやclass、cssセレクタで要素を指定します。
STEP.4
指定した要素を操作する
クリックさせたり、テキストを入力させたりします。
STEP.5
ステップ3、4を好きなだけ実行する
行いたい動作をひたすら書きまくります。
終了

Seleniumのプログラムは『操作したいブラウザを指定する』と『操作したいページを開く』を指定し、後は『操作したい要素を指定』と『その要素を操作する』をひたすら書きまくるだけの、あまり頭を使わない簡素なソースコードになります。

# PythonでSeleniumのwebdriverモジュールをインポート
from selenium import webdriver

# 1.操作するブラウザを開く
# /Users/Kenta/Desktop/Selenium/chromedriver
driver = webdriver.Chrome('WebDriverを格納しているディレクトリを指定')

# 2.操作するページを開く
driver.get('URL')

# 基本設定はここまで。↑は使い回し可能。ここから下は、やりたい動作によって増える

# 3.操作する要素を指定

# 4.その要素を操作する

要素を指定する

Seleniumでブラウザ操作をするフロー
  1. 操作したいブラウザを開く
  2. 操作したいページを開く
  3. 操作したい要素を指定する
  4. 指定した要素を操作する

Seleniumを使うときのテンプレの設定が終わったところで、いよいよブラウザ操作にまつわる部分のコードを紹介します。

id・class・name属性で指定する

# id属性で指定する
driver.find_element_by_id('ID')

# class属性で指定する
driver.find_element_by_class_name('CLASS_NAME')

# name属性で指定する
driver.find_element_by_name('NAME')

指定したい要素にIDがあった場合は迷わずIDを選びましょう。何故かと言うと、IDは一意な値なので、確実にその要素を取得することが出来るからです。

WebサイトのIDやclass、nameを調べたいときは、ディベロッパーツール(+option+I)やソースコード(+option+U)を表示すれば出てきます。

Chromeの作業効率3倍アップ!?超強力なショートカットキー10個を厳選してみた

CSSセレクタ・XPathで指定する

# CSSセレクタで指定する
driver.find_elements_by_css_selector('CSSセレクタ')

# XPathで指定する
driver.find_elements_by_xpath('XPath')

id、class、nameがちゃんと設置されてないページでも、CSSセレクタやXPathをゴリゴリ書けば基本的になんでも要素を取得できます。

CSSセレクタやXPathはディベロッパーツールで指定の要素を右クリックすればまるごとコピーできます。

selenium-default4
CSSセレクタ(Copy selector)、XPath(Copy XPath)

リンクテキストで指定する

# 完全一致のリンクテキスト
driver.find_elements_by_link_text('リンクテキスト')

# 部分一致のリンクテキスト
driver.find_elements_by_partial_link_text('リンクテキスト')

完全一致と部分一致について補足します。

次のページに進む』というリンクテキストがあったとすると、完全一致の場合は『driver.find_elements_by_link_text(‘次のページに進む‘)』で取得でき、部分一致の場合は『driver.find_elements_by_partial_link_text(‘進む‘)』だけでも取得できるというわけです。

部分一致の場合『複数あると思わずに、思わぬ挙動をさせてしまう恐れがある』という点だけ注意して使いましょう。

要素を操作する

Seleniumでブラウザ操作をするフロー
  1. 操作したいブラウザを開く
  2. 操作したいページを開く
  3. 操作したい要素を指定する
  4. 指定した要素を操作する

操作する要素を指定した後は、その要素に対してクリックさせたりテキストを入力させたりと、何かしらアクションさせるだけです。

ここでは、ブラウザ操作するときによく使うアクションを紹介します。

前提として、要素はすべてIDで指定しているものとします。

クリックする

# クリックする1
driver.find_element_by_id('ID').click()

# クリックする2
# 『.click()』で何故かクリックできないときは、JavaScriptで無理やりクリックさせます。
element = driver.find_element_by_id('ID')
driver.execute_script("arguments[0].click();", element)

テキストを入力・取得・クリアする

# テキストを入力する
driver.find_element_by_id('ID').send_keys('文字列')

# テキストを取得する
driver.find_element_by_id('ID').text

# 属性値を取得する
driver.find_element_by_id('ID').get_attribute('属性名')

# テキストをクリアする
driver.find_element_by_id('ID').clear()

select要素のoptionを選択・選択解除する

SELECT要素のOPTIONはクリックしても反応しません!

選択する

# Selectタグを操作できるモジュール
from selenium.webdriver.support.ui import Select

# 選択する(value属性)
Select(driver.find_element_id('ID')).select_by_value('VALUE')

# 選択する(index|番号)
Select(driver.find_element_id('ID')).select_by_index(INDEX)

# 選択する(テキスト)
Select(driver.find_element_id('ID')).select_by_visible_text('文字列')

選択解除する

# Selectタグを操作できるモジュール
from selenium.webdriver.support.ui import Select

# 選択解除する(value属性)
Select(driver.find_element_id('ID')).deselect_by_value('VALUE')

# 選択解除する(index|番号)
Select(driver.find_element_id('ID')).deselect_by_index(INDEX)

# 選択解除する(テキスト)
Select(driver.find_element_id('ID')).deselect_by_visible_text('文字列')

# すべて選択解除する
Select(driver.find_element_id('ID')).deselect_all()

ページを操作する

この章では、要素単体ではなく、ページ全体の操作について紹介します。

# 『戻る』ボタンをクリックする
driver.back()

# 『進む』ボタンをクリックする
driver.forward()

# ページをリフレッシュ(リロード)する
driver.refresh()

# ページを閉じる
driver.close()

# ブラウザを終了する (全てのウィンドウを閉じる)
driver.quit()

【応用】その他の実践テクニック

時間を遅延させる

たまに、要素が表示される前にクリックや取得しようとして『そんな要素存在しないよ〜』とエラーを吐かれることがあります。

そんなときは、time.sleep()で遅延させましょう。

import time       #時間を操作するPythonの標準ライブラリ

time.sleep(2) #2秒遅らせる
driver.find_element_by_id('ID').click()

ウィンドウを最大化する

from selenium.webdriver.chrome.options import Options

options = webdriver.ChromeOptions()
options.add_argument('--kiosk')

# Chromeドライバーを読み込んでウィンドウを最大化する
driver = webdriver.Chrome('/Users/'+ user_name +'/Desktop/python/selenium/chromedriver',chrome_options=options)

操作するウィンドウを切り替える

リンクテキストのtarget="_blank"で別ウィンドウに飛ばされたときに使います。

# ウィンドウハンドルを取得する(list型配列)
handle_array = driver.window_handles

# 一番最後に表示されたブラウザにドライバーを切り替える
driver.switch_to.window(handle_array[-1])
[Python]Seleniumで操作するウィンドウを切り替える2つの方法を紹介

テーブルのすべてをPandasのデータフレームに格納する

import pandas as pd

# テーブル内容取得(X列)
try:
    tableElem = driver.find_element_by_id('ID')
    trs = tableElem.find_elements(By.TAG_NAME, 'tr')

    # 配列作成
    tableArray = [[0 for i in range(X)] for j in range(len(trs))]

    # ヘッダ行は除いて取得
    for i in range(len(trs)):
        tds = trs[i].find_elements(By.TAG_NAME, "td")
        line = ""
        for j in range(len(tds)):
            tableArray[i][j]=tds[j].text
            if j < len(tds)-1:
                line += "%s\t" % (tds[j].text)
            else:
                line += "%s" % (tds[j].text)
except Exception as e:
    print(e)

df = pd.DataFrame(tableArray)

display:none;で隠された要素を表示する

# JavaScriptで無理矢理削除する
driver.execute_script('var element=document.getElementById("ID"); element.style.display="";')

アラートダイアログ・BASIC認証を突破する

# アラートダイアログ
from selenium.webdriver.common.alert import Alert

# YESかNOかのダイアログアラートが出現したとき
Alert(driver).accept() # YESを押す
Alert(driver).dismiss() # NOを押す
# BASIC認証を突破する
driver.get('ID:PASSWORD@URL')

2段階認証を突破する

Python+Seleniumで2段階認証(6桁のパスコード)を突破する全手順

reCAPTCHAを突破する

【2Captcha】Python+Seleniumで『reCAPTCHA』を突破する方法

さいごに

今回は、Seleniumの導入方法とよく使う処理をまとめました。

Seleniumを使えば、仕事や趣味を問わず、いろんなことが効率化できます。

[aside]Pythonを定時実行させたい欲張りさんは、この記事をどうぞ!
【保存版】cronでPython3を定時実行する方法&注意すべき4つのポイント [/aside]

人間が行うには下らない単純作業を自動化させ、人生のクオリティを上げていきましょう!!

それでは