このドキュメントは、LuaWebDriverの使い方を段階的に説明しています。まだ、LuaWebDriverをインストールしていない場合は、このドキュメントを読む前にLuaWebDriverをインストールしてください。
Session:navigate_to
を使って、Webブラウザーで特定のWebサイトへアクセスできます。
まず最初に、Webサイトへアクセスするためのコールバック関数を作成します。
Session:navigate_to
の引数としてURLを指定します。
次に、Firefox:start_session
の引数としてコールバックを指定し、Firefox:start_session
を呼び出します。
セッションはコールバックを呼び出した後、自動的に破棄されます。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL = "https://clear-code.gitlab.io/lua-web-driver/sample/"
-- コールバックの作成とセッションの開始
driver:start_session(function(session)
session:navigate_to(URL)
end)
Session:xml
を使ってWebサイトをXMLとしてシリアライズできます。
まずはじめに、以下の例のようにシリアライズするWebサイトへアクセスします。
次に、Session:xml
を呼び出します。
そうすると、現在のWebサイトをXMLとしてシリアライズできます。このXMLはLuaの文字列として使えます。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/"
-- コールバックの作成とセッションの開始
driver:start_session(function(session)
session:navigate_to(URL)
-- 現在のWebサイトをXMLとしてシリアライズする
local xml = session:xml()
print(xml)
end)
Session:save_screenshot
を使って現在のWebサイトのスクリーンショットを取得できます。
スクリーンショットは、PNG形式で取得されます。
まずはじめに、以下の例のようにスクリーンショットを取得するWebサイトへアクセスします。
次に、Session:save_screenshot
を呼び出します。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/"
driver:start_session(function(session)
session:navigate_to(URL)
-- PNG形式でスクリーンショットを保存します
session:save_screenshot("sample.png")
end)
以下の機能を使って、Webサイトの移動ができます。
この例では、ログインして、リンクをクリックしてテキストを取得します。
まず最初に、対象のWebサイトへアクセスします。
次にこのWebサイトは認証が必要なので、ユーザー名とパスワードを入力します。
Session:css_select
とElementSet:send_keys
を使ってユーザー名とパスワードを入力できます。
ユーザー名とパスワードを入力するための要素をSession:css_select
を使って取得します。
この例では、CSSセレクターを使って要素を取得していますが、Session:xpath_search
でXpathを使った取得もできます。
次に、取得した要素オブジェクトのElementSet:send_keys
を呼び出します。ElementSet:send_keys
の引数には、入力文字列を指定します。
次に、Session:css_select
とElementSet:click
でログインボタンを押します。
次に、Session:link_search
とElementSet:click
を使ってログインした後のWebサイトのリンクをクリックします。
次に、ElementSet:text
で移動後のWebサイトの特定の要素のテキストを取得します。
Session:css_select
を使って、テキストを取得する要素を取得します。
取得した要素のElementSet:text
を呼び出します。
取得したテキストの値はLuaの文字列として使えます。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/move.html"
-- コールバックの作成とセッションの開始
driver: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())
end)
Session:css_select
とElementSet:click
を使って、特定のフォームのボタンを操作できます。
まずはじめに、以下の例のようにボタンを操作するWebサイトへアクセスします。
次に、Session:css_select
を使って、ボタン操作をするための要素オブジェクトを取得します。
この例では、CSSセレクターで取得していますが、XPathを使って取得することもできます。
次に、取得した要素オブジェクトのElementSet:click
を呼び出します。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/button.html"
-- コールバックの作成tおセッションの開始
driver:start_session(function(session)
session:navigate_to(URL)
-- ボタン操作をするための要素を取得
local elements = session:css_select('#announcement')
-- 取得したボタンをクリック
elements:click()
-- 移動後のWebサイトの要素のテキストを取得
elements = session:css_select('a[name=announcement]')
local informations_summary = elements:texts()
for _, summary in ipairs(informations_summary) do
print(summary)
end
end)
ElementSet:send_keys
を使って、特定のフォームに文字列を入力できます。
まずはじめに、フォームに文字列を入力するWebサイトへアクセスします。
次に、Session:css_select
を使って、文字列を入力するための要素オブジェクトを取得します。この例では、CSSセレクターで取得していますが、XPathを使って取得することもできます。
次に、取得した要素オブジェクトのElementSet:send_keys
を呼び出します。ElementSet:send_keys
の引数には、入力文字列を指定します。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/index.html"
-- コールバックの作成とセッションの開始
driver:start_session(function(session)
session:navigate_to(URL)
-- 文字列を入力するための要素を取得
local elements = session:css_select('input[name=name]')
-- フォームに文字列を入力
elements:send_keys("This is test")
print(elements[1].value)
end)
Element:get_attribute
を使って特定の要素の属性を取得できます。
まずはじめに、Session:css_select
を使って、属性を取得するための要素オブジェクトを取得します。
次に、取得した要素オブジェクトのElement:get_attribute
を呼び出します。Element:get_attribute
の引数には、属性名を指定します。取得した属性値は、Luaの文字列として使えます。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/get-attribute.html"
-- コールバックの作成とセッションの開始
driver:start_session(function(session)
session:navigate_to(URL)
-- 属性取得するための要素を取得
local elements = session:css_select('p')
for _, element in ipairs(elements) do
-- 取得した要素の属性を取得
if element["data-value-type"] == "number" then
print(element:text())
end
end
end)
ElementSet:text
を使って特定の要素のテキストを取得できます。
まずはじめに、Session:css_select
を使って、テキストを取得するための要素オブジェクトを取得します。
次に、取得した要素オブジェクトのElementSet:text
を呼び出します。取得したテキストの値は、Luaの文字列として使えます。
例:
local web_driver = require("web-driver")
local driver = web_driver.Firefox.new()
local URL = "https://clear-code.gitlab.io/lua-web-driver/sample/"
-- コールバックの作成とセッションの開始
driver:start_session(function(session)
session:navigate_to(URL)
-- テキストを取得するための要素を取得
local element_set = session:css_select('#p2')
-- 取得した要素のテキストを取得
local text = element_set:text()
print(text)
end)
web-driver.Firefox.new()
のオプションを使って、Webブラウザのユーザーエージェントをカスタマイズできます。この機能は、例えば、スマートフォン用のWebサイトをクローリングする時に有用です。
まず始めに、options.preferences
にユーザーエージェントを文字列として設定します。
次に、そのoptions
をweb-driver.Firefox.new()
の引数に設定して呼び出します。
ここでは、iPhoneのユーザーエージェントへカスタマイズする例を示します。
例:
local web_driver = require("web-driver")
local user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X)"..
" "..
"AppleWebKit/602.3.12 (KHTML, like Gecko)"..
" "..
"Version/10.0 Mobile/14C92 Safari/602.1"
local options = {
preferences = {
["general.useragent.override"] = user_agent,
}
}
local driver = web_driver.Firefox.new(options)
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/"
driver:start_session(function(session)
session:navigate_to(URL)
print(session:request_headers()["User-Agent"])
-- Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1
end)
LuaWebDriverをマルチスレッドで使う場合は、以下の例のように、web-driver.ThreadPool.new()
の引数にoptions.preferences
を設定することでユーザーエージェントをカスタマイズできます。
local web_driver = require("web-driver")
local log = require("log")
local url =
"https://clear-code.gitlab.io/lua-web-driver/sample/"
local log_level = "info"
local n_threads = 2
local logger = log.new(log_level)
local function crawler(context)
local logger = context.logger
local session = context.session
local url = context.job
local prefix = url:match("^https?://[^/]+/")
logger:debug("Opening...: " .. url)
session:navigate_to(url)
local status_code = session:status_code()
if status_code and status_code ~= 200 then
logger:notice(string.format("%s: Error: %d",
url,
status_code))
return
end
logger:notice(string.format("%s: Title: %s",
url,
session:title()))
local anchors = session:css_select("a")
local anchor
for _, anchor in pairs(anchors) do
local href = anchor.href
local normalized_href = href:gsub("#.*$", "")
logger:notice(string.format("%s: Link: %s (%s): %s",
url,
href,
normalized_href,
anchor:text()))
if normalized_href:sub(1, #prefix) == prefix then
context.job_pusher:push(normalized_href)
end
end
end
local user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X)"..
" "..
"AppleWebKit/602.3.12 (KHTML, like Gecko)"..
" "..
"Version/10.0 Mobile/14C92 Safari/602.1"
local options = {
logger = logger,
size = n_threads,
firefox_options = {
preferences = {
["general.useragent.override"] = user_agent,
},
}
}
local pool = web_driver.ThreadPool.new(crawler, options)
logger.debug("Start crawling: " .. url)
pool:push(url)
pool:join()
logger.debug("Done crawling: " .. url)
LuaWebDriverはロガーにlua-log
を使っています。
呼び出し元で作成したロガーオブジェクトをweb-driver.Firefox.new()
の引数に渡すことで、呼び出し元と同じロガーオブジェクトを使えます。
使用できるログレベルは以下です。
上記のログレベルは文字列として指定します。
例:
local web_driver = require("web-driver")
local log = require("log")
local logger = log.new("trace")
local options = { logger = logger }
local driver = web_driver.Firefox.new(options)
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/"
driver:start_session(function(session)
session:navigate_to(URL)
end)
LuaWebDriverをマルチスレッドで使う場合は、web-driver.ThreadPool.new()
の引数にロガーオブジェクトを渡します。
例:
local web_driver = require("web-driver")
local log = require("log")
local url =
"https://clear-code.gitlab.io/lua-web-driver/sample/"
local log_level = "trace"
local n_threads = 2
local logger = log.new(log_level)
local function crawler(context)
local logger = context.logger
local session = context.session
local url = context.job
local prefix = url:match("^https?://[^/]+/")
logger:debug("Opening...: " .. url)
session:navigate_to(url)
local status_code = session:status_code()
if status_code and status_code ~= 200 then
logger:notice(string.format("%s: Error: %d",
url,
status_code))
return
end
logger:notice(string.format("%s: Title: %s",
url,
session:title()))
local anchors = session:css_select("a")
local anchor
for _, anchor in pairs(anchors) do
local href = anchor.href
local normalized_href = href:gsub("#.*$", "")
logger:notice(string.format("%s: Link: %s (%s): %s",
url,
href,
normalized_href,
anchor:text()))
if normalized_href:sub(1, #prefix) == prefix then
context.job_pusher:push(normalized_href)
end
end
end
local options = {
logger = logger,
size = n_threads,
}
local pool = web_driver.ThreadPool.new(crawler, options)
logger.debug("Start crawling: " .. url)
pool:push(url)
pool:join()
logger.debug("Done crawling: " .. url)
以下のように環境変数でログレベルを設定することもできます。
例:
export LUA_WEB_DRIVER_LOG_LEVEL="trace"
環境変数もロガーオブジェクトも設定しない場合、LuaWebDriverは、Firefoxとgeckodriverのログを"info"レベルで出力します。
複数のスレッドでLuaWebDriverを使えます。LuaWebDriverを複数のスレッドで使うためには、以下のようにweb-driver.ThreadPool
オブジェクトを使う必要があります。
以下の例では、web-driver.ThreadPool:push()
の引数に与えられたURLを起点にWebページをクロールします。
例:
local web_driver = require("web-driver")
local log = require("log")
local URL =
"https://clear-code.gitlab.io/lua-web-driver/sample/"
local log_level = "notice"
local logger = log.new(log_level)
local function crawler(context)
local web_driver = require("web-driver")
local logger = context.logger
local session = context.session
local url = context.job
local prefix = url:match("^https?://[^/]+/")
logger:debug("Opening...: " .. url)
session:navigate_to(url)
logger:notice(string.format("%s: Title: %s",
url,
session:title()))
local anchors = session:css_select("a")
local anchor
for _, anchor in pairs(anchors) do
local href = anchor.href
local normalized_href = href:gsub("#.*$", "")
logger:notice(string.format("%s: Link: %s (%s): %s",
url,
href,
normalized_href,
anchor:text()))
if normalized_href:sub(1, #prefix) == prefix then
context.job_pusher:push(normalized_href)
end
end
end
local pool = web_driver.ThreadPool.new(crawler, {logger = logger})
logger.debug("Start crawling: " .. URL)
pool:push(URL)
pool:join()
logger.debug("Done crawling: " .. URL)
web-driver.ThreadPool.new()
の引数に与えられた関数内に実行したい処理を書くことができます。
web-driver.ThreadPool.new()
の引数に与えられた関数内でweb-driver.JobPusher:push()
(上の例では、context.job_pusher:push()
です。)を呼び出すことによって、空いているスレッドがジョブを順に処理します。
web-driver.ThreadPool.new()
の引数に与えられる関数の引数の数は1つです。(上の例で、web-driver.ThreadPool.new()
の引数に与えられる関数はcrawler
です。)
この引数は、Webページをクロールするための情報が入っています。(上の例では、この引数はcontext
です。)
同じジョブを登録した場合、LuaWebDriverはデフォルトで同じジョブを無視します。
ジョブは、文字列のみ受け取れます。ジョブには、URLを与えることをおすすめします。
失敗したジョブは自動的にリトライします。リトライ回数はデフォルトで3回です。
以下のようにweb-driver.ThreadPool.new()
の引数として、リトライ回数を指定することもできます。
例:
local pool = web_driver.ThreadPool.new(crawler, {max_n_failures = 5})
LuaWebDriverを複数のスレッドで使うには、以下のような注意が必要です。
libpthread.so
をLD_PRELOAD
に指定することで解消する可能性があります。web-driver.ThreadPool.new()
の引数として与えられる関数は、その関数の外部の情報を参照してはいけません。
luajit
プロセスを途中で終了した場合、ジョブは最初から実行されます。ジョブの重複チェックもリセットされます。web-driver.ThreadPool:join()
内で各スレッドの終了処理を実行しているためです。これで、LuaWebDriverのすべての主な機能を学びました!それぞれの機能をより理解したい場合は、各機能のリファレンスマニュアルを見てください。