はてなスターが適用されているページのエントリ本文を抽出する

perlで書いてみた。まだまだ適用されてるページのサンプルが少ないから変更の必要あると思う。タグ+クラス名を[h3,null]以外のサンプルを見つけられて無いのでとりあえずデフォルト固定パターンにしている。ブログによってカテゴリとかコメント欄へのリンクのパターンがさまざまなのでそれを削除する必要もある。

#!/usr/bin/env perl
use strict;
use warnings;

use LWP::UserAgent;
use HTML::TreeBuilder::XPath;
use Encode;
use Encode::Detect;

#my $url = 'http://d.hatena.ne.jp/jkondo/';
#my $url = 'http://unknownplace.org/memo/';
my $url = 'http://blog.yappo.jp/';
my $html = "";

my $ua = LWP::UserAgent->new;
my $response = $ua->get($url);
if ($response->is_success) {
    $html = encode('euc-jp', decode('Detect', $response->content));
}
else {
    die $response->status_line;
}

my $tree = HTML::TreeBuilder::XPath->new;
$tree->parse($html);

my $header_tag_and_classname = get_header_tag_and_classname();
my $headers = get_headers($tree, $header_tag_and_classname);

my $scraped_entries = [];
foreach my $header (@$headers) {
    my $header_string = $header->as_text;
    push @$scraped_entries, {
        title => $header_string,
        description => '',
    };
}

my $entries = get_entries($tree, $header_tag_and_classname);
print "[entry]", "\n";
my $i = 0;
foreach my $entry (@$entries) {
    my $entry_string = $entry->as_text;
    my $entry = $scraped_entries->[$i++];
    $entry_string =~ s/$entry->{title}//;
    $entry->{description} = $entry_string;
    print "  [ENTRY] ", "\n";
    print "    [TITLE] ", $entry->{title}, "\n";
    print "    [DESCRIPTION] ", $entry->{description}, "\n";
}

sub get_header_tag_and_classname {
    my $default = {
        tag => 'h3',
        class => '',
    };
    $default;
}

sub header_xpath {
    my($header_info) = @_;
    my $xpath = '//' . $header_info->{tag};
    $xpath .= ($header_info->{class})
        ? '[@class=' . $header_info->{class} . ']'
        : '';
}

sub get_headers {
    my($tree, $header_info) = @_;
    my $xpath = header_xpath($header_info) . '';
    $tree->findnodes($xpath);
}

sub get_entries {
    my($tree, $header_info) = @_;
    my $xpath = header_xpath($header_info) . '/..';
    $tree->findnodes($xpath);
}