前置き
いろいろな言語でSeleniumを最低限動かせるようになってみようという勉強のメモです。
今回はNode.js、TypeScript、CoffeeScriptを試してみました。
書き手は普段RubyでSeleniumを使うことが多く、ときどきVB、Javaの他、C#やScalaで書くこともあります。(Scalaに入門したときに書いた記事)
Node.jsは多少読み書きの経験あり、TypeScriptは初めまして、CoffeeScriptはだいぶ昔に軽く勉強した程度です。
このメモでは、Macへの各環境のインストールから、SeleniumでHeadless Chromeを操作してQiitaのサイトへアクセスし、キーワード "selenium" で検索してすべての検索結果数のバッジの値を取得するコードの実行までの手順をまとめます。
環境
- OS: Mac OS X 10.14.3 Mojave
- Homebrew: 2.1.4-67-gc95cf90
- nodebrew: 1.0.1
- Node.js: v12.4.0
- npm: 6.9.0
- TypeScript: 3.5.1
- CoffeeScript: 2.4.1
- selenium-webdriver: 4.0.0-alpha.1
- @types/selenium-webdriver: 4.0.0
- Google Chrome: 75.0.3770.80(Official Build)
- ChromeDriver: 75.0.3770.8
Homebrewの環境は構築済みであることを前提とします。
準備
ChromeDriverのインストール
Homebrewでchromedriverをインストールします。
$ brew tap homebrew/cask
$ brew cask install chromedriver
$ chromedriver -v
ChromeDriver 75.0.3770.8 (681f24ea911fe754973dda2fdc6d2a2e159dd300-refs/branch-heads/3770@{#40})
以前はbrew installでchromedriverをインストールできましたが、現在はcaskを使うようになっています。
Node.jsのインストール
今回はNode.jsのバージョン管理にnodebrewを使用します。
Homebrewでnodebrewをインストール後、nodebrewでNode.jsをインストールします。
npmも最新の状態にしておきます。
$ brew install nodebrew
$ nodebrew setup
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
$ nodebrew install stable
$ nodebrew use stable
$ node -v
v12.4.0
$ npm install -g npm
$ npm -v
6.9.0
各言語でSeleniumを実行
Node.js
selenium-webdriverのインストール
npmでselenium-webdriverをインストールします。
$ mkdir ~/selenium-nodejs; cd $_
$ npm init -y
$ npm install -D selenium-webdriver
ソースコードの作成
jsファイルを作成し、コードを書いていきます。
$ touch test.js
const { Builder, By, Capabilities, Key, until } = require('selenium-webdriver')
const capabilities = Capabilities.chrome()
// Chrome起動時のオプションを指定
capabilities.set('chromeOptions', {
args: [
'--headless',
'--disable-gpu',
'--window-size=1024,768'
],
w3c: false
})
const search = async (query) => {
// オプション指定ありでChromeを起動
const driver = await new Builder()
.withCapabilities(capabilities)
.build()
try {
// Qiitaのトップページへアクセス
await driver.get('https://qiita.com/')
// 検索欄にキーワードを入力してEnter
await driver
.wait(until.elementLocated(By.name('q')), 5000)
.sendKeys(query, Key.RETURN)
// 検索結果数のバッジの値を取得
const result = await driver
.wait(until.elementLocated(By.className('badge')), 5000)
.getText()
// キーワードと結果の値を出力
console.log(`${query}: ${result}`)
} catch(e) {
console.log(e)
} finally {
// Chromeを終了
driver && await driver.quit()
}
}
search('selenium')
最低限動くコードとしては、このような感じでしょうか。
Selenium公式のドキュメントにもサンプルコードはありますが書き方が古いので、なるべくモダンなJavaScriptっぽくなるように調べながらコーディングしてみました。1
改善の余地はまだまだありますが、それについてはまた別の記事に譲ろうと思います。
ソースコードの実行
$ node test.js
selenium: 2465
2465件2という結果が出力されました。
TypeScript
typescriptとselenium-webdriverのインストール
npmでtypescriptとselenium-webdriverをインストールします。
$ mkdir ~/selenium-typescript; cd $_
$ npm init -y
$ npm install -D typescript selenium-webdriver @types/selenium-webdriver
ソースコードの作成
tsファイルを作成し、コードを書いていきます。
$ touch test.ts
import { Builder, By, Capabilities, Key, until, WebDriver } from 'selenium-webdriver'
const capabilities: Capabilities = Capabilities.chrome()
capabilities.set('chromeOptions', {
args: [
'--headless',
'--disable-gpu',
'--window-size=1024,768'
],
w3c: false
})
async function search(query: string): Promise<void> {
const driver: WebDriver = await new Builder()
.withCapabilities(capabilities)
.build()
try {
await driver.get('https://qiita.com/')
await driver
.wait(until.elementLocated(By.name('q')), 5000)
.sendKeys(query, Key.RETURN)
const result: string = await driver
.wait(until.elementLocated(By.className('badge')), 5000)
.getText()
console.log(`${query}: ${result}`)
} catch(e) {
console.log(e)
} finally {
driver && await driver.quit()
}
}
search('selenium')
tsconfigの作成
コンパイルの設定ファイルを作成します。
$ npx tsc --init
ソースコードのコンパイルと実行
$ npx tsc --target es6
$ node test.js
selenium: 2465
Node.jsとほとんど同じコードで動かせました。
この程度の内容ですとNode.jsとTypeScriptのどちらを使っても大差ない印象ですが、テストフレームワークを使ったり、デザインパターンを適用するなどしてコードの規模が大きくなってくると、TypeScriptのメリットも活きてくるのだろうと思います。
CoffeeScript
coffeescriptとselenium-webdriverのインストール
npmでcoffeescriptとselenium-webdriverをインストールします。
$ mkdir ~/selenium-coffeescript; cd $_
$ npm init -y
$ npm install -D coffeescript selenium-webdriver
ソースコードの作成
coffeeファイルを作成し、コードを書いていきます。
$ touch test.coffee
{ Builder, By, Capabilities, Key, until: Until } = require 'selenium-webdriver'
capabilities = Capabilities.chrome()
capabilities.set('chromeOptions', {
args: [
'--headless',
'--disable-gpu',
'--window-size=1024,768'
],
w3c: false
})
search = (query) ->
driver = await new Builder()
.withCapabilities(capabilities)
.build()
try
await driver.get 'https://qiita.com/'
await driver
.wait(Until.elementLocated(By.name('q')), 5000)
.sendKeys(query, Key.RETURN)
result = await driver
.wait(Until.elementLocated(By.className('badge')), 5000)
.getText()
console.log "#{query}: #{result}"
catch e
console.log e
finally
driver && await driver.quit()
search 'selenium'
requireする際にuntilがCoffeeScriptの予約語になっている点に注意が必要です。
ソースコードのコンパイルと実行
$ npx coffee -c test.coffee
$ node test.js
selenium: 2465
Rubyライクな言語ということもあって個人的には親しみやすいです。
斜陽の時代を迎えている感の強いCoffeeScriptですが、リバイバルしないものでしょうか。3
参考サイト
ソースコード作成にあたり、以下のサイトの記事を特に参考に致しました。
ありがとうございました。
- イマドキのJavaScriptの書き方2018 - Qiita
- 最近のselenium-webdriverの話 - Qiita
- Nodejsを使ってSeleniumでChromeを動かす - Qiita
- TypeScript公式ハンドブック
- CoffeeScript公式リファレンス
- Selenium+Chrome75で全てのオプションが効かない - Qiita