2010年07月09日

Naver の Yeti を追い出す

 この10日ほど、Trend Antenna にアクセスしにくい状況が続いています。データベースサーバに負荷がかかっているために、PHP の実行に制限がかかっているようです。

 エラーが出始めてから、データベースの構造を改善したり、SQL文の書き方を工夫してみたりしました。しかし、好転の兆しが見えず、かえって状況は悪化…。

 そんなときに、アクセス解析を眺めていたら、Naver のロボット、Yeti が大量にアクセスしてきていることが判明しました。普段、ロボットを除いたアクセス解析しか見ていなかったので気付かなかったのですが、改めて見てみると、全体の転送量の60%以上が Yeti によるアクセス。他の検索エンジンのロボットがせいぜい5〜6%なのに比べると、大きな違いです(ちなみに、Googlebot によるアクセスは、訪問回数こそ多いものの、転送量は非常に小さく、同じ内容のデータを読まないような配慮がされているように思います)。

 Naver 経由のアクセスもありませんし、人間のアクセスに支障が生じてまでロボットに配慮する必要はありませんから、Yeti を追い出すことにしました。

 方法としては、.htaccess と、robots.txt を併用することにしました。単にアクセス禁止にするだけだと、リソースの無駄遣いは減らせるものの、アクセス数そのものは減らせないからです。

 まず、.htaccess によるアクセス制限ですが、こちらは IPアドレスベースの制限をかけることにします。私のページにアクセスしてきたロボットの IPアドレスを JPNIC の Whois にかけて調べると、運営者である NHN Japan 株式会社が使用している IPアドレスが確認できます(結果)。これをすべてアクセス禁止にしてもよいのですが、それも気の毒なので、今回は 119.235.237.0/24 だけを制限することにしました(成果が出なければ拡大します)。また、後で述べるように robots.txt を読ませたいので、.htaccess に追加した記述は最終的に以下のようになります。

Order allow,deny
Allow from all
Deny from 119.235.237.0/24

<Files robots.txt>
order deny,allow
allow from all
</Files>

 次に、robots.txt の記述ですが、こちらは簡単で、

User-agent: Yeti
Disallow: /

これだけ。これで、robots.txt 以外へのアクセスを遮断したうえで、robots.txt を解釈してくれるのであれば、私のサイトに来てはいけないということを認識してくれるはずです。

 早く成果が挙がることを祈ってます。

 Baidu の BaiduMobaider もお行儀が悪いので、追い出すことにしました。こちらについては、IPアドレスの範囲が、119.63.195.0/24 なので(Baidu のクローラー情報ページ)、.htaccess に
Deny from 119.63.195.0/24
を追加しました。大量のアクセスでリソースを食いつぶされてしまうのは、本当につらい…(2010年7月22日:追記)

posted by まいける at 14:51 | Comment(0) | TrackBack(0) | その他

2010年02月26日

PEAR Services_Amazon を使ってみる

 楽天ウェブサービスが安定しないこともあり(新規デベロッパーIDの発行を停止したようですね)、Amazon を併用するようにしたのですが、せっかくなので、新しいことを試してみようと、PEAR Services_Amazon を使ってみることにしました。書籍検索の場合は、以下のような感じです。

require_once 'Services/Amazon.php';
require_once 'Cache.php';

$access_key_id = '(公開アクセスキー)';
$secret_access_key = '(秘密アクセスキー)';
$associate_tag = '(アソシエイトタグ)';
    
$amazon = new Services_Amazon($access_key_id, $secret_access_key, $associate_tag);
$amazon->setCache('file', array('cache_dir' => '(キャッシュの保存先)'));
$amazon->setCacheExpire(3600); // 秒数で指定
$amazon->setLocale('JP');

$options = array();
    
$options['ResponseGroup']  = 'Medium'; //取得したい情報
$options['Keywords']       = '検索したいキーワード';
$options['Sort']           = 'salesrank';

$result = $amazon->ItemSearch('Books', $options);

if (PEAR::isError($result)) {
        echo $result->message;
} else {
    foreach($result['Item'] as $item) {
        $ItemData[] = array(
            'ImageURL' => $item["SmallImage"]["URL"],    
            'DetailPageURL' => $item["DetailPageURL"],
            'Title' => $item["ItemAttributes"]["Title"],
            'Price' => $item["ItemAttributes"]["ListPrice"]["FormattedPrice"]
        );
    }
}

 これで、$ItemData の中に商品データが入るので、適宜加工して表示するような形になります。ちょっと変わったこととしては、キャッシュを使うことによって、同じリクエストを連続して行わないように工夫をしています。この機能を使うためには、Services_Amazon のほかに、Cache のパッケージも必要となります(Cache_Lite ではないので注意)。

 パッケージのドキュメントもクラスのリファレンスしかないため、取っつきにくいですが、電子署名認証を自動でやってくれたり、結果を連想配列で返してくれたりと、かなり使い勝手がよいので、おすすめです。他にも、複数のキーワードについてひとつのリクエストで処理する doBatch メソッドや、複数の操作をひとつのリクエストで処理する doMultiOperation メソッドなども便利だと思います。

