M.C.P.C.

―むり・くり―プラスコミュニケーション(更新終了)


| トップページ |

2009年10月29日 12:30

Adobe Creative Suite 出力対応店一覧をGoogle Mapsで表示させる(4)

このエントリーをはてなブックマークに追加 mixiチェック

アドビのCS4対応プリントショップのリストのページから、Google Mapsに表示させるやつの4回目。

前回は、アドビのサーバからHTTPステータスコードが200ばっかり返ってくるので、ステータスコードは使えないから、HTTPレスポンスヘッダを見てみよう、ということで、FirefoxのLive HTTP Headersという機能拡張を入れて調べたところ、ヘッダからはコンテンツの更新がわからないということがわかりました。ということは実際に取得してみなくてはわからないと言うことになりますが、どうしよう? ていうところまでやりました。

さて、アドビのサーバは、「取得したデータは取得した側で6時間キャッシュしてね。内容変更はヘッダでは教えてあげないよ。」と言っているわけなので、まず、6時間ごとアドビのサーバから取得すればいい、という方針が立ちます。従って、取得する部分は6時間ごと実行するようにcronに設定すればいいかなあということになります。

また、6時間ごと取得しても、内容に変化がないことがあるのも予想されますので、「内容に変化がない」ことを検出する仕組みを作らなくてはなりません。どうしよう。

そこで、今回は「取得したHTMLの長さを比較する」方法でいきたいと思います。なお、この方法は、AdobeさんがPDFの改変チェックで採用している由緒正しい古式ゆかり方式です。PDFのチェックサムの再計算とか知らなかったとき、ゲームのセーブデータをいじるがごとく手法でPDFをいじっていたのを思い出します。

今回のコードはこんな感じです。

#!/usr/bin/perl
 
# Filename: test3.pl
 
use strict;
use warnings;
use URI::Fetch;
use Cwd;
 
# GETしてきたコンテンツの長さを記録するファイル
my $cwd = getcwd; # カレントディレクトリ
my $length_file = "$cwd/length.txt";
# GETするコンテンツのURL(STATUSが常に200なので
# 内容変更調べるにはコンテンツの大きさを使う)
my $url= 'http://www.adobe.com/jp/print/printshop/';
 
# main
 
my $html = get_html($url);
print "modified:\n" if $html;
 
exit;
 
sub get_html {
  my $url = shift;
  # length.txtから前回取得時のコンテンツの大きさを
  # 取得するよ
  my $length = 0;
  if ( -e $length_file ) {
    open my $fh, '<', $length_file or die $!;
    $length = <$fh>;
    close $fh;
  }
  # Webからコンテンツを取得するよ
  my $ua = new LWP::UserAgent;
  $ua->timeout(10);
  $ua->agent('DTPWiki.jp AdobeJpPrintShopMap/0.1 '
           . '(+http://labo.dtpwiki.jp/printmap/)'
  );
  my $res = URI::Fetch->fetch(
    $url, UserAgent => $ua,
  ) or die URI::Fetch->errstr;
  my $html = $res->content;
  # 今回取得したWebコンテンツの大きさを記録するよ
  my $length_new = length($html);
  {
    open my $fh, '>', $length_file or die $!;
    print $fh $length_new;
    close $fh;
  }
  # 前回と大きさが変わらない場合はundef、
  # 変わっている場合はコンテンツを返すよ
  return ( $length == $length_new
             ? undef
             : $html
         );
}
 
__END__

実行結果:

$ perl test3.pl
modified:
$ perl test3.pl
$ cat length.txt
188685$ cat > length.txt 
120000
$ perl test3.pl
modified:
$ cat length.txt
188685$

1回目は更新と検出、2回目は変更なしと検出、length.txtファイルにはコンテンツのサイズが入っています。意図的にlength.txtファイルを書き換えてやると、その次に取得した場合は変更ありと検出されていることが確認できました。

ちなみに、length.txtに記録されるのは、HTTPレスポンスヘッダのContent-Lengthの値ではなくて、実際データとして利用できるコンテンツのサイズです。アドビのサーバからは、GZipエンコーディングで圧縮された状態で送られてくるのですが、URI::Fetchが自動的に伸張するのですね。

泥臭いですが何とかアドビさんからHTMLをGETするところができました。

次回は、いったんWebやHTTPから離れて、HTMLを解析するところをやりたいと思います。


(2009-10-30 14:00修正)

<del>由緒正しい</del><ins><a href="http://www3.airnet.ne.jp/gomimemo/tmron/yukari.htm" target="_blank">古式ゆかり</a>な</ins>

ブックマークのコメントで、「ダメな手法を真似したらダメ。ギャグのつもりならネタだと分かるようにかいてほしい」とOtsuneさんから指摘があったので、ギャグにしました。念のため、古式ゆかりは本命キャラ攻略失敗時に出てくるキャラです。

アドビの擁護をするならば、PDFはバイトサービングなどの細切れで転送される用途もあったため、ファイル全体のハッシュ値でファイルの健全性を確認する手法は使えなかったのかもなあと思っています。

投稿 大野 義貴 [GoogleMaps] | |

トラックバック(0)

トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/3020

コメントする