ククログ

株式会社クリアコード > ククログ > WebDriver APIを使ったLua用のWebブラウザー自動操作ライブラリー LuaWebDriver

WebDriver APIを使ったLua用のWebブラウザー自動操作ライブラリー LuaWebDriver

WebDriver APIを使ってWebブラウザーを自動操作できるLuaのライブラリーを開発しました。LuaWebDriverといいます。 これは、クリアコードが株式会社セナネットワークス様からの発注を受けて開発したライブラリーです。MITライセンスで公開しています。

LuaWebDriverではWebDriver APIを使って、LuaからWebブラウザーを操作することができます。Webブラウザーはデフォルトでヘッドレスモードで起動します。(GUIでの起動もできます。)

Webブラウザーを利用してWebサイトをレンダリングするため、JavaScriptを使用して動的に生成されるWebページをスクレイピングすることや、HTMLのパーサーライブラリ等で解釈できないような正しくないHTMLで書かれたWebページのスクレイピング等に使用できます。(正しくないHTMLで書かれたWebページもWebブラウザーはなんとか表示するため。) また、Webブラウザーを操作できるので、ログインが必要なページに対して、ログインし、ログイン後のWebページをスクレイピングするようなこともできます。

対応環境

本記事執筆時点でのLuaWebDriverの対応OSと対応Webブラウザーは以下の通りです。

  • 対応OS
    • CentOS 7
    • macOS
  • 対応Webブラウザー
    • Mozilla Firefox

上記以外のOS(Windows)、上記以外のWebブラウザー(Google Chromeなど)には未対応となっています。 他の環境でも使えるように改良していただけた場合には、開発プロジェクトへマージリクエストをいただけましたら幸いです。

インストール方法

LuaWebDriverは、LuaRocksで公開しており、luarocksコマンドを使ってインストールできます。 また、Firefoxを操作するためにgeckodriverを使っているため、本ライブラリーの他にgeckodriverのインストールも必要です。

例えば、CentOS 7では、以下のようにインストールします。

% yum install -y gcc gcc-c++ firefox lua-devel luajit-devel luarocks make openssl-devel
% curl -L -O https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-linux64.tar.gz
% tar xf geckodriver-v0.23.0-linux64.tar.gz -C /usr/local/bin
% chmod +x /usr/local/bin/geckodriver
% sudo luarocks install web-driver

CentOS 7以外のインストール方法は、LuaWebDriverのドキュメントのインストールを参照してください。

基本的な使い方

LuaWebDriverを使ってFirefoxを操作するには、web-driver.Firefoxクラスのオブジェクトが必要です。 web-driver.Firefoxクラスのオブジェクトは以下のように作成します。

local Firefox = require("web-driver/firefox")
local firefox = Firefox.new()

web-driver.Firefoxクラスのオブジェクト作成時には、様々なオプションが設定できますが、ここでは、わかりやすさのため、オプションは設定せず、全てデフォルト値で実行します。 設定可能なオプションについては、web-driver.Firefoxクラスのリファレンスを参照してください。

web-driver.Firefoxクラスのオブジェクトを作成しました。次は、作成したオブジェクトを使って、Firefoxを起動し、操作します。 Firefoxの起動と操作は、web-driver.Firefox:start_session()を使って行います。

web-driver.Firefox:start_session()は引数にコールバック関数を指定でき、LuaWebDriverは、Firefox起動後、引数に指定されたコールバック関数を実行します。このweb-driver.Firefox:start_session()の引数に与えるコールバック関数内にFirefoxを操作して実行したい処理を実装します。

例えば、指定したURLのWebサイトへアクセスする場合は以下のように実装します。

local Firefox = require("web-driver/firefox")
local firefox = Firefox.new()

local URL = "https://clear-code.gitlab.io/lua-web-driver/sample/"

-- コールバックの作成とセッションの開始
firefox:start_session(function(session)
  -- 指定したURLのWebサイトへアクセス
  session:navigate_to(URL)
end)

コールバック関数の引数には、起動したFirefoxとのセッションがweb-driver.Sessionクラスのオブジェクトとして渡されます。 このオブジェクトを使って、ブラウザーの操作を実装します。 Webサイトへのアクセスは、web-driver.Session:navigate_to()を使って行います。このメソッドの引数にアクセスしたいWebサイトのURLを指定すると、そのURLへアクセスできます。

Webサイトへのアクセス以外の操作については、web-driver.Sessionクラスのリファレンスに記載がありますので、合わせて参照してください。

主な機能

LuaWebDriverの主な機能を紹介します。 LuaWebDriverを使うとLuaで以下のようなことができます。

Webサイトへのログイン、ページ内のリンククリック

ここでは、ログインが必要なWebサイトへアクセスし、ログインを実施、ログイン後のページ内のリンクをクリックしてWebページを移動、移動後のページの要素のテキストを取得する例を示します。 少し複雑な例ですが、Webサイトの操作によく使う機能を紹介できるので、このような例にしました。

