LoginSignup
125
113

More than 5 years have passed since last update.

Nodejsを使ってSeleniumでChromeを動かす

Posted at

はじめに

Seleniumとは、WebアプリケーションのUIテストツール。
動的なサイトのスクレイピングツールとしても使われている。
今回はSeleniumをNode.jsで動かす方法を紹介する。

ドキュメント(英語版)

使用方法

事前準備(Windowsの場合)

インストール

npm i selenium-webdriver

ChromeDriverのダウンロード

ChromeDriver – WebDriver for Chrome
https://sites.google.com/a/chromium.org/chromedriver/downloads
実行ファイルと同じパスに配置

基本操作

ライブラリのインポート

const webdriver = require('selenium-webdriver');
const { Builder, By, until } = webdriver;

良く使うBuilder, By, untilをここで定義

設定(Chromeの場合)

const capabilities = webdriver.Capabilities.chrome();
capabilities.set('chromeOptions', {
    args: [
        '--headless',
        '--no-sandbox',
        '--disable-gpu',
        `--window-size=1980,1200`
        // other chrome options
    ]
});

Chrome Options

ブラウザの立ち上げ

const driver = await new Builder().withCapabilities(capabilities).build();
// ブラウザを終了する
driver.quit();

※基本的に返り値がpromiseなので、async/awaitを使う

ページ移動

await driver.get('https://www.youtube.com/');

要素の特定


// タグ名で特定
let el1 = await driver.findElement(By.tagName('hoge'));
let el2 = await driver.findElement({ tagName: 'hoge' });

// idで特定
let el1 = await driver.findElement(By.id('foo'));
let el2 = await driver.findElement({ id: 'foo' });

// classで特定
let el1 = await driver.findElement(By.className('bar'));
let el2 = await driver.findElement({ className: 'bar' });

// cssセレクタで特定
let el1 = await driver.findElement(By.css('#foo'));
let el2 = await driver.findElement({ css: '#foo' });

// 複数要素の特定
let els1 = await driver.findElements(By.css('.bar'));
let els2 = await driver.findElements({ css: '.bar' });

要素から属性の取得


let el = await driver.findElement(By.css('#foo'));

// テキストを取得
let text = await el.getText();
// ↑だとなぜか動かない場合はこちら
let innerHTML = await el.getAttribute('innerHTML');

// その他属性の取得
let href = await el.getAttribute('href');

応用編

待ち処理

/**
 * xxx:関数名
 * timeout:タイムアウト時間(ミリ秒)
 */
await driver.wait(until.xxx(), timeout);

要素の出現

// 要素の出現を待つ
await driver.wait(until.elementLocated(By.id('foo')), 10000);
await driver.wait(until.elementsLocated(By.className('bar')), 10000);

URL条件

// 完全一致
await driver.wait(until.urlIs('xxx'), 10000);

// 部分一致
await driver.wait(until.urlContains('xxx'), 10000);

// 正規表現
await driver.wait(until.urlMatches(/xxx/), 10000);

タイトル条件

// 完全一致
await driver.wait(until.titleIs('xxx'), 10000);

// 部分一致
await driver.wait(until.titleContains('xxx'), 10000);

// 正規表現
await driver.wait(until.titleMatches(/xxx/), 10000);

特定要素のテキスト条件

let el = await driver.findElement(By.css('#foo'));

// 完全一致
await driver.wait(until.elementTextIs(el, 'xxx'), 10000);

// 部分一致
await driver.wait(until.elementTextContains(el, 'xxx'), 10000);

// 正規表現
await driver.wait(until.elementTextMatches(el, /xxx/), 10000);

要素の状態

let el = await driver.findElement(By.css('#foo'));

// enabled
await driver.wait(until.elementIsEnabled(el), 10000);

// disabled
await driver.wait(until.elementIsDisabled(el), 10000);

// selected
await driver.wait(until.elementIsSelected(el), 10000);

// not selected
await driver.wait(until.elementIsNotSelected(el), 10000);

// visible
await driver.wait(until.elementIsVisible(el), 10000);

// not visible
await driver.wait(until.elementIsNotVisible(el), 10000);

スクリーンショットを撮る

// スクリーンショット画像をbase64でエンコードしたもの
let base64 = await driver.takeScreenshot();

// bufferに変換
let buffer = Buffer.from(base64, 'base64');

サンプル

Youtubeのスクリーンショットを撮るサンプル

sample.js
const fs = require('fs');
const { promisify } = require('util');
const webdriver = require('selenium-webdriver');
const { Builder, By, until } = webdriver;

const capabilities = webdriver.Capabilities.chrome();
capabilities.set('chromeOptions', {
    args: [
        '--headless',
        '--no-sandbox',
        '--disable-gpu',
        `--window-size=1980,1200`
    ]
});

// awaitを使うので、asyncで囲む
(async () => {

    // ブラウザ立ち上げ
    const driver = await new Builder().withCapabilities(capabilities).build();

    // Youtubeへ移動
    await driver.get('https://www.youtube.com/');

    // 検索ボックスが表示されるまで待つ
    await driver.wait(until.elementLocated(By.id('search')), 10000);

    let base64 = await driver.takeScreenshot();
    let buffer = Buffer.from(base64, 'base64');

    // bufferを保存
    await promisify(fs.writeFile)('screenshot.jpg', buffer);

    // ブラウザ終了
    driver.quit();

})();
125
113
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
125
113