2009年9月アーカイブ

いつも刺激的なインプットを頂戴している「勉強会勉強会(通称:metacon)」。
10/30、31に開催されるOSCでもセッションをやることになったので、僕も事前打ち合わせに参加してきました。

ustream.tvの録画↓

ブレイクを挟んで、意識的にUstreamの向こうの人(インターネットの向こうの人)を意識した進行になったんですが、これはやっていてすごい面白かった。
深夜番組のダルダルな雰囲気みたいな感じが最高w
タモリ倶楽部みたいですね。実際、チャットでもそういう指摘があったし。
もちろん、会議室に集ってたメンバーは皆真剣に語り合ってたんだけど。

勢い余って、二次会(会議後の飲み会)もUstで中継。会場は大手町の屋台。

録画↓

屋台とUstreamは、相性いいかもと思った。e-mobileの電波がバリバリ入るので、下手な建物の中よりも良いw

屋台に固定カメラ付けて流しっぱなしにしておくと、様々な人間模様が観察できるコンテンツソースとして使える気がしました、です。

それではお休みなさい。

確か先週の水曜日。AWS(Amazon Web Service)のお話で、えふしんさんがmovatwitterの事例を紹介してくれるというので。

主催いただいたJJUGのみなさま、会場を提供していただいたsgiのみなさま、どうもありがとうございました。

究極のスモールスタートの方法 自宅サーバからEC2へ

発表資料の掲載、ありがとうございます。数字とか読み取れなかった部分があったので、助かります。

・自宅サーバーの限界
 これは僕も興味があったので、とても面白かった。自宅でも、案外いけるようだ。
 さすがにモバツイは「案外いける」のかなり上を行ってしまったために苦労をされたそうだが。。
 僕が自宅サーバーを諦めた瞬間は二回あって、一回目は引越したとき。
 もう一回は江戸川で架線が切れて停電喰らった時。悩みが小さいなぁw

・クラウド時代になると、サーバーエンジニアが要らなくなる、というか全体で必要な人数が減る
 たしかにー。だからこそ、生き残るための方法、というかどうやったら生き残れるかを考えるのは大事だと思った。
 生き残るってのは、人生総合で生き残るって意味で、IT業界に生き残るってこと自体を見直してもいいかもしれない


■AWSから見るクラウドコンピューティング

仕事人としての意見は「自社でインフラ持つくらいなら、EC2使ったほうがいい」と、最近強く思っている。
その反面、クラウドはネットビジネスを(特に僕が仕事にしているコンテンツビジネスを)ダメにすると思うので、実はあんまり大きな期待はしていない。

映画もゲームも、新聞も漫画も小説も音楽CDも、コンテンツの基本は「前払い」だし、コンテンツ制作者サイドのキャッシュフローは基本的に「先行投資」だ。
莫大な制作予算をつぎ込む代わりに、回収するためのプロモーションにきっちりカネをかけて、動員や販売促進をきっちりやる。
だが今のWEBは違う。基本的に「タダ」だし、何らかの方法で課金をしているビジネスでも「面白いと思ったらお金を払って下さい」、言ってみれば「後払い」だ。
その後払いな課金ですら、コンテンツ制作者はエンドユーザーからのキャッシュフローをまだ確立できていない状況にあると思っている。

「とりあえず、サービスを作ってみる。スモールスタートで。
 ヒットしたらサーバーはいつでも増強できるから大丈夫」

これは、作り手の慢心を産むんじゃぁないかなぁ・・、と思うです。必死でいいものを作ろう、お客様に喜んでもらえる内容に何がなんでもしなくてはならない、という気持ちを削ぐような。

WEBコンテンツにはまだまだ可能性があると信じているし、映画やゲームと比較すると、単純にまだ成熟していないというだけなんだろうと思う。クラウドがその成熟の過程の一つなのは間違い無いだろうが、その先を見据えていないと本当の意味で「生き残る」というのは難しいだろうな、と。

そんなことを感じた夜でした。

そういえば、勉強会に参加したのも結構久しぶりだった。
やっぱいいもんだね。外にでるのは刺激になる。

今朝昨日の朝、東西線が止まって会社に遅刻した。

