devlog

主に web 開発とかプログラミングについて書きます

Node.js でブラウザオートメーション

f:id:nkgr:20180521230949j:plain

TL;DL 🗒

  • Node.js で Selenium-webdriver を使ってブラウザオートメーションを実現する方法
  • 簡単なDOM操作
  • Cookie , Proxy の設定
  • 非同期、同期実行

成果物 🎉

selenium · GitHub

動機 🤔

  • 仕事で使う機会があった
  • Proxy と Cookie の設定は少しだけはまったのでメモとして残す
  • PythonRuby にくらべて Node の例が少ないので 母数 n を増やす

環境 💻

参考リンク

https://seleniumhq.github.io/selenium/docs/api/javascript/index.html

環境構築とブラウザ起動まで ✏️

 

Selenium のダウンロード

今回は Chrome Driver1 を利用

https://sites.google.com/a/chromium.org/chromedriver/downloads

SeleniumChrome Driver がなくても Chrome には Headless モードがあって同じようなことはできるのだけどWindows に対応していないとのことで今回は Selenium を利用。

PATH を通す

ダウンロードした chromedriver の zip ファイルを解凍し 以下のディレクトリに配置

/Users/user/selenium/chromedriver

PATH を通す

$ vim ~/.zshrc
export PATH=$PATH:/Users/user/selenium/

Node.js で動かす

$ mkdir node-selenium
$ cd node-selenium
$ npm init -y
$ yarn add selenium-webdriver --save

browser.js

Chrome を起動し、google.co.jp へアクセス。 その後 HTML上の タグから検索ワードを入力する欄に 'webdriver' を入力してRETRUN を押下 HTMLのタイトルが’'webdriver - Google 検索'になるまで 1000 ms まつ

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

let driver;

async function accessGoogle() {
    driver = new webdriver.Builder()
        .withCapabilities(webdriver.Capabilities.chrome())
        .build();
    try {
        await driver.get('https://www.google.co.jp');
        await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
        await driver.wait(until.titleIs('webdriver - Google 検索'), 1000);
    } catch (e) {
        console.error(e);
    } finally {
        // await driver.quit();
    }
};

accessGoogle();

実行

$ node browser.js

ブラウザが起動して https://www.google.co.jp にアクセスすればOK😄

Cookie を使ったログイン 🍪

ログイン状態をアクセス時に再現したい場合など、Coockie を設定することができる

selenium-webdriver/lib/webdriver.Options

let expiry = new Date(Date.now() + (10 * 60 * 1000));
const cookie = {
    name: "hoge",
    value: "fuga",
    path: "/",
    domain: "www.google.co.jp",
    expiry: expiry
}

async function accessGoogle() {
    driver = new webdriver.Builder()
        .withCapabilities(webdriver.Capabilities.chrome())
        .build();
    try {
        await driver.get('https://www.google.co.jp'); // cookie は先にブラウザを起動しないと設定できないため一度アクセス
        await driver.manage().addCookie(cookie)
        await driver.get('https://www.google.co.jp'); // cookie 設定後のアクセス
    } catch (e) {
        console.error(e);
    } finally {
        // await driver.quit();
    }
};

プロキシ設定 🏢

社内でプロキシを経由したログインを行う場合 .setProxy でプロキシを設定できる。 ただし、認証ありのプロキシ(http:xxxx:yyyy@host:1234)には対応できていない?

selenium-webdriver/proxy

    driver = new webdriver.Builder()
        .withCapabilities(webdriver.Capabilities.chrome())
        .setProxy(proxy.manual({http: 'host:1234'}))
        .build();

非同期、同期実行

自動実行を複数回行う場合、普通にループを回すと、非同期実行となる

非同期

const count = 3;

for (let i = 0; i < count; i++) {
    accessGoogle();
}

同期 

(async () => {
    for (let i = 0; i < count; i++) {
        await accessGoogle();
    }
})();

以上、おしまい。


  1. Chrome のバージョンとの互換性に注意