file-glob こと k.daibaの日記 このページをアンテナに追加 RSSフィード

2006-11-09 はじめてのircbot

はじめてのircbot

まったりとしたチャット

ircdを動かして日々の何気ないチャットをやっていたある日,

url送ったらそのページのタイトルを返してくれるボットが欲しいなぁ

という話がでてきました.これはPOEを使ってみるチャンス,ってことでircbot作りに挑戦することにしました.

サンプル

POE::Compoennt::IRCにはいくつかサンプルがついていたり,podにもサンプルがついているのですが,一番簡単なのがPOE Cookbookだったので,これをベースにしてみました.やることは簡単で,元のスクリプト

    if ( my ($rot13) = $msg =~ /^rot13 (.+)/ ) {
        $rot13 =~ tr[a-zA-Z][n-za-mN-ZA-M];

となっている部分を,urlを受け取ったらそのタイトルを返すように書き直せばいいわけです.これを実現するために見つけたのがHTML::TagParserモジュールでした.これを使うと,

    my $html = HTML::TagParser->new( "index-j.html" );
    my $elem = $html->getElementsByTagName( "title" );
    print "<title>", $elem->innerText(), "</title>\n" if ref $elem;

とするだけで,指定したhttp urlからタイトルを抜き出すことができます.さらにうれしいことには,

This module natively understands the character encoding used in document by parsing its meta element.The parsed document's encoding is converted as this class's fixed internal encoding "UTF-8".

ということなので文字コード変換までおまかせでやってくれています.後はサーバへの書き込み時点で,サーバ指定のiso-2022-jpに変換してやればOK.そんなこんなでスクリプトはこんな感じになりました.

title.pl

#!/usr/local/bin/perl

use POE;
use POE::Component::IRC;
use HTML::TagParser;
use Encode qw(from_to);
use strict;

my ( $url, $channel, $irc );

$url     = q{s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+};
$channel = '#test';

$irc = POE::Component::IRC->spawn();

POE::Session->create(
    inline_states => {
        _start     => \&bot_start,
        irc_001    => \&on_connect,
        irc_public => \&on_public,
    },
);

sub bot_start {
    my $kernel  = $_[KERNEL];
    my $heap    = $_[HEAP];
    my $session = $_[SESSION];

    $irc->yield( register => 'all' );

    my $nick = 'poe0';
    $irc->yield(
        connect => {
            Nick     => $nick,
            Username => 'cookbot',
            Ircname  => 'POE::Component::IRC cookbook bot',
            Server   => 'irc.hoge.co.jp',
            Port     => '6667',
        }
    );
}

sub on_connect {
    $irc->yield( join => $channel );
}

sub on_public {
    my ($msg) = @_[ARG2];

    if ( my ($http) = $msg =~ m/^title ($url)/ ) {
        my $title;
        eval {
            my $html = HTML::TagParser->new($http);
            my $elem = $html->getElementsByTagName('title');
            $title = $elem->innerText();

            from_to( $title, 'utf-8', 'iso-2022-jp' );
        };
        $title = 'Error to get Title.' if ($@);

        $irc->yield( privmsg => $channel, $title );
    }
}

$poe_kernel->run();
exit 0;

ちょっとした解説

http URL正規表現で書いてみる方法はPerlメモが詳しいです.ここでは,単純な場合を使っています.

$url     = q{s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+};

っていうか,複雑なケースを使う気力はあんまりないですね(笑

それから,タイトルを抜き出す部分のスクリプトが以下のようになっています.文字コードHTML::TagParser中でutf8になっているので,それをfrom_toを使ってjisコードに変換しています.

eval {
        my $html = HTML::TagParser->new($http);
        my $elem = $html->getElementsByTagName('title');
        $title = $elem->innerText();

        from_to( $title, 'utf-8', 'iso-2022-jp' );
};
$title = 'Error to get Title.' if ($@);

おわりに

PlaggerからIRCにしたりしていたら,ircbotがどんどん増えてしまいました.少しまとめる方法を考えないといけなさそうです.

miyagawamiyagawa 2006/11/09 17:16 これHTML::TagParserの中でLWPか何かでダウンロードしてTITLEをとっているんですよね。とすると、URLのサイトが重かったりするとブロックしてしまうとおもいます。POE::Component::Client::HTTP などでドキュメントを取得してからパーサにまわすほうがいいかと。

kdaibakdaiba 2006/11/10 12:07 あああ,そうですね.じゃあ,「少し手慣れたircbot」って日記で書きます(笑い

LenaLena 2007/01/26 11:52 Well done!
[url=http://atmkeavw.com/acjb/fqno.html]My homepage[/url] | [url=http://cgfhewje.com/uvbh/sxod.html]Cool site[/url]

JeanJean 2007/01/26 11:52 Well done!
<a href=”http://atmkeavw.com/acjb/fqno.html”>My homepage</a> | <a href=”http://dxkgsrwx.com/eauj/fdsc.html”>Please visit</a>

JaneJane 2007/01/26 11:52 Well done!
http://atmkeavw.com/acjb/fqno.html | http://jheqhbvm.com/mmza/ngic.html

st lucia caribbeanst lucia caribbean 2007/02/01 07:20 God bless you, nothing could now begin to read every one of my surprise, in one passage, that I was at the theatre. http://www.qvgs.com/141/st-lucia-caribbean.html <a href=”http://www.qvgs.com/141/st-lucia-caribbean.html”>st lucia caribbean</a> [url]http://www.qvgs.com/141/st-lucia-caribbean.html[/url]

NicolasNicolas 2007/04/19 11:02 http://b7804d2c4b9a43c39b6bf8eb6c77ddcc-t.gf7tiuy9.info <a href=”http://b7804d2c4b9a43c39b6bf8eb6c77ddcc-h.gf7tiuy9.info”>b7804d2c4b9a43c39b6bf8eb6c77ddcc</a> [url]http://b7804d2c4b9a43c39b6bf8eb6c77ddcc-b1.gf7tiuy9.info[/url] [url=http://b7804d2c4b9a43c39b6bf8eb6c77ddcc-b2.gf7tiuy9.info]b7804d2c4b9a43c39b6bf8eb6c77ddcc[/url] [u]http://b7804d2c4b9a43c39b6bf8eb6c77ddcc-b3.gf7tiuy9.info[/u] b8c211221d19f4c8bbabc2332ed541f5

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/kdaiba/20061109/p1