posted by まいける at 01:46 | Comment(0) | TrackBack(0) | PHP

2009年11月24日

モバイル版 Google Analytics を PHP4 で動かす

 先日からサービスの提供が始まったモバイル版の Google Analytics ですが、アクセス解析用の PHP スクリプトである ga.php は PHP4 では動きません。PHP4 のアップデートはすでに終わっているので、PHP5 にアップグレードするべきなのですが、レンタルサーバなどで PHP のアップグレードをしてくれないところもあると思います。そこで、PHP4 でも動くように、ga.php を修正してみました(ライセンス的な問題がちょっと気になりますが…)。

 準備として、PEAR の PHP_Compat をインストールします(stable版の1.5.0ではなく、alpha版の1.6.0a2が必要)。

 次に、ga.php の先頭部分に

require_once 'PHP/Compat/Function/setrawcookie.php';
require_once 'PHP/Compat/Function/file_get_contents.php';

を追加します。そして、97行目と100行目にある file_get_contents を php_compat_file_get_contents に書き換えます。さらに、144行目以降を

    setrawcookie(
        COOKIE_NAME,
        $visitorId,
        $timeStamp + COOKIE_USER_PERSISTENCE,
        COOKIE_PATH);

から

    setrawcookie(
        COOKIE_NAME,
        $visitorId,
        $timeStamp + COOKIE_USER_PERSISTENCE,
        COOKIE_PATH,
        '',
        false,
        false);

に変更します。

 これで動くようになるはずです(PHP4.4.9 の環境で確認)。

 種明かしをすると、setrawcookie は PHP5 から新たに登場した関数です。また、file_get_contents のコンテキストサポート(第3引数)も PHP5 以降にサポートされたものです。このため、これらを使えるようにしなければなりません。setrawcookie は、PHP4 にもともとない関数ですので、それほど問題ない(せいぜい 1.6.0a2 をインストールすることと、引数を省略せずに記載することくらい)のですが、file_get_contents は、PHP4.3.0 以降ではすでに登場しているため、PHP_Compat::loadFunction を使う PEAR PHP_Compat の通常の使い方だと、PHP ネイティブの関数が優先されてしまいます。そこで、上記のように個別の関数を手動で読み込んだうえで、PHP_Compat 側の関数を使うようにしているのです。

 不具合等があれば、コメント欄などでご指摘ください。

posted by まいける at 12:32 | Comment(2) | TrackBack(1) | PHP

2009年11月08日

Amazon の書籍を楽天ブックスで買うためのブックマークレット(続き)

 前回のエントリーで書いたAmazon の書籍を楽天ブックスで買うためのブックマークレットですが、処理の流れとしては、

  1. javascript で表示中の Amazon の URL から ASIN を取得
  2. 取得した ASIN を Amazon の API に渡して ISBN を取得
  3. 取得した ISBN を楽天の楽天ブックス書籍API に渡して楽天ブックスの商品ページを取得
ということをやっています。

 書籍の場合はこれでうまくいくのですが、雑誌の場合はうまくいきません。雑誌には ISBN ではなく、JANコードが付けられており、ASIN→ISBN変換では値を返さないからです。

 いろいろ調べてみると、Amazon API の ItemAttributes レスポンスグループの中にある EAN が日本の雑誌の場合には JANコードになっていることがわかりました。そこで、ASIN→ISBN変換で値を返さない場合は、EAN を取得し、これを楽天ブックス雑誌検索API に渡すことで、雑誌でも楽天ブックスの商品ページを取得できるようになりました。

 これを応用すれば、CD や DVD でも Amazon→楽天の検索ができるかもしれません(未検証ですが)。

posted by まいける at 00:51 | Comment(0) | TrackBack(0) | その他

2009年11月05日

Amazon の書籍を楽天ブックスで買うためのブックマークレット

 厳密にいうと、Trend Antenna の開発とは直接関係がないのですが、ちょっとしたツールを作りましたので、ご報告。

 API の使い勝手の良さもあって、Webサービスで書籍を紹介する場合、大概のサービスは Amazon へのリンクを張っています。私がよく使うはてなもメディアマーカーも同様です。レビューの充実度をみても、確かに便利なのですが、実際に買う段になると、個人的にはポイントがたまっている楽天ブックスで買いたいのです。そこで、Amazon の商品紹介ページから楽天ブックスの商品紹介ページに橋渡しをするブックマークレットを作ってみました(下のリンクをブックマークに保存すれば利用できます)。私個人で使う分には、直接飛ばしてもよさそうな感じですが、一応確認ページをはさんでいます。

 Amazon to Rakuten

 Amazon の URL に ASIN または dp が含まれている場合のみに対応しています。それ以外の場合には、うまく動きませんので、ご了承ください。

posted by まいける at 13:11 | Comment(0) | TrackBack(2) | その他