SNSから人気記事の指標を取得する

■使用するAPI
いずれもパラメータに記事のURLを付けてHTTPでエンドポイントをたたけば返ってきます。 各SNSで使用するAPIの実行例を記載します。
はてなブックマーク
#リクエスト
http://api.b.st-hatena.com/entry.count?url=http://www.ois-yokohama.co.jp/
#レスポンス 1
#リクエスト
http://urls.api.twitter.com/1/urls/count.json?url=
#レスポンス
{"count":0,"url":"https://www.ois-yokohama.co.jp/"}
#リクエスト
http://graph.facebook.com/
#レスポンス
{
"id": "http://www.yahoo.co.jp/",
"shares": 12,
"comments": 1
}
はてブは値がそのまま返ってきて、TwitterとFacebookはJSON形式で返ってきます。Twitterは”count”、 Facebookは”shares”の値をとります。Facebookは0件の場合は”shares”の項目自体がないので注意が必要です。
■APIを呼び出す機能
上記のAPI呼び出しを実装します。よく使いそうなのでクラスにしておきます。 親クラス
<?php
abstract class AbstractSNS
{
abstract public function getSNSCount($url);
}
?>
Twitter用クラス
<?php
class Twitter extends AbstractSNS
{
public function getSNSCount($url){
$json = file_get_contents('http://urls.api.twitter.com/1/urls/count.json?url=' . $url);
$array_good = json_decode($json, true);
return $array_good['count'];
}
}
?>
Facebook用クラス
<?php
class Facebook extends AbstractSNS
{
public function getSNSCount($url){
$json = file_get_contents('http://graph.facebook.com/' . $url);
$array_good = json_decode($json, true);
if(isset($array_good['shares'])){
return $array_good['shares'];
}
return 0;
}
}
?>
はてブ用クラス
<?php
require('AbstractSNS.php');
class Hatena extends AbstractSNS
{
public function getSNSCount($url){
$count = file_get_contents('http://api.b.st-hatena.com/entry.count?url=' . $url);
return $count;
}
}
?>
■収集するタイミング
RSSと違い時間が経つと数値が増えていくので、1度だけではなく何度か収集します。 新しい記事ほどSNSの指標の伸びも大きいはずなので、新しい記事は間隔を短く、古い記事は間隔を長くします。7日分を収集し、8日以上経った記事についてはもう収集しません。遅れて話題になったりすることもありますが、それは無視することにします。 収集タイミングを以下の4パターンに分けます。それぞれのパターンに対してAPIにリクエストする間隔を決めます。決めるに当たり必要な記事の件数は、1日当たり600を最大と想定しました。(よほど暇でないとそれほど多くの記事を読むことはないと思いますが。)
| 記事の新しさ | 更新タイミング | リクエスト間隔 |
|---|---|---|
| 24時間以内の記事 | 1時間に1回 | 6sec/req(600req/h) |
| 24時間前~48時間前以内の記事 | 3時間に1回 | 18sec/req(200req/h) |
| 48時間前~72時間前の記事 | 6時間に1回 | 36sec/req(100req/h) |
| 72時間前~168時間前 | 1日に1回 | 36sec/req(100req/h) |
同時に4リクエストされる場合がありますが、これくらいは問題ないでしょう。
■収集機能
収集機能を実装します。対象となる記事を抽出後、それぞれのURLについて各SNSのAPIで件数を調べます。 収集タイミングを後から調整できるように、記事更新日時のFrom, Toと収集間隔は外からパラメータで渡せるようにします。
<?php
require dirname(__FILE__) . './Twitter.php';
require dirname(__FILE__) . './Hatena.php';
require dirname(__FILE__) . './Facebook.php';
class SnsCollect
{
public function collect($from, $to, $sleeptime){
// 対象の記事を抽出
$dsn = 'mysql:host=localhost;dbname=rss;port=3306;';
$pdo = new PDO($dsn, 'user', 'password');
$sql = 'SELECT feedno, url FROM article WHERE updatedate BETWEEN :from AND :to';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':from', $from, PDO::PARAM_STR);
$stmt->bindParam(':to', $to, PDO::PARAM_STR);
$flag = $stmt->execute();
if (!$flag) {
$info = $stmt->errorInfo();
exit($info[2]);
}
$article_array = array();
while($rec = $stmt->fetch(PDO::FETCH_ASSOC)){
$article_array[] = $rec;
}
$stmt = null;
$stmt = $pdo->prepare('UPDATE article SET facebook = :facebook, twitter = :twitter, hatena = :hatena WHERE feedno = :feedno AND url = :url');
$stmt->bindParam(':facebook', $facebook, PDO::PARAM_STR);
$stmt->bindParam(':twitter', $twitter, PDO::PARAM_STR);
$stmt->bindParam(':hatena', $hatena, PDO::PARAM_STR);
$stmt->bindParam(':feedno', $feedno, PDO::PARAM_STR);
$stmt->bindParam(':url', $url, PDO::PARAM_STR);
// SNSから指標を取得
foreach($article_array as $article){
$feedno = $article['feedno'];
$url = $article['url'];
$sns = new Twitter();
$twitter = $sns->getSNSCount($url);
$sns = new Hatena();
$hatena = $sns->getSNSCount($url);
$sns = new Facebook();
$facebook = $sns->getSNSCount($url);
$stmt->execute();
sleep($sleeptime);
}
}
}
?>
収集機能の呼び出し処理です。収集タイミングごとに作成します。 下記は24時間前~48時間前の記事の収集です。
<?php
require dirname(__FILE__) . '/SnsCollect.php';
$from = date('Y-m-d H:i:s',strtotime('-48 hour'));
$to = date('Y-m-d H:i:s',strtotime('-24 hour'));
$sns = new SnsCollect;
// 6秒間隔で収集
$sns->collect($from, $to,
6
); ?>
同様に他の3パターンを作成し、cronで起動スケジュール設定をすれば完成です。 次回はこれまでに溜めたRSSの情報を利用します。