同村チェッカーについて技術的な話5
ハイ、実に1週間間が空きました。
その間に陰謀州の見た目が変わったりとか、同村チェッカーの見た目が変わったりとか、地味に状況が変わっています。
が、解説は古いソースでやっていきたいと思います。陰謀対応のところ以外はあまり変わってないのと、
陰謀対応は暫定状態で正直あまりお見せしたくない*1……。
同村チェッカーについて技術的な話 - Portal:siro
同村チェッカーについて技術的な話2 - Portal:siro
同村チェッカーについて技術的な話3 - Portal:siro
同村チェッカーについて技術的な話4 - Portal:siro
前回ラストのforeach文で回している、insert_vil_all関数の中身からいきます。
<?php // 村一覧のURLからエピローグURLを特定して回す function insert_vil_all($form_url,$form_server,$form_first_vil,$form_last_vil){ $oldlog_html = file_get_html($form_url); if(strcmp($form_server,"RPAd") == 0 || strcmp($form_server,"ultimate") == 0 ){ // RPAd foreach($oldlog_html->find('table.vindex tbody tr') as $oldlog_vildata){ // 村のURLを特定する // 村ID $vil_no = trim_convert($oldlog_vildata->children(0)->plaintext); if($vil_no < $form_first_vil || $vil_no > $form_last_vil){ echo "skip" . $vil_no . "<br>"; continue; } // 村名 // $vil_name = $oldlog_vildata->children(1)->children(0)->plaintext; // 最終日&エピローグ $vil_last_day = trim_convert($oldlog_vildata->children(3)->plaintext); // 廃村対策 // ただし、進行中に廃村した場合は考慮してない if(strcmp($vil_last_day,"廃村") == 0){ $vil_last_day = 1; }else{ $vil_last_day = preg_replace("/([0-9]+)(日.*)/","\\1",$vil_last_day,-1); $vil_last_day++; } // 最終日から村URLを生成 // 村URL // http://utage.sytes.net/wolf/sow.cgi?css=ririnra&cmd=oldlog // http://utage.sytes.net/wolf/sow.cgi?pageno=1&css=ririnra&cmd=oldlog&rowall=on // http://utage.sytes.net/wolf/sow.cgi?css=ririnra&turn=5&vid=212&mode=all&move=page&pageno=1 $vil_url = preg_replace("/(.*cgi\?)(.*)/","\\1",$form_url,-1); $vil_url = $vil_url . "turn=" . trim_convert($vil_last_day) . "&vid=" . trim_convert($vil_no) . "&mode=all&move=page&pageno=1"; echo $vil_url . "<br>"; insert_vil_data($vil_url); echo "done."."<br>"; } }else{ // RPAd以外?(標準、陰謀系はこれで取得できるのを確認済) foreach($oldlog_html->find('table.vindex tr.i_hover') as $oldlog_vildata){ echo "are"; // 村のURLを特定する // 村ID $vil_no = trim_convert($oldlog_vildata->children(0)->plaintext); if($vil_no < $form_first_vil || $vil_no > $form_last_vil){ echo "skip" . $vil_no . "<br>"; continue; } // 村名 // $vil_name = $oldlog_vildata->children(1)->children(0)->plaintext; // 最終日&エピローグ $vil_last_day = trim_convert($oldlog_vildata->children(3)->plaintext); // 廃村対策 // ただし、進行中に廃村した場合は考慮してない if(strcmp($vil_last_day,"廃村") == 0){ $vil_last_day = 1; }else{ $vil_last_day = preg_replace("/([0-9]+)(日.*)/","\\1",$vil_last_day,-1); $vil_last_day++; } // 最終日から村URLを生成 // 村URL // http://utage.sytes.net/wolf/sow.cgi?css=ririnra&cmd=oldlog // http://utage.sytes.net/wolf/sow.cgi?pageno=1&css=ririnra&cmd=oldlog&rowall=on // http://utage.sytes.net/wolf/sow.cgi?css=ririnra&turn=5&vid=212&mode=all&move=page&pageno=1 $vil_url = preg_replace("/(.*cgi\?)(.*)/","\\1",$form_url,-1); $vil_url = $vil_url . "turn=" . trim_convert($vil_last_day) . "&vid=" . trim_convert($vil_no) . "&mode=all&move=page&pageno=1"; echo $vil_url . "<br>"; insert_vil_data($vil_url,$form_server); } } } ?>
大きなif文のif〜はRPAdとultimate鯖対応の部分なので省略します。がっつり。
ぶっちゃけやってることはどちらも微妙なHTMLの差に対応しているだけで変わりません。
<? // RPAd以外?(標準、陰謀系はこれで取得できるのを確認済) foreach($oldlog_html->find('table.vindex tr.i_hover') as $oldlog_vildata){ echo "are"; // 村のURLを特定する // 村ID $vil_no = trim_convert($oldlog_vildata->children(0)->plaintext); if($vil_no < $form_first_vil || $vil_no > $form_last_vil){ echo "skip" . $vil_no . "<br>"; continue; } ?>
なので、else文の中を順番に見ていきましょう。
vindexクラスを持ったtableの、i_hoverクラスを持ったtrタグを順に見ていきます。
perjury.rulez.jp/sow.cgi?cmd=oldlogあたりのHTMLを確認しながらご覧ください。
<tr class="i_hover"> <td>169 <td><a href="./sow.cgi?vid=169&cmd=vinfo">アンドロイドシステム</a> <i><br>〈<a href="./sow.cgi?vid=169#newsay">最新</a>〉 <img src="http://giji.check.jp/images/icon/key.png" width="16" height="16" alt="[鍵]"> </i><img src="http://giji.check.jp/images/icon/cd_sexyviolence.png" width="40" height="16" alt="[性暴 ]" title="[性暴] えろぐろ"> <i class="small"> <br> 人物 : 人狼議事 ちゃんぷる <br> 更新 : 07:00 48h毎</i> </td> <td class="small">14人<i><br>村人の勝利</i> </td> <td class="small">06日 </td> <td class="small"> タブラの人狼<i> <br><a href="./sow.cgi?vid=169&cmd=howto&game=TABULA&trsid=all#rolerule">オール☆スター</a> <br><a href="./sow.cgi?vid=169&cmd=rolematrix&game=TABULA&trsid=all">自由設定</a></i> </td> <td class="small">いっぱい<i></i> </td> </tr>
とりあえず直近で終了した村を引っ張ってきます。trの中身はこんな感じ。
村のIDは最初のtdタグの中。つまり、$oldlog_vildata->children(0)->plaintextの中です。
ちなみにこのtdタグ閉じていないのですが、Parserちゃんはちゃんと解析してくれます、ありがたいですねー。
で、引数で受け取った解析対象の村番号かどうかっていうのをチェックして、この村は対象外だよ!ってなったらそこで処理終了して次の行を見ています。
で、次
<?php // 村名 // $vil_name = $oldlog_vildata->children(1)->children(0)->plaintext; // 最終日&エピローグ $vil_last_day = trim_convert($oldlog_vildata->children(3)->plaintext); // 廃村対策 // ただし、進行中に廃村した場合は考慮してない if(strcmp($vil_last_day,"廃村") == 0){ $vil_last_day = 1; }else{ $vil_last_day = preg_replace("/([0-9]+)(日.*)/","\\1",$vil_last_day,-1); $vil_last_day++; } ?>
あれ?ここでも村名取ってるじゃん?
あ、あれ……?取ってますね……?
しかもここで村名取得しても結局エピローグのtitleタグ解析してるので、ぶっちゃけこれいらない処理ですね……いまきづいt
気を取り直して次。
村の日付を取得します。
<td class="small">06日 </td>
この部分ですねー。
ここの部分が廃村だったら1日目=プロローグとして解釈しています。8割がたこれで問題ないです。
進行中廃村(バグとか)があった場合は解析部でエラーが出るのですが、
そういう村は手動で対策していますー。数えるほどしかないのであまり気にしてません。
そうでなければ[06]の部分を取得して、+1しています。
ここがPHPの妙なのですが、
$vil_last_day(String) = '06'; に、
$vil_last_day++;を処理すると、
$vil_last_day = 7; (int)となるのです。オート型変換というやつです。
それにしてもこの時期の僕はスネークケースでプログラミングしてたんですね。
途中からキャメルケースになってて統一感がない……。
<?php // 最終日から村URLを生成 // 村URL // http://utage.sytes.net/wolf/sow.cgi?css=ririnra&cmd=oldlog // http://utage.sytes.net/wolf/sow.cgi?pageno=1&css=ririnra&cmd=oldlog&rowall=on // http://utage.sytes.net/wolf/sow.cgi?css=ririnra&turn=5&vid=212&mode=all&move=page&pageno=1 $vil_url = preg_replace("/(.*cgi\?)(.*)/","\\1",$form_url,-1); $vil_url = $vil_url . "turn=" . trim_convert($vil_last_day) . "&vid=" . trim_convert($vil_no) . "&mode=all&move=page&pageno=1"; echo $vil_url . "<br>"; insert_vil_data($vil_url,$form_server); ?>
村の最終日(エピローグ)のURLさえわかればこっちのものです。
村のエピローグURLを組み立てて、解析関数にぶん投げます。
特に難しい説明はなかった!
というわけで一通り、同村チェッカーにデータを「登録する」部分の説明は終わってしまったのですがー。
「検索する」部分の説明はしないことにします。
基本的にあれもformから入力された情報を元にSQLを組み立てて表示してるだけなので説明することが特にないんですよ!まいった!
なので、ここで一区切りとします。
いやはや本当にお疲れ様でございました。
新しい陰謀州の解析方法を思いついたらまたなんか記しまs
*1:ソースが汚い