朝日新聞の記事が事細かに事故の経緯を報じてる。
東京メトロ東西線、衝突事故で29万人に影響

以下、要点を抜き書き。(太字にしたのは僕)

・5時間に渡って一部が不通、29万人に影響
・ポイントを切り替える操作を失念
・保守用車両には衝突を防止する自動列車制御装置(ATC)は付いていない
・国土交通省関東運輸局は9日午後、東京メトロに警告文書を出し、再発防止を指示


一方、ほぼ1年前、2008年9月14日に発生した全日空のシステム障害。
全日空システム障害の原因は伝達ミス

こちらはソースがニュース報道ではないので公平性に欠けるような気がするけど、同じ観点で要点を抜いてみる。(太字にしたのは僕)

・午前1時44分〜午前11時12分の暫定手順まで、63便が欠航、358便に遅れ、7万人に影響
・端末設計の担当者は端末認証管理サーバーの担当者が更新するだろうと思い込んでいました
・ウイルス対策ソフトのように期限切れが近づくと警告してくれるような代物ではないので、しっかり管理しないと、なかなか気がつきません
・2008年9月16日 国土交通省が全日空に早急な原因究明と再発防止を求めるよう指導

ちなみに両方とも、死傷者は出ていない。

どちらも事の顛末は「人間がミスった」ってだけ。そりゃそうだよ、どこにも完璧な人間はいないんだから。
だから仕方ないよね、というつもりも毛頭ない。けど、システム系の障害については、ITに携わっている人間が、ネットを使って後から後から色々と考察して記事を書き、ある意味祭りを盛り上げてるようにすら感じられる。

全日空に限った話じゃない。やれ、どこそこの銀行でシステム障害が・・、今度はどこどこでサーバーの障害が・・。


東京メトロの公式WEBサイトにはお詫びが掲載されているけど、
http://www.tokyometro.jp/kinkyu/48.html

全日空のケースのように、利用者に向けて再発防止策を具体的に表明するかというと、多分ないと思う。
http://www.ana.co.jp/topics/notice080914/index.html

3倍以上の人間に影響が出てるんですけどねぇ。

WEBマスターツールのhomeに戻る処理と、dashboardに遷移する部分がおかしかったので、follow_linkのURL正規表現を修正してみた。
Publish::Gmailで送信してみると、メールでこんなようなレポートを受信できる。

20090908.png
.yamlファイルで設定したGoogleアカウントで管理しているサイトについて、全部一括でレポートを作成できるようになったので、実現したいことは大体できるようになった。
文言の表示とか、テーブルそのまま取ってくるとかどうよ?みたいな、細かい部分はそのうち直す。

package Plagger::Plugin::CustomFeed::GoogleWebmasterToolReport;
use strict;
use warnings;
use Plagger::Mechanize;
use base qw (Plagger::Plugin);

sub register {
    my ($self, $context) = @_;
    $context->register_hook(
        $self,
        'subscription.load' => \&load,
        );
}

sub load {
    my ($self, $context) = @_;
    my $feed = Plagger::Feed->new;
    $feed->aggregator(sub { $self->aggregate(@_) });
    $context->subscription->add($feed);
}

sub aggregate {
    my ($self, $context, $args) = @_;
    my $mech = join('::', __PACKAGE__, "Mechanize")->new($self);
    $mech->login or $context->error('login failed');

    my $feed = Plagger::Feed->new;
    $feed->type('Google Webmaster Tool Report');
    $feed->title('Google Webmaster Tool Report on ' . Plagger::Date->now());
    $feed->link('http://www.google.com/webmasters/tools/?hl=ja');

    my @sites = $mech -> find_targets;
    my $num_sites = @sites;
    $context -> log (debug => "$num_sites");

    for (my $i = 1; $i <= $num_sites; $i++) {
        my $queries_entry = Plagger::Entry->new;
        $mech->go_top();
        $queries_entry->title("上位の検索クエリ site #$i");
        $queries_entry->date( Plagger::Date->now() );
        $mech->go_dashboard($i);
        $queries_entry->body($mech->search_queries_html);
        $feed->add_entry($queries_entry);

        my $external_links_entry = Plagger::Entry->new;
        $mech->go_top();
        $external_links_entry->title("外部リンク site #$i");
        $external_links_entry->date( Plagger::Date->now() );
        $mech->go_dashboard($i);
        $external_links_entry->body( $mech->external_links_html);
        $feed->add_entry($external_links_entry);
    }
    $context->update->add($feed);
}

