masalibの日記

システム開発、運用と猫の写真ブログです

はてなブログの記事一覧を取得するプログラムを作った

記事別のログ集計とSEOチェックをしたかったが
記事一覧というものがはてなブログにはなかった

探してみたところ、はてなブログAtomPub」という
APIがあったが、1回のリクエストにつき7件しか取得できないという
単純には使えない状況だった
今後も記事がふえた事を考慮して、phpのプログラムを組むことにした

前提

・自分の環境はCentOS6.7,php5.6です
バージョンによっては動かない可能性があります

再帰プログラムを組めばよかったのですが・・・できれば修正します

準備

1・APIキーを確認する

はてなブログのダッシュボード
 => 設定
 => 詳細設定
 => AtomPub
   ルートエンドポイントAPIキーをメモる

f:id:masalib:20161026224357p:plain 

f:id:masalib:20161026224406p:plain


2・はてなIDを取得する

はてなブログのダッシュボード
 => 設定
http://blog.hatena.ne.jp/masalib/masalib.hatenablog.com/config
             ↑ここ    
またはアカウト設定
f:id:masalib:20161026224829p:plain



プログラム


出力結果は記事id,title,url,draft(no:表示、yesが非表示)で出力される
(DBに保存する前提だったのでCSVの保存とかはしていない)

<?php

//ルートエンドポイントの設定
//"https://blog.hatena.ne.jp/{はてなID}/{ブログID}/atom/entry";
$url = "https://blog.hatena.ne.jp/masalib/masalib.hatenablog.com/atom/entry";

$USERNAME = "masalib";//hatenaid
$PASSWORD = "XXXXXXXX";//APIkeyをセットする
$nextlink = getdata($url,$USERNAME,$PASSWORD);
//永久ループが怖いので普通のforにする
for($i = 0; $i < 30; $i++){
  //echo $i . '<br><br>';
  if ($nextlink == '') {
      break;
  } else {
    $url = $nextlink;
  }
  $nextlink = getdata($url,$USERNAME,$PASSWORD);
}

function getdata($url,$USERNAME,$PASSWORD) {

  //culrの設定をおこなう
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_USERPWD, $USERNAME . ":" . $PASSWORD);
  curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

  $result = curl_exec($ch); // リクエスト実行

  //app:controlとapp:draftを変換しないとオブジェクトとして認識しなかった(原因不明)
  $result = str_replace('app:control', 'appcontrol', $result);
  $result = str_replace('app:draft', 'appdraft', $result);
  $oXML = new SimpleXMLElement($result);
  $nextlink = ''; //初期化
  //次のページがあるのかの判別
  foreach($oXML->link as $oLink){
  	//echo $oLink->@attributes . "\n<br>";
    if($oLink->attributes()->rel == 'next'){
      $nextlink =  $oLink->attributes()->href ;
    }
  }

  //記事データ
  foreach($oXML->entry as $oEntry){
    //var_dump($oEntry);
    //フォーマットは記事id,title,url,draft(no:表示、yesが非表示)で出力される
  	echo  '"' . $oEntry->id . '"';
    echo  ',' ;
    echo  '"' . $oEntry->title  . '"';
    echo  ',' ;
    $links =  $oEntry->link;
    foreach($links as $link){
      if($link->attributes()->rel == 'alternate'){
        echo '"' . $link->attributes()->href . '"';
        echo  ',' ;
      }
    }
    echo  '"' . $oEntry->appcontrol->appdraft . '"' ;
    echo  "\n<br>";
  }

    return $nextlink;
}
?>

結果は以下のような感じです
f:id:masalib:20161026231325j:plain




ハマった所

basci認証の所
$USERNAME = "masalib";//hatenaid
$PASSWORD = "XXXXXXXX";//APIkeyをセットする

passwordをいつものログインのパスワードをセットしていまい
あれ・・・表示できないってハマりました 


7件しか取得できないので次のページURLをセットする所
  //次のページがあるのかの判別
  foreach($oXML->link as $oLink){
  	//echo $oLink->@attributes . "\n<br>";
    if($oLink->attributes()->rel == 'next'){
      $nextlink =  $oLink->attributes()->href ;
    }
  }

このattributes()の部分がvar_dumpで出すと
@attributesになっていてその取得方法がわからなかった

app:controlという項目がXMLとして認識されなかった
  //app:controlとapp:draftを変換しないとオブジェクトとして認識しなかった(原因不明)
  $result = str_replace('app:control', 'appcontrol', $result);
  $result = str_replace('app:draft', 'appdraft', $result);

この部分は記事の表示、非表示のデータ部分なのですが
SimpleXMLElementの関数をかますと消えてしまった
データがないので「非表示、表示はどこ???・・・」と困惑した

注意事項

1・windowsの環境では試していないです
環境を作って試します

2・記事が200件以上ある人は下記の部分を修正してください

//永久ループが怖いので普通のforにする
for($i = 0; $i < 30; $i++){

3・エラーハンドリングとか全然していないです
githubに載せる時は修正します

今後について

nohohon.hatenadiary.com

junichi-manga.com

などをバッチとかで作ります


参考URL

www.bunkei-programmer.net

ただ私はjavaのプログラムを組めない(環境をつくるのが面倒)ので
phpに置き換えたというか全部組み直した