Selenium WebdriverをNode.jsで動かして、CMSのWYSIWYGエディタを操作しJSONで用意した複数の記事データを自動登録する
「Selenium WebdriverをNode.jsで動かして、CMSのWYSIWYGエディタを操作しJSONで用意した複数の記事データを自動登録する」という誰得な記事が書けるくらいになった【作業がんばるぞい】 https://t.co/Fuhtvlnny5 #作業がんばる
— console.log('べこ🐄'); (@becolomochi) 2018年7月4日
静的HTMLで用意されているデータをCMSの記事として登録する作業があったのだけど、枚数がパッと見てもものすごく多く、人力でやるには人手も時間も足りなそうだったのでSeleniumを初めて使ってみた。
CMSで使っているエディタのライブラリが原因でソース入力ができず結構悩んでしまった。解決したので書いておく。
使用ツール・環境など
- Selenium Webdriver Node.js版
- CKEditor 4(WYSIWIGエディタ)
- macOS High Sierra 10.13.5
- iTerm
- Node.js v8.11.1
やりたかったこと
つっかかったこと
- Seleniumで動かした時にCKEditorをソース表示モードにできずにターミナルにエラーが表示される
- もちろん本文も流し込めない
解決方法
Seleniumで以下のように操作するよう記述。
- 一旦は初期表示のビジュアルモードのままダミーテキストを入力
- その後、ソース表示ボタンを押す動作を入れる
- ダミーテキストを削除
- 本文を流し込む
CKEditor特有のものだったらしい。公式サイトのデモをSeleniumで操作してみて気づいた。
用意したJSONファイル
以下のようなtitle(記事のタイトル)、url(記事のURL)、souce(本文のHTML)を入れてあります。
サンプル
仮の内容にしてあります。
ちなみにSelenium Webdriverの入手方法は公式サイトに。
コードはnpmのページのサンプルを元に作っていった。
実行方法
ターミナルから以下コマンドで実行する
$ cd ファイルを保存したディレクトリ
$ node ファイル名.js
コードの解説
const {Builder, By, Key, until} = require('selenium-webdriver');
Selenium Webdriver を呼び出し
const posts = require('sample.json');
用意しておいたJSONファイルを呼び出し
let driver = await new Builder().forBrowser('firefox').build();
Firefoxで動かす
for(let i = 0; i<posts.length; i++){
記事データを1項目ずつ取り出す
await driver.get('http://入力フォームのURL');
入力フォームのページへ遷移
await driver.findElement(By.name('title')).sendKeys(posts[i]['title']);
titleのinputに用意したtitleの内容を入れる
await driver.findElement(By.name('url_name')).sendKeys(posts[i]['url_name']);
url_nameのinputに用意したurl_nameの内容を入れる
await driver.wait(until.elementLocated(By.tagName("iframe")), 1000); let iframe = await driver.findElement(By.tagName("iframe")); await driver.switchTo().frame(iframe);
CKEditorの入力フォームは表示に少し時間がかかっていたので1000ミリ秒待ってから、iframe内に移動
await driver.findElement(By.tagName("body")).sendKeys("dummy");
「dummy」というテキストを入れる
await driver.switchTo().defaultContent();
iframeから脱出する
await driver.findElement(By.className('cke_button__source')).click();
cke_button__source というクラスのついた項目をクリックする(これがソース表示ボタン)
await driver.findElement(By.className('cke_source')).clear();
さっき「dummy」と入れたのを消す
await driver.findElement(By.className('cke_source')).sendKeys(posts[i]['source']);
jsonファイルの「souce」に用意してあったHTMLの内容を入力する
await driver.findElement(By.name('button')).click();
登録ボタンを押す
} finally { await driver.quit(); }
作業が完了したらブラウザを閉じる
参考URL
- Selenium WebDriver
- https://ckeditor.com/ckeditor-4/
- Selenium API(逆引き)
- selenium-webdriver - npm
- Selenium | frameを利用したページの自動操作 - Tbpgr Blog