package Plagger::Plugin::CustomFeed::GoogleWebmasterToolReport::Mechanize;
use strict;
use warnings;
use Plagger::Mechanize;
use base qw(Class::Accessor::Fast);

__PACKAGE__->mk_accessors(qw(mech email password start_url));

sub new {
    my $class = shift;
    my $plugin = shift;
    my $mech = Plagger::Mechanize->new;
    $mech->agent_alias( "Mac Mozilla" );
    return bless {
        mech     => $mech,
        email    => $plugin->conf->{email},
        password   => $plugin->conf->{password},
        start_url => 'https://www.google.com/accounts/ServiceLogin?service=sitemaps&passive=true&nui=1&continue=https%3A%2F%2Fwww.google.com%2Fwebmasters%2Ftools%2F&followup=https%3A%2F%2Fwww.google.com%2Fwebmasters%2Ftools%2F&hl=ja',
    }, $class;
}

sub login {
    my $self = shift;
    my $mech = $self->mech;
    my $res = $mech->get($self->start_url);
    return unless $mech->success;
    $mech->form_number(1);
    $mech->set_fields('Email' => $self -> email,
                      'Passwd' => $self -> password);
    $mech->submit;
    return if ($mech->content =~ m!
return 1; } sub find_targets { my $self = shift; return $self -> mech -> find_all_links(url_regex => qr/dashboard/i); } sub search_queries_html { my $self = shift; my $html; $self->mech->follow_link(url_regex => qr/top-search-queries/i); my $content = $self->mech->content; if ($content =~ m!(.*?
)!is) { $html = "表示回数\n"; $html .= $1; } if ($content =~ m!(.*?
)!is) { $html .= "クリックスルー\n"; $html .= $1; } return $html; } sub external_links_html { my $self = shift; my $html; $self->mech->follow_link(url_regex => qr/external-links/i); my $content = $self->mech->content; if ($content =~ m!(.*?
)!is) { $html = "サイトへのリンク\n"; $html .= $1; } return $html; } sub go_dashboard { my ($self, $number) = @_; $number += 0; $self->mech->follow_link(url_regex => qr/webmasters\/tools\/dashboard/i, n => $number); } sub go_top { my $self = shift; $self -> mech -> follow_link(url_regex => qr/webmasters\/tools\/home/i); } 1; __END__
なんとなくできた。Googleウェブマスターツールにログインして、上位の検索クエリ、サイトへのリンクを自動的に取ってくるPlaggerプラグイン。

package Plagger::Plugin::CustomFeed::GoogleWebmasterToolReport;
use strict;
use warnings;
use Plagger::Mechanize;
use base qw (Plagger::Plugin);

sub register {
    my ($self, $context) = @_;
    $context->register_hook(
        $self,
        'subscription.load' => \&load,
        );
}

sub load {
    my ($self, $context) = @_;
    my $feed = Plagger::Feed->new;
    $feed->aggregator(sub { $self->aggregate(@_) });
    $context->subscription->add($feed);
}

sub aggregate {
    my ($self, $context, $args) = @_;
    my $mech = join('::', __PACKAGE__, "Mechanize")->new($self);
    $mech->login or $context->error('login failed');

    my $feed = Plagger::Feed->new;
    $feed->type('Google Webmaster Tool Report');
    $feed->title('Google Webmaster Tool Report');
    $feed->link('http://www.google.com/webmasters/tools/?hl=ja');

    my @sites = $mech -> find_targets;
    my $num_sites = @sites;
    $context -> log (debug => "$num_sites");

    for (my $i = 1; $i <= $num_sites; $i++) {
        my $queries_entry = Plagger::Entry->new;
        $queries_entry->title('Search Queries');
        $queries_entry->date( Plagger::Date->now() );
        $mech->go_top();
        $mech->go_dashboard($i);
        $queries_entry->body($mech->search_queries_html);
        $feed->add_entry($queries_entry);

        my $external_links_entry = Plagger::Entry->new;
        $external_links_entry->title('External Links');
        $external_links_entry->date( Plagger::Date->now() );
        $mech->go_top();
        $mech->go_dashboard($i);
        $external_links_entry->body( $mech->external_links_html);
        $feed->add_entry($external_links_entry);
    }
    $context->update->add($feed);
}

package Plagger::Plugin::CustomFeed::GoogleWebmasterToolReport::Mechanize;
use strict;
use warnings;
use Plagger::Mechanize;
use base qw(Class::Accessor::Fast);

__PACKAGE__->mk_accessors(qw(mech email password start_url));

sub new {
    my $class = shift;
    my $plugin = shift;
    my $mech = Plagger::Mechanize->new;
    $mech->agent_alias( "Mac Mozilla" );
    return bless {
        mech     => $mech,
        email    => $plugin->conf->{email},
        password   => $plugin->conf->{password},
        start_url => 'https://www.google.com/accounts/ServiceLogin?service=sitemaps&passive=true&nui=1&continue=https%3A%2F%2Fwww.google.com%2Fwebmasters%2Ftools%2F&followup=https%3A%2F%2Fwww.google.com%2Fwebmasters%2Ftools%2F&hl=ja',
    }, $class;
}

sub login {
    my $self = shift;
    my $mech = $self->mech;
    my $res = $mech->get($self->start_url);
    return unless $mech->success;

    $mech->form_number(1);
    $mech->set_fields('Email' => $self -> email,
                      'Passwd' => $self -> password);
    $mech->submit;
    return if ($mech->content =~ m!
mech -> find_all_links(url_regex => qr/dashboard/i); } sub search_queries_html { my $self = shift; my $html; $self->mech->follow_link(url_regex => qr/top-search-queries/i); my $content = $self->mech->content; if ($content =~ m!(.*?
)!is) { $html = "表示回数\n"; $html .= $1; } if ($content =~ m!(.*?
)!is) { $html .= "クリックスルー\n"; $html .= $1; } return $html; } sub external_links_html { my $self = shift; my $html; $self->mech->follow_link(url_regex => qr/external-links/i); my $content = $self->mech->content; if ($content =~ m!(.*?
)!is) { $html = "サイトへのリンク\n"; $html .= $1; } return $html; } sub go_dashboard { my ($self, $number) = @_; $number += 0; $self->mech->follow_link(url_regex => qr/dashboard/i, n => $number); } sub go_top { my $self = shift; $self -> mech -> follow_link(url_regex => qr/webmasters\/tools\/home\?hl=ja/i); } 1; __END__
それにしてもひどいコードだw

Google Webmaster Tools API ってのが公開されているので、さっきのスクリプトではなくてAPI経由で取得する方が良いのかもしれない。

* Retrieve a list of the keywords Google has found on your site

これが検索キーワードの一覧を取得する、という本来の目的をちゃんと果たせればOKだよね。
これも後で試してみよう。

Googleウェブマスターツールが提供してくれる情報を、いちいち管理ツールにログインすることなく、定期的に自動取得したいのでPerlでこんなコードを書いてテストしてみた。

#!/usr/bin/env perl

use strict;
use WWW::Mechanize;
use Data::Dumper;
use FileHandle;
use Net::SMTP::OneLiner;

$Data::Dumper::Indent = 1;

my $url = 'https://www.google.com/accounts/ServiceLogin?service=sitemaps&passive=true&nui=1&continue=https%3A%2F%2Fwww.google.com%2Fwebmasters%2Ftools%2F&followup=https%3A%2F%2Fwww.google.com%2Fwebmasters%2Ftools%2F&hl=ja';
my $user_id = 'MY_GOOGLE_ACCOUNT';
my $user_password = 'PASSWORD';

sub message { print @_; }
sub abort { &message(@_); exit 8; }

# get top page
my $mech = WWW::Mechanize->new();
$mech->agent_alias( 'Mac Mozilla' );

my $response = $mech->get($url);
&abort(Dumper($response)) unless ($mech->success);


#login
$mech->form_number(1);
$mech->set_fields('Email' => $user_id, 'Passwd' => $user_password);
$response = $mech->submit;
&abort(Dumper($response)) unless ($mech->success);


# move to the page
$response = $mech->follow_link(text => 'blog.somethingnew2.com');
&abort(Dumper($response)) unless ($mech->success);


# move to detail page
$response = $mech->follow_link(url_regex => qr/top-search-queries/i);
&abort(Dumper($response)) unless ($mech->success);


# get top-search-queries-csv
$response = $mech->follow_link(url_regex => qr/top-search-queries-dl/i);
&abort(Dumper($response)) unless ($mech->success);

print ("$response\n");

詳細ページの表示は問題なし。CSVのデータもダウンロードできそうだ。

TODO:
Plaggerのプラグインにして、メール送信はP::P::P::Gmailとかで送るようにする。
→ ウォッチ対象のURLと、レポートの送り先をPlaggerの設定ファイル(.yaml)で管理するようにしたい
プラグインにするベースは AmazonAssociateReportJP.pm あたりを参考にすれば案外簡単にできそうだ。
Yahoo!サイトエクスプローラーのデータも自動取得するものも作らないと。

モバイルサイトマップを、Google謹製 sitemap-generatorsで作成できるようにしたところで、Yahoo!でもGoogleウェブマスターツール同様の機能を持ってるものが使えると教えてもらった。

Yahoo! サイトエクスプローラー

Googleウェブマスターツール同様に「サイトの確認」という作業が必要になり、そのチェッカー(ロボット)が来るアドレスが、Yahoo!のクローラーのIPアドレス帯域とは別のもの。なのでIPアドレスでアクセス制限をかけているケータイサイトは、このアドレスからのアクセスを許容してあげないといけない。

72.30.76.134

■参考 :
実践モバイルSEO講座7|携帯でしか見れない携帯サイトを作る時の落とし穴 | 携帯サイトをつくろう。

ユーザーエージェントも Slurp/Site Explorer というものなので、作りによってはちょいと面倒な作業が発生するかも。

本棚に本が入らなくなってきたので、要らない本を処分しないとどうにもならなそう。
かなり前にラジオで聴いた方法で、何年か前に実践してみたら結構良かった方法がこんな感じ。

・生半可な事はやらない。ブックオフに売るなり捨てるなり、とにかく自分のものでなくする、と固く誓う
・誓いを立てた日と、完了期限(2ヶ月後くらい)を付箋紙とかに書いて、本棚の目立つ場所に貼る
・今すぐブックオフ行く!とか思い立って、処分対象を抽出する作業を開始しない、のがコツ
・誓った日から完了期限までは「猶予期間」として確保し、この期間内に「処分しない対象」を絞り込む
・やることは簡単。猶予期間に一度でも手にした本は、本棚に戻す時に倒立させて(上下を逆さにして)戻す
・そうすると辞書とかリファレンス系の本が、どんどん倒立してくる
・レシピ本とか、図鑑とかの普段使いの本も上下逆さになってくる
・期限日を迎えた時に、本棚に正立している(ちゃんと背表紙の字がそのまま読み取れる)ものを全て処分する

期限日になっても正立している本は、
(1) 猶予期間中に一度も手にしなかった本
 → この先も読まれる可能性は低いので、処分しても問題ない
(2) 手にはしたものの、いつものクセで本棚に正立で戻しちゃった本
 →「無意識にそうしちゃうくらい価値の低い本」なので、処分しても問題ない。

確か、オリジナルのネタ(ラジオで紹介されてた方法)は、思い立った日に全部倒立させる、ってやりかただったような気がする。で、それを忠実に実行したらなんかしっくり来なかったので、微妙にアレンジを加えて上記のようなやり方になった。
なんでしっくりこなかったかは思い出せない。きっとその想い出も処分しちゃったんだと思う。

そういえばこの話をした時に、クロゼットの整理にも応用できるね、って誰かが言ってた。
洋服をわざと裏表逆に収納しておく、みたいな。

このアーカイブについて

このページには、2009年9月に書かれた記事が新しい順に公開されています。

前のアーカイブは2009年8月です。

次のアーカイブは2009年10月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 6.1.2