最近 google から公開された headless な chrome を Javascript で操作するpuppeteer が割と便利そうなのでちょっと試してみた記録です。
目標
最近使い始めたムームードメインのDNS設定を操作してみようかと思います。
自宅のサーバは静的IPじゃないのでddns的な運用をしているのですが、ムームードメインには更新ツールなどもあるわけではないので
手動でポチポチやるしかなくて辛いので、自動化しようかと思います。
環境構築
試してみると意外と環境構築に手間取りました。
環境を汚さないようにしたかったのでdockerから操作してみます。
nodeが必要なので、node:8なイメージで動作させようとしたら、このIssueにハマりました。
puppteerはどうやら今はdebian系で使うには色々苦労しそうな感じです。そして、node:8のイメージもベースはdebianです。
- イメージに色々apt-getで入れる
- スクリプトの方では(
['--no-sandbox', '--disable-setuid-sandbox']
)を追加する
という対処で良いようです。
完成したDockerfileは以下のような感じです。
ここで日本語フォントも追加しておかないと文字化けしてしまうので注意が必要です。
FROM node:8
<p>RUN apt-get update && \
apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \
fonts-vlgothic fonts-horai-umefont fonts-umeplus
CMD ["npm", "run", "start"]
スクリプトを書いてみる
では、さっそくスクリプトを書いてみます。
ムームードメインさんに迷惑になっても困るので抜粋です。
const fs = require('fs');
const assert = require('assert');
const puppeteer = require('puppeteer');
var webclient = require("request-promise-native");
(async() => {
// 自分のIPアドレスを取得
const result = await webclient.get({
url: "http://ifconfig.moe",
headers: {
"User-Agent": "curl/7.52.1";
}
});
const ip_addr = result;
console.log(result);
// 起動できない問題に対処
const browser = await puppeteer.launch({args: ["--no-sandbox", "--disable-setuid-sandbox"]});
const page = await browser.newPage();
await page.setViewport({width: 1024, height: 2048});
await page.goto('https://muumuu-domain.com/?mode=conpane');
// ログインフォームへ入力
await page.focus("#session_muu_id\\ focus")
await page.type("xxxxxxxxxxxxxxxxxxxxxxx");
await page.focus("#session_password");
await page.type("xxxxxxxxxxxxxxxx");
// DNS設定画面を開くまで画面の要素を順番にクリックしていく
await page.waitForSelector("#login > div > div.form-row-left > a");
await page.click("#login > div > div.form-row-left > a");
//
// 目的のページにたどり着くまで、clickとwaitForSelectorを繰り返す
//
await page.click("対象のフォームへのセレクタ");
// DNSの設定画面が開いた
await page.waitForSelector("対象のフォームへのセレクタ");
page.evaluate(() => {
var input = document.querySelector("対象のフォームへのセレクタ");
input.value="";
});
await page.focus("対象のフォームへのセレクタ");
await page.type(ip_addr);
await page.screenshot({path: "setting.png"});
// 確認ダイアログが出たら無条件でOKを押す
page.on('dialog', dialog => {
dialog.accept();
});
page.click("#setup_btn > a");
await page.waitFor(20000);
await page.screenshot({path: "result.png"});
browser.close();
})();
うまく動作すればsetting.pngとresult.pngが生成されるはずです。
またムームードメイン側のDNS設定もうまく変わっているはずです。
Chromeとして動作してくれるので、今までのツールと比較して楽にこういったツールが作れそうですね。