Pocket数をJavaScriptとYQLを使って取得する方法
「後で読む」の 代表サービス Pocket。書いた記事がどれだけ Pocket に登録されているかを JavaScript だけで取得したいのですが、公式には Pocket 数取得のための API がないということで JavaScript の力だけでは無理です。ですので米 Yahoo! が提供している YQL というサービスと併用して Pocket 数を取得したいと思います。
YQL は特に登録せずとも使えるサービスなのでこちら側がすることは JavaScript コードを書くだけです。パッと見「Pocket 数を JavaScript だけで取得する方法」に見えるかと思います。
追記:Pocket 公式ボタンの仕様変更があったため色々変更しています。2016/12/4
YQL とは
参考:YQL
YQL はものすごく簡単に、雑に言うと「指定した URL の内容を JSON 化して送ってくれる」サービスです。内容というのは HTML データを指します。
Sample YQL Response にいろいろ入れてみると意味が分かるかと思います。正確に知りたい方は英語ですが本家サイトを読んでください。JSON データ以外でも XML でもデータを送ってくれます。通常の XML 通信ではクロスドメイン制約がかかるため通信ができませんが YQL を使えば可能になります。
select * from html where url='http://widgets.getpocket.com/v1/button?v=1&count=horizontal&url=https://q-az.net/buruburu-hurueru-css/&src=https://q-az.net/buruburu-hurueru-css/'
例えば YQL に対して上のようなクエリを投げると以下の JSON がレスポンスとして返ってきます。赤字の URL はとあるページの Pocket のシェアボタンの URL です。
JSON
{
"query": {
"count": 1,
"created": "2016-10-18T23:16:21Z",
"lang": "ja",
"results": {
"body": {
"div": {
"class": "widget horizontal pocket left",
"a": {
"id": "btn",
"span": {
"em": {
"id": "cnt",
"content": "15"
},
"i": null,
"u": null
},
"b": null
}
},
"script": [
{
"type": "text/javascript",
"content": "\nvar POCKET_DOMAIN = 'getpocket.com';\nvar iLi = false;\n\nvar btnData = {\"mode\":\"viapocketbutton\",\"ct\":\"b3915bc80a322542d2a9203996c595d7bb9e969b\",\"ctn\":\"10a229a703adf44ffb1a160a70f5fe0fd0401e87\",\"label\":\"pocket\",\"count\":\"horizontal\",\"src\":\"\",\"url\":\"https:\\/\\/q-az.net\\/buruburu-hurueru-css\\/\"};\n"
},
{
"src": "https://d7x5nblzs94me.cloudfront.net/v1/j/button.js?v=5",
"type": "text/javascript"
}
]
}
}
}
}
シェア数が入っている Pocket ボタンの HTML を JSON に変換しているので、 body や div などの記述がみられます。Pocket 数は赤字で示した content の値です。
JavaScript で Pocket 数の取得
まず YQL に対して投げるクエリです。
select * from html where url='http://widgets.getpocket.com/v1/button?v=1&count=horizontal&url=(Pocket数を表示したい記事の URL)&src=(Pocket数を表示したい記事の URL)'
最後のほうに書いてある url= 以降に URL を指定すれば Pocket ボタンの HTML を取得できます。
次は実際の実施コードです。非同期通信のためコードはそこまで柔軟ではありません。同期通信であれば return で簡単に数値自体を戻り値として取得できますが、非同期通信はそう簡単にはいきません。そのかわり非同期通信はページの表示を邪魔しません。
非同期通信で簡単に表示可能にするために、指定した id を持つ要素に Pocket 数を入れることにします。以下の例では id="pocket-1" などを持つ要素内に取得した Pocket 数を挿入しています。
JavaScript
function getPocket(pocketElm) {
var xml = new XMLHttpRequest();
xml.onreadystatechange = function() {
if ((xml.readyState == 4) && (xml.status == 200)) {
//受け取った text を JSON にパースする
var json = JSON.parse(this.responseText);
//指定した id を持つ要素に Pocket 数を挿入
document.getElementById(pocketElm).textContent = json.query.results.body.div.a.span.em.content;
}
};
//YQL と非同期通信 URLはエンコードする
var xmlUrl = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D'http%3A%2F%2Fwidgets.getpocket.com%2Fv1%2Fbutton%3Fv%3D1%26count%3Dhorizontal%26url%3D" + encodeURIComponent(location.href) + "%26src%3D" + encodeURIComponent(location.href) + "'&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
xml.open("GET", xmlUrl, true);
xml.send(null);
}
//使用例
getPocket("pocket-1");
//いくつでも id を指定できます
getPcket("pocket-2");
getPcket("pocket-3");
以下の要素内にそれぞれ Pocket 数が挿入されます。
<span id="pocket-1"></span>
<span id="pocket-2"></span>
<span id="pocket-3"></span>
デモ
この記事の Pocket 数を上記コードで取得した実際の数です。
この記事の Pocket 数は現在 個です。
注意事項
YQL というサービスを利用しているため、このサービスが何らかの理由で終了した場合この方法は使えなくなります。また YQL 自体に利用の制限数が存在します。詳しくは公式で確認してください。
Pocket ボタンのソースを見てもらえればわかるのですが、Please do not scrape this for the Pocket count. It is not relible for you to use and will likely change. Contact us at api@getpocket.com for an official API. Thanks!
と書いてあり、このボタンの HTML を解析して Pocket 数を取得することを推奨していません。むしろ禁止しているのかもしれません。ただ、公式の API にコンタクトをとってね、と言っているにもかかわらず Pocket 数を取得するための公式な API は存在しません。
上の英文にも書いてありますが、Pocket ボタンの HTML の構造が少しでも変われば取得できなくなります。そのたびに修正が必要です。
YQL キャッシュ時間がおそらくですが3時間程度であるためすぐには反映されません。またたまにですが取得できないバグ?のようなものがあります。
まとめ
公式が推奨していない方法なので何とも言えないですが JavaScript オンリーで取得する簡単な方法はこんな感じになるかと思います。実際、WordPress のシェアボタンのプラグインなどで Pocket 数を取得しているものは、JavaScript ではないものの公式のボタンからこの数字を拝借しているのは変わりません。同じく非推奨なやり方です。
今は公式が正式な API を出してくれることを祈るしかありません。