ログインの実行やリンククリックを行うには、特定のフォームへのテキスト入力、ボタン操作、リンクのクリック操作が必要です。 LuaWebDriverでは、これらを、web-driver.Session:css_selectweb-driver.ElementSet:send_keys()web-driver.ElementSet:click()web-driver.Session:link_search()というメソッドで実現します。

具体的な使い方は、以下の実装例を使って説明します。

local Firefox = require("web-driver/firefox")
local firefox = Firefox.new()

local URL =
  "https://clear-code.gitlab.io/lua-web-driver/sample/move.html"

-- コールバックの作成とセッションの開始
firefox:start_session(function(session)
-- ログインが必要なページへアクセス
  session:navigate_to(URL)

-- Webサイト内のフォームを取得
  local form = session:css_select('form')
-- ユーザー名を入力するためのフォームを取得
  local text_form = form:css_select('input[name=username]')
-- フォームにユーザー名を入力
  text_form:send_keys("username")
-- パスワードを入力するためのフォームを取得
  local password_form = form:css_select('input[name=password]')
-- フォームにパスワードを入力
  password_form:send_keys("password")

-- ユーザー名とパスワードを送信するためのボタンを取得
  local button = form:css_select("input[type=submit]")
-- ユーザー名とパスワードを送信
  button:click()

-- リンク操作をするための要素オブジェクトを取得
  local link = session:link_search("1")
-- リンクをクリック
  link:click()
  local elements = session:css_select("p")
-- 取得した要素のテキストを取得
  print(elements:text())
-- 1
end)
ログイン

まずは、web-driver.Session:css_select()を使って、ユーザー名を入力するフォームを取得します。 web-driver.Session:css_select()は、CSSセレクターを用いて取得したい要素を指定できます。上記例では、input[name=username]としているので、name属性がusernameとなっているinput要素を取得します。

取得した結果は、web-driver:ElementSetクラスのオブジェクトとして返ってきます。 返ってきたオブジェクトを使って、web-driver:ElementSet:send_keys()を実行します。このメソッドは、取得した要素に対して指定したテキストを入力します。上記例では、取得したinput要素にusernameという文字列を入力しています。 これで、ユーザー名の入力は完了です。

次にパスワードの入力を実施します。パスワードの入力もユーザー名の入力と同様web-driver.Session:css_select()を使ってinput要素を取得し、取得したinput要素に対して、web-driver.ElementSet:send_keys()を使ってパスワードを入力します。

ユーザー名とパスワードの入力が完了したら、次は、ユーザー名とパスワードを送信するために送信ボタンを押下します。 送信ボタンの押下は、web-driver.Session:css_select()を使って、送信ボタンを取得します。ボタンの押下は、web-driver.ElementSet:click()を使います。

ここまでで、ユーザー名とパスワードを入力し、それらを送信しました。 入力したユーザー名とパスワードに間違いがなければ、ログイン成功し、ログイン後のページヘ遷移します。

リンク先のページへ遷移

次は、ログイン後のページ内のリンクをクリックし、別のページへ遷移します。 ページ内のリンクを取得するには、web-driver.Session:link_search()を使います。このメソッドの引数にa要素のname属性の値を指定します。 上記の例では、リンクテキストが「1」のリンクを取得しています。取得したリンクをクリックするには、web-driver.ElementSet:click()を使います。 これで、リンク先のページへ遷移します。

ページ内のテキストを取得

リンク先のページへ遷移後は、ページ内要素を取得し、その要素のテキストを取得します。 要素の取得は、今までと同様、web-driver.ElementSet:css_select()で取得します。 取得した要素のテキストを取得するには、web-driver.ElementSet:text()を使用します。web-driver.ElementSet:text()は要素のテキストを文字列として返します。 上記の例では、遷移後のページのp要素のテキストを取得し、printを使ってテキストを標準出力に出力しています。

このようにして、LuaWebDriverでは、Webブラウザーを操作し、必要なページや要素へアクセスしその値を取得することができます。 今回の例では、要素の取得にCSSセレクターを使いましたが、XPathなどその他の方法で検索、取得することもできます。 CSSセレクター以外の取得方法については、web-driver.Searchableモジュールのリファレンスに記載しています。

終わりに

LuaWebDriverの基本的な使い方と主な機能を紹介しました。ここで紹介した機能以外にも便利な機能があります。 LuaWebDriverのその他の機能については、以下のドキュメントを参照して下さい。

チュートリアル リファレンス

このライブラリーは、XMLuaLuaCSと同様株式会社セナネットワークス様からの依頼を受けて開発した受託開発の成果物です。

成果物をフリーソフトウェアとして公開すると、様々なユーザーがライブラリーを使うことによって、いままで気が付かなかったバグを発見できたり、ユーザーからの要望によって、当初想定していなかった、便利な新機能を実装するきっかけとなったり、様々なメリットがあます。

このように成果物の公開によって、ライブラリーの品質も高まるので、お客さんにとっても成果物を公開するメリットがあります。

ご依頼主の株式会社セナネットワークス様には、上記のようなメリットにご理解をいただき、成果を公開できました。ありがとうございます!