stMind

about Arsenal, Arsene Wenger, Tech, Computer vision and Machine learning

twitterのbotとtwitter公式の検索ウィジェットを組み合わせてサイトをブログパーツ(ウィジェット)化

はじめに


秋元@サイボウズラボ・プログラマー・ブログ : twitterの公式検索ブログパーツ(ウィジェット)が登場

twitterの公式検索ウィジェットが出て、検索結果をブログパーツとしてブログに貼付けたりできるようになったみたいです。

やりたかったこと

Webページから情報を取得してTwitterにポストするボットと、ポストしたつぶやきを検索する
検索ブログパーツを作って、いろんなサイトをブログパーツ化したい!

というわけで

うごメモはてなの総合作品ランキングをTwitterにポストするボットを作って、Twitter検索ブログパーツ
ブログパーツ化してはてなダイアリーに貼付けてみよう!!

と思ったんですが、はてなダイアリーにはTwitterの検索ブログパーツは設置出来ませんでした><

どうしようかなーと思っていたところ、Operaのパネルに配置できるということをこのページ
で知り、ひとまずOperaに表示させることにしました。

やったこと

ボットの説明

うごメモはてなからのデータ取得とTwitterへのポストの大きく二つの処理があります。
データ取得では、Web::Scraperを使って

  • ランキングの日付
  • ランキングデータ
    • 順位
    • 順位変動(up, down, stay)
    • 作品のURL
    • 作者名

を取得します。
その後、Net::Twitterを使って(アカウント情報の管理にConfig::Pitを使用)、ランキングデータ一つを一つのつぶやきとして
ポストします。
ボット専用のアカウントを作る事も考えましたが、常時稼働しているサーバも持っていないし、ひとまず自分のアカウントで
ポストすることにしました。

作ったボットのソース

ソースは以下のようになりました。

#! /usr/bin/perl

use strict;
use warnings;
use Web::Scraper;
use URI;
use Net::Twitter;
use Config::Pit;

# うごメモランキングのURL
my $site = "http://ugomemo.hatena.ne.jp/ranking";

# アカウント情報の設定関数
sub set_account {
    my ($username, $password) = @_;
    my $twit = Net::Twitter->new(username => $username, password => $password);
    return $twit;
}

# うごメモランキングの総合作品ランキングを取得関数
sub fetch_data {
    my $url = shift;
    my $uri = URI->new($url);

    my $scraper = scraper {
process '/html/body/div[3]/div/div[2]/div/div', 'ranking_date' => 'TEXT';
process '/html/body/div[3]/div[2]/div/div[2]/div', 'ranking[]' => scraper {
   process '/div', 'rank' => [ '@class', sub { (/count(\d+)/)[0] } ];
   process '/div/div/img', 'updown' => '@alt';
   process 'a', 'url' => '@href';
   process '/div/ul/li', 'author' => 'TEXT';
};
    };
    my $result = $scraper->scrape($uri);
}

# ランキングをtwitterにポストする関数
sub post2twit {
    # ランキングリストを取得
    my ($list, $un, $pwd) = @_;

    # アカウント情報を設定
    my $twit = set_account($un, $pwd);

    # ランキングリストから要素を一つ取り出してTwitterにポスト
    # このとき、最後の要素はランキングの要素ではないので除外
    my $date = $list->{'ranking_date'};
    for my $i ( 0 .. scalar @{$list->{'ranking'}} - 2 ) {
        my $data = $list->{'ranking'}->[$i];

        my $a = $data->{'rank'}; 
        my $b = $data->{'updown'};
        my $c = $data->{'author'};
        my $d = $data->{'url'};

        # rank以外が定義されていなければ削除された動画と判断
        if ( !defined($b) || !defined($c) || !defined($d) ) { next; }

        # [rank](updown) author, urlの形式でポスト
        my $status = "ugomemo_bot: [$date][$a]($b) $c $d";
        $twit->update($status);
    }
}

# 総合作品ランキングを取得
my $ret = fetch_data($site);

# アカウント情報
my $conf = pit_get("twitter.com", requires => {
    username => "satojkovic",
    password => "password on twitter.com",
  });

# ランキングを1つずつtwitterにポスト
post2twit($ret, $conf->{username}, $conf->{password});

検索ブログパーツの作成

Twitter / Search Widgetのページで

  • Search Query に「satojkovic ugomemo_bot」を指定
    • ポストにはugomemo_botという文字列を指定しているので、それで自分のポストから絞り込む

して、あとタイトルやキャプションを適当に設定して作成しました。

f:id:satojkovic:20090801190228p:image

Test your settings で確認したら、Finish & Grab Codeでコードを作成します。

Operaのパネル作成

ここからはOperaで作業を進めます。

さっき作ったソースをThe data: URI kitchenでdata URI化します。
そして、出来たページをブックマークして、パネルに表示します。

出来上がり

このようになりました。

f:id:satojkovic:20090801191652p:image

終わりに

Twitterのボットと検索ブログパーツを組み合わせて、いろんなサイトをブログパーツ化できるんじゃないか
ということで、うごメモ総合作品ランキングを題材に取り組んでみました。
結局、Operaのパネル表示しかできず、ブログパーツ化できたの?という気はしますが、ボットの作成とか勉強になりました。

ボットを作らなくても、既存のつぶやきを検索するブログパーツを作ればサイトのブログパーツ化はできるので、
いろいろと試して自分なりのブログパーツを作るのも面白いんじゃないかと思いました。