何時でも何処でも携帯で「はてなスター」チェック

| 3 Comments | 0 TrackBacks | このエントリーをはてなブックマークに追加 このエントリーのはてなブックマーク件数

追記

コメント欄でotsuneさんにご指摘頂きました。scraperのprocess部、LWPの初期化をループ内で行わないようにしました。


やっぱり書いた記事にはてなスターが付くと嬉しいものですよね。出先でちょっとした間にはてなスターが付いているのを見て、ニタニタしたい人もいるかと思います。

でもはてなスターにはモバイルページがありません。しかもスターレポートページを閲覧するにはログインが必要になります。さて今日はモバイル端末から閲覧出来るエゴツール「モバイルはてなスターページ」を作って見たいと思います。

まずスターレポートページを見る為に、WWW::Mechanizeを使ってログインします。ログインページは

http://www.hatena.ne.jp/login?location=http://s.hatena.ne.jp/

となります。セキュリティを考慮されたいならばhttpsにされるのが良いかと思います。以下WWW::Mechanizeでログインする処理になります。

my $username = 'xxxxxxxx';
my $password = 'xxxxxxxx';

my $mech = WWW::Mechanize->new(timeout => 10, agent=>'StarScraper');
$mech->get('http://www.hatena.ne.jp/login?location=http://s.hatena.ne.jp/');
$mech->add_header('Accept-Encoding', 'identity');
my $res = $mech->submit_form(
    form_number => 1,
    fields => {
        name     => $username,
        password => $password,
    }
);

ログイン後の処理はWeb::Scraperでのスクレイピングになります。レシピは以下の通り

my $star_list = scraper {
    process 'span.entry-title',
        'stars[]' => scraper {
            process 'a', title => 'TEXT', link => '@href';
        };
    result 'stars';
};

そして上記mechをWeb::Scraperのuaに設定し、スクレイピングを実行します。

$star_list->user_agent( $mech );

my $u = "http://s.hatena.ne.jp/$username/report";
my $stars = $star_list->scrape( URI->new($u) );

さて、これだけではスターが付けられたURLの一覧しか取得出来ません。そこで、はてなスターAPIを使ってスターのエントリを取得します。はてなスターAPIのエントリ取得URLは以下の通り。

http://s.hatena.ne.jp/entries.json?uri=[URL]

このAPIに上記でスクレイピングしたURLを渡します。

my $ua = LWP::UserAgent->new;
for my $star (@$stars) {
    my $uri = 'http://s.hatena.ne.jp/entries.json?uri=' . URI::Escape::uri_escape($star->{link});
    my $req = HTTP::Request->new(GET => $uri);
    my $res = $ua->request($req);
    $res->is_success or return 0;
    my $json = from_json( $res->content );
    my @sts = @{$json->{entries}->[0]->{stars}};
}

ここで気をつける必要があるのですが、stsの要素はHASHの場合とスカラの場合があり、HASHにはスター情報が、スカラには"☆35☆"といった省略する数値が入っています。これに気をつけて以下の様に処理します。

    for my $st (@sts) {
        if (ref $st eq 'HASH') {
            print '<img src="http://s.hatena.ne.jp/images/star.gif" title="' . $st->{name} . '" />'
        } else {
            printf '<font color="#f4b128">%d</font>', $st;
        }
    }

全体のコードは以下の様になります。

#!/usr/bin/perl

use warnings;
use strict;
use URI;
use Web::Scraper;
use HTML::Entities;
use WWW::Mechanize;
use JSON;

my $username = 'xxxxxxxx';
my $password = 'xxxxxxxx';

my $mech = WWW::Mechanize->new(timeout => 10, agent=>'StarScraper');
$mech->get('http://www.hatena.ne.jp/login?location=http://s.hatena.ne.jp/');
$mech->add_header('Accept-Encoding', 'identity');
my $res = $mech->submit_form(
    form_number => 1,
    fields => {
        name     => $username,
        password => $password,
    }
);

my $star_list = scraper {
    process 'span.entry-title',
        'stars[]' => scraper {
            process 'a', title => 'TEXT', link => '@href';
        };
    result 'stars';
};
$star_list->user_agent( $mech );

print "Content-Type: text/html; charset=utf-8\n\n";
my $u = "http://s.hatena.ne.jp/$username/report";
my $stars = $star_list->scrape( URI->new($u) );
my $ua = LWP::UserAgent->new;
for my $star (@$stars) {
    printf "<a href=\"%s\">%s</a><br />&#x202C;\n", $star->{link}, encode_entities($star->{title});
    my $uri = 'http://s.hatena.ne.jp/entries.json?uri=' . URI::Escape::uri_escape($star->{link});
    my $req = HTTP::Request->new(GET => $uri);
    my $res = $ua->request($req);
    $res->is_success or return 0;
    my $json = from_json( $res->content );
    my @sts = @{$json->{entries}->[0]->{stars}};
    for my $st (@sts) {
        if (ref $st eq 'HASH') {
            print '<img src="http://s.hatena.ne.jp/images/star.gif" title="' . $st->{name} . '" />'
        } else {
            printf '<font color="#f4b128">%d</font>', $st;
        }
    }
    print "<br />\n";
}

携帯片手にニタニタしてみてはどうでしょうか。

No TrackBacks

TrackBack URL: http://perl-mongers.org/MT/mt-tb.cgi/69

3 Comments

process 'a', title => 'TEXT';
process 'a', link => '@href';

process 'a', title => 'TEXT' , link => '@href';
でok

あとforループの中で
my $ua = LWP::UserAgent->new;
でコンストラクタ走らせるとおもくね?

>otsuneさん
ありがとうございます。修正しました。

trackback送ってるはずなのに反映されてないのは気のせいですかね?

私も「はてなスター」チェックにチャレンジしてみましたー(^o^)/
http://d.hatena.ne.jp/sasezaki/20080719#p1

Leave a comment

About this Entry

This page contains a single entry by mattn published on July 8, 2008 3:09 PM.

strict プラグマについて was the previous entry in this blog.

CGI.pmのファイルアップローダ is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

Creative Commons License
This blog is licensed under a Creative Commons License.
Powered by Movable Type 4.21-en