electronのwebview内のHTMLデータを引っ張り出してみる（qiitaから未読数を取得する例）

# この記事を書いた背景

electronのwebviewを使って、他のサイトのページを表示させることができます。

開発していくなかで、webview内のHTMLデータなどを引っ張り出して、違うところで使いたいというシーンが出てきます。

たとえば、

* qiitaページ内の未読数を取得してみたい
* ページ内からスケジュールを取り出して、リマインダーを作ってみたい

などとかがその例にあたります。

ただ、解決にまたまた時間がかかってしまったので、備忘録がてらに解決法を記載します。

# 前提環境
windows 7
NodeJS v0.12.5
electron v0.33.1

# 本題

ここでは、「qiitaページ内の未読数を取得してみたい」を例にやってみます。


まずは、qiita-sampleフォルダを作って、package.jsonを生成します。

```
mkdir qiita-sample
cd qiita-sample
npm -y init
```

生成されたpackage.jsonを開き、こんな感じに編集しました。

```package.json
{
  "name": "qiita-sample",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

main.jsはこんな感じ。webviewが最低限動く環境でやっています。

```main.js
'use strict';

var app = require('app');
var BrowserWindow = require('browser-window');

require('crash-reporter').start();

var mainWindow = null;

app.on('window-all-closed', function() {
  if (process.platform != 'darwin') {
    app.quit();
  }
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({width: 1000, height: 600});
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});
```

index.htmlはこんな感じにしました。

```index.html
<html>
<head>
  <meta charset="UTF-8">
  <title>QiitaSample</title>
</head>
<body>
  <div>未読お知らせ数: <span id="unread-count"></span></div>
  <webview id="mainWebview"
    src="https://qiita.com"
    autosize="on"
    preload="lib/webview/qiita.js"></webview>
  <style>
  webview {
    position: relative;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
  }
  </style>
  <script src="lib/qiita.js"></script>
</body>
</html>
```

ここのポイントとしては、webviewタグに[preloadオプション](https://github.com/atom/electron/blob/master/docs/api/web-view-tag.md#preload)を設定おきます。ここに指定したjsはwebview内のデータを取り扱うことができます。

```html
  <webview id="mainWebview"
    src="https://qiita.com"
    autosize="on"
    preload="lib/webview/qiita.js"></webview>
```

読み込み先のlib/webview/qiita.jsはこんな感じにします。ipc（プロセス間通信を行うためのライブラリ）の[onメソッド](https://github.com/atom/electron/blob/master/docs/api/ipc-main-process.md#ipconchannel-callback)でretrieveUnreadCountチャネルを定義し、ここに未読数を取得させる処理を定義しておきます。

```lib/webview/qiita.js
var ipc = require('ipc');

ipc.on('retrieveUnreadCount', function(){
  var unreadCount = document.getElementsByClassName("globalNotifications_count")[0].innerText;
  ipc.sendToHost('retrieveUnreadCount', unreadCount);
});
```

このように定義し、アプリ内でつぎのコードを実行させると、webview側でretrieveUnreadCountチャネル以下の処理が実行されます。

```js
var webview = document.getElementById('mainWebview');
webview.send("retrieveUnreadCount");
```

また、retrieveUnreadCountチャネルでは、[sendToHostメソッド](https://github.com/atom/electron/blob/master/docs/api/ipc-renderer.md#ipcsendtohostchannel-arg1-arg2-)を用いることで、webview側からアプリへ結果を返してあげています。

```
ipc.sendToHost('retrieveUnreadCount', unreadCount);
```

この結果を受け取るには、webviewの[ipc-messageイベント](https://github.com/atom/electron/blob/master/docs/api/web-view-tag.md#event-ipc-message)を用います。index.html上にあるlib/qiita.jsではこの[ipc-messageイベント](https://github.com/atom/electron/blob/master/docs/api/web-view-tag.md#event-ipc-message)を用いて、webview側のretrieveUnreadCountチャネルから送られた未読数を取得し、アプリ内へ反映させています。

```lib/qiita.js
var webview = document.getElementById('mainWebview');

var checkUnreadCountTimer= setInterval(function() {
  webview.send("retrieveUnreadCount");
}, 1000);

webview.addEventListener('ipc-message', function(event) {
 switch(event.channel){
   case "retrieveUnreadCount":
     var unreadCount = event.args[0];
     document.getElementById("unread-count").innerText = unreadCount;
     break;
 }
});
```

これで、未読数を取得して、アプリ内へ反映させる一連の処理ができあがりました。

では、実際に実行してみましょう！qiita-sampleフォルダへ行き、次のコマンドを実行させてみると

```
electron .
```

qiitaのページが表示されます。そして、そのままログインし、トップページへいくと、未読数が取得されて表示されていることが確認できます。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/95464/91a32c3a-56ae-24db-65b8-91f0045da4a2.png)


# まとめ
ここまで至るのにプロセス間通信とかしらないといけなかったので、結構手間取りました。
正直、もっと楽な方法があればいいなと感じました。

<b>参考元:</b> [ElectronでChatworkをデスクトップアプリ化 (Webview + badge)](http://qiita.com/mottox2/items/7a1373f23ba02245d0e0)