twitterのつぶやきをリスト形式でまとめる


昨日のをベースにリスト形式(ul-li)にまとめて出力するスクリプトを作ってみました。

処理の割に無駄に長いです。

昨日のtwitrss.plをベースにイロイロ追加

#!perl
use strict;
use warnings;
use utf8;
use Encode;
  binmode STDOUT, ":utf8";
use XML::TreePP;
use HTML::Entities;
use Web::Scraper;
use URI;
use URI::Escape;
use DateTime::Format::HTTP;

  my $input = $ARGV[0] or die 'no input error.';
  unless($input =~ /^\w+$/) {
    exit;
  }
  my $username = $input;

  my $base = 'http://twitter.com/';
  my($rss, $icon) = &get_uri_rss_icon($base, $username) or die('doesnot get user-code.');

  my($count, $days) = (0, "");
  for(my $i = 1; $i < 99; $i++) {
    my $twit = &get_rss_twit($rss, $i);
    unless($twit) { print "</ul>\n"; $count = $i; last; }
    foreach(@$twit) {
      my($date, $time) = &get_date_timestamp($_->{pubDate});
      my $link = $_->{link};
      my $post = HTML::Entities::decode($_->{title});
      $post =~ s/^$username: //;
      $post =~ s/\@(\w+)/\@<a href\="@{[&get_uri_reply($link, $base.$1)]}">$1<\/a>/g;
      $post =~ s/#\S+/<a href\="$base#search\?q\=@{[uri_escape_utf8($&)]}">$&<\/a>/g;
      if($days ne $date) {
        if($days) { print "</ul>\n"; }
        print "- $date\n";
        print "<ul>\n";
        $days = $date;
      }
      print "<li><a href=\"$link\">$time</a> $post</li>";
    }
  }
  print "\nscraping: $count\n";

  exit;

sub get_uri_rss_icon {
  my $base = shift or return;
  my $id = shift or return;
  my $uri = new URI($base.$id);
  my $icon = scraper {
    process 'div h2 a img', 'icon' => '@src';
    result 'icon';
  }->scrape($uri);
  my $rss = scraper {
    process 'html head link', 'rss[]' => '@href';
    result 'rss';
  }->scrape($uri);
  foreach(@$rss) {
    if($_ =~ /^($base)statuses\/user_timeline\/\d+\.rss$/) {
      return $_, $icon;
    }
  }
}

sub get_rss_twit {
  my $uri = shift or return;
  my $page = shift or return;
  my $xtpp = XML::TreePP->new() or return;
  my $rss = $xtpp->parsehttp(GET => $uri.'?page='.$page) or return;
  my $item = $rss->{rss}->{channel}->{item} or return;
  sleep(7);
  return $item;
}

sub get_date_timestamp {
  my $timestamp = shift or return;
  my $dt = DateTime::Format::HTTP->parse_datetime($timestamp)->set_time_zone('local');
  my($date, $time) = split(/T/, $dt);
  return $date, $time;
}

sub get_uri_reply {
  my $entry = shift or return;
  my $user_tl = shift or return;
  my $uri = new URI($entry);
  my $link = scraper {
    process 'span span.entry-meta a', 'link[]' => '@href';
    result 'link';
  }->scrape($uri);
  foreach(@$link) {
    if($_ =~ /^$user_tl\/status\/\d+$/) {
      return $_;
    }
  }
  return $user_tl;
}


これは引数で与えられたユーザーの呟きをリスト形式で抽出するものです。最新から順に最古の呟きまで遡ります(ビビリなので99pageまでにしてます)。あとtwitterが機嫌を損ねない様にウェイトを入れているので遅いです。

しかし・・・。う〜ん、きたないwww


とりあえず、これを書いててわかったことは、RSS2.0等でよく使われてる日付形式は DateTime::Format::HTTP でパースできます。ってことかな。

ちなみに関係無いけど最後に 'Z' が付いてるタイムゾーンって何? はてなのサービスでよく使われてるけど。


さて、もうちょっと整理して1日毎にまとめてどこかにアップするようなものに仕上げよう。まあ自分用ですけどね。出力先はやっぱハイクかなw(と思ってたけどハイクってhtml書けないのか・・・)