EDGE Now!の内部DBの代わりを外部に作る
スポンサードリンク
EDGE Now!は、参加者みんなからURLを紹介してもらっているわけですけれども、紹介してもらったURLを一覧するインターフェースがありません。
一見、LATEST SITEの欄に表示されているように見えますが、ここの欄は、午前1時のその日初のクロール直前にリセットされてしまうので、ストックされているわけではないのです。
これをストックしておかないと、特定URLがEDGE Now!にすでに登録されているかどうか分からないので、いろいろおもしろいサービスが作れません。
というわけで、EDGE Now!内部のDBの代わりに、外部でEDGE Now!に新規登録されたサイトをDBに登録してみようと思いました。
Filename: edgenow_sites.db
$ sqlite3 edgenow_sites.db SQLite version 3.1.2 Enter ".help" for instructions sqlite> CREATE TABLE urls ( id INTEGER PRIMARY KEY AUTOINCREMENT, ctime DEFAULT CURRENT_TIMESTAMP, entryid INTEGER, url TEXT, title TEXT, option TEXT ); sqlite> .schema CREATE TABLE sqlite_sequence(name,seq); CREATE TABLE urls ( id INTEGER PRIMARY KEY AUTOINCREMENT, ctime DEFAULT CURRENT_TIMESTAMP, entryid INTEGER, url TEXT, title TEXT, option TEXT ); sqlite> .q $
Filename: robot.pl
#!/usr/bin/perl use strict; use warnings; use DateTime::Format::MySQL; use DBI; use LWP::UserAgent; use URI; use URI::Escape; use utf8; use XML::RSS; use XML::Simple; binmode STDOUT => ':utf8'; # 定数 our $referer = 'http://labo.dtpwiki.jp/edgenow/index.rdf'; my $db_path = 'edgenow_sites.db'; # LWP::UserAgent 用意 our $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->agent( "EDGENow!index.rdf/0.1($referer)" ); # DB 用意 our $dbh = DBI->connect( "dbi:SQLite:dbname=$db_path", q(), q(), { AutoCommit => 0 } ); my $sth = $dbh->prepare( "INSERT INTO urls " ."(entryid, url, title, option, ctime ) " ."VALUES (?, ?, ?, ?, ?)"); my $sth2 = $dbh->prepare( "SELECT * FROM urls WHERE entryid = ?" ); # メインルーチン my $result = get_data(); #EDGE Now!からXMLデータをある分だけ取得 # 帰ってきたハッシュを処理。DBと照合してまだ無い項目を追加します foreach my $id ( sort keys %$result ) { my $hash = $result->{ $id }; my $result = $sth2->execute( $id ) or die $DBI::errstr; my $ref = $sth2->fetchrow_hashref; next if $ref; next if ref( $hash ) ne 'HASH'; next unless $hash->{url}->[0]; my $title = ref( $hash->{title }->[0] ) eq 'HASH' ? q() # NULLの場合 : $hash->{title }->[0]; # NULLでない my $option = ref( $hash->{option}->[0] ) eq 'HASH' ? q() # NULLの場合 : $hash->{option}->[0]; # NULLでない my $url = uri_unescape( $hash->{url}->[0] ); my $ctime = _date( $hash->{entryTime}->[0] ); $sth->execute( $id, $url, $title, $option, $ctime ); print "INSERT INTO urls " ."( entryid, url, title, option, ctime ) " ."VALUES ( $id, '$url', '$title', " ."'$option', '$ctime' )\n"; } $dbh->commit; # DBコミット exit; # EDGE Nowから必要分取得する sub get_data { my $refs = {}; my $i = 0; my $max; while ( 1 ) { my $ref = get_EDGENow( $i ); # EDGE Now!からページ # 指定でハッシュ取得 $max = $ref->{module}->[1]->{count} if $i == 0; # 項目数 $refs = { %$refs, %{ $ref->{siteList}->[0]->{site} } }; # ハッシュ合流 $i++; last if ($i * 5 >= $max); # もうEDGE Now!から取得しなくてよし } return $refs; } # EDGE Now!から1ページ分取得する sub get_EDGENow { our ( $ua, $referer ); my $page = shift; my $proxy = 'http://edgenow.jp/xml/edgeNow.php'; my $uri = URI->new( $proxy ); $uri->query_form( page => $page, ) if $page; my $req = HTTP::Request->new( GET => $uri->as_string ); $req->referer( $referer ); my $res = $ua ->request( $req ); my $xml = $res->content; my $xs = XML::Simple->new(); my $ref = $xs->XMLin( $xml, forcearray => 1 ); return $ref; } # EDGE Now!の日付データをMySQL形式に変換 sub _date { my $date = shift; my @s = split( ' ', $date ); my $timestamp = "$s[0]-$s[1]-$s[2] $s[3]:$s[4]:$s[5]"; my $dt = DateTime::Format::MySQL ->parse_datetime( $timestamp ) ->set_time_zone( 'local' ); return DateTime::Format::MySQL ->format_datetime( $dt->set_time_zone( 'UTC' ) ); }
実行例:
$ ./robot.pl INSERT INTO urls ( entryid, url, title, option, ctime ) VALUES ( 5670, 'http://www.suzurankai.com', 'リリー オブ ザ バレイ-サロン ド フルール 少人数制サロンの フラワーアレンジメント教室です。', '', '2008-04-14 14:11:11' ) INSERT INTO urls ( entryid, url, title, option, ctime ) VALUES ( 5671, 'http://30d.jp', '30日間限定オンラインアルバム | 30days Album™', '', '2008-04-14 14:11:11' ) INSERT INTO urls ( entryid, url, title, option, ctime ) VALUES ( 5672, 'http://tha.jp/feed', 'tha feed!', '', '2008-04-14 14:11:14' ) $
このrobot.plを、EDGE Now!のクローリング間隔である2時間ごとに回すとOK。
こうやって、DBに登録した奴を利用して、
M.C.P.C.: EDGE Now!のリンク件数を返す野良API(XML-RPC)
にて、URLから、EDGE Now!に紹介した人数が得られるようになっています。次回は、EDGE Now!に紹介した人数が得られるXML-RPCサーバのプログラムを紹介するつもり。
スポンサードリンク
トラックバック(0)
トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/2439
コメントする