2010年8月31日
| コメント(0) | トラックバック(0) 昔書いたスクリプトをグレードアップした

WWW::MechanizeとWeb::ScraperでLast.fmからfreemp3をダウンロードするスクリプトを久しぶりに動かしてみたら、エラーになった…。

確認したところ、どうやらコンフィグ(Config::YAML)の使い方に問題があったようだ。
なんとも恥ずかしい。

そこで、最近使い方を覚えた小技をいくつか加えてグレードアップすることにした。
Config::Pitを使ってみたり、autodieを使ってみたり。

Config::PitはWindowsでは使えないと勝手に思い込んでいたけど、普通に使えた。
スクリプトにアカウント情報を入れなくても済むので、ブログで公開するときにも気を使わなくて済むのが良いです。
Config::Pitは、getとsetが組になっていて、まずはsetでアカウント情報を記録しておきます。
やり方は幾つかあるのですが、とりあえず今回のスクリプトに合わせて作ったスクリプトを晒しておきます。

# utf8
# use Acme::PerlTidy;
use strict;
use warnings;
use Config::Pit;
 
# 設定
Config::Pit::set(
    "last.fm",
    data => {
        username => "username",
        password => "password",
    }
);

usernameとpasswordの値を、実際のアカウント情報に変更してから実行すると、私の環境では

C:\Users\<username>\.pit

の中に、YAMLファイルで入力した情報が保管されていました。
あとは使うときにsetで使ったキー(今の場合は「last.fm」)で引いてやると、このアカウント情報がちゃんと使えます。
便利ですね。

autodieは、Fatalの自動版という感じでしょうか。
use autodieとしておくだけで、色々なエラーを捕まえてdieしてくれます。
例えば以下のようなスクリプトでは、ファイルがなかった時にはdieします。

# utf8
use strict;
use autodie;
 
open my $fh, '<:utf8', 'autodie.dat';
close $fh;

便利ですね。

8月15日のエチカの鏡を見ていて、ハーバード大学で活躍している日本人(名前は失念)の言葉が記憶に残った。

自らの手で科学を推し進めている感覚がある。 この計算が解ければ世界が変わる。

細かいニュアンスは覚えていないが、最先端にいる人の感覚が、その発する言葉から伝わってきた。
何のためらいもなく「世界を変えている」と言えることが、素直に素晴らしいと感じた。


そういう事を考えていたときに、ふと思い出したことがあった。
昨年参加したKansai.pmで話していた(というか聞いた)ことを思い出したのだ。

最先端を行っている人は、そのまま突っ走って欲しい。 色々なソフトウェアを開発したり、モジュールを作ったりする人は、初心者にわかるような詳細なドキュメントを作るよりも、もっと開発に時間をかけて欲しい。 ドキュメント作成は、ソースコードを読んでソフトウェアやモジュールを使える人がやっていくほうが、全体としてプラスになる気がする。

そんな想いを聞いたのだ。
その時に、オレもPerlの入り口に立った人に何かできることをしよう、と思ったことを同時に思い出した。

うまく文章にはまとめられないけど、書きたい、という気持ちが熱いうちに言葉にしたいと思った。
まとめようと思えば思うほど、書こうとした言葉がどこかに行ってしまうのが悔しい。

しばらく前に、POSIXにstrftimeという便利なコマンドがあるのを発見した。
DateTime等とのベンチマークだったと思う。
はてブしたハズなのだが、見つからず。
タグのつけ方が安定しない…。

ともかく。
日付時刻を表示するときは、localtimeをスカラーコンテキストで表示することが多いのだが、日本風に表示しようとすると、それなりに面倒。

my @now = localtime;
$now[5] += 1900;
$now[4]++;
printf qq{%04d/%02d/%02d %02d:%02d:%02d}, reverse(@now[0..5]);

そこで便利なのが、POSIXのstrftimeですよ。

use POSIX;
print POSIX::strftime '%Y/%m/%d %H:%M:%S', localtime;

これで同じ出力を得ることが出来る。
しかも、手元の環境では、strftimeを使ったほうが速い。

ここのところ、CGIを書く場合は、NanoAのようなフレームワークばかり使っていたので知らなかったのだが、単純なCGIを書くときに、ど派手なデバッグスクリーンをだすモジュールがあった。
CGI::ExceptionManagerの原型とも言えるか。

PerlでCGIを作成するときに、殆どの人がお世話になるであろうモジュールは、CGI::Carpだろう。
このモジュールは、一般的に500エラーと言われている「Internal Server Error」からあなたを救ってくれる。

普段、MovableTypeのプラグインでお世話になっている「小粋空間」さんが、意外なところで躓いていた。

以上です。色々調べてこれが最適解と思ったのですが、より適切な解決方法がありましたらコメントください。

「より適切」かどうかは分かりませんが、よりモダンな感じの解決方法を考えてみます。

さっきの記事を書きながら、トピックスの取得だったらRSSで良いよね、と思ってしまったので、ついでに書いてみた。

# utf8
use 5.8.1;
use strict;
use warnings;
use utf8;
 
use Encode;
use Term::Encoding qw(term_encoding);
my $enc = Encode::find_encoding(term_encoding);
 
use Data::Feed;
use URI;
 
# urlを指定する
my $url = URI->new('http://dailynews.yahoo.co.jp/fc/rss.xml');
 
# サイトにアクセスし、Feedを取得する
my $feed = Data::Feed->parse($url);
print $enc->encode($_->title)."\n" for ($feed->entries);

RSSの解析をするモジュールは色々とあるけれども、今回はData::Feedを使ってみた。

簡単!たった13行のコードでHTML取得&解析をするPerlスクリプト - DQNEO起業日記」が面白そうだったので、コードをコピペしたけど、文字化けしたので、Windowsでも動くように書き直してみた。

…かなり行数は増えましたが。

# utf8
# インスパイヤ:[Perl]簡単!たった13行のコードでHTML取得&解析をする - DQNEO起業日記 <http://dqn.sakusakutto.jp/2010/06/perlhtml.html>
use 5.8.1;
use strict;
use warnings;
use utf8;
 
use Term::Encoding qw(term_encoding);
my $encoding = term_encoding;
 
binmode STDOUT => ":encoding($encoding)";
 
use LWP::UserAgent;
use HTML::TreeBuilder;
 
# urlを指定する
my $url = 'http://yahoo.jp';
 
# IE8のフリをする
my $user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)";
 
# LWPを使ってサイトにアクセスし、HTMLの内容を取得する
my $ua = LWP::UserAgent->new(agent => $user_agent);
my $res = $ua->get($url);
my $content = $res->decoded_content;
 
# HTML::TreeBuilderで解析する
my $tree = HTML::TreeBuilder->new;
$tree->parse($content);
 
# DOM操作してトピックの部分だけ抜き出す。
# <div id='topicsfb'><ul><li>....の部分を抽出する
my @items =  $tree->look_down('id', 'topicsfb')->find('li');
 
print $_->as_text."\n" for @items;

モダンPerlの記事を読んで、Term::Encodingを知った。

ときには外からどのような入力がくるかわからない場合もありますが,コンソールアプリケーションであれば宮川達彦氏のTerm::Encodingというモジュールを利用すれば標準入出力のエンコーディングを判定できます。

今まで、手動で「cp932」と入力していたのだが、Term::Encodingを使ってやれば自動的に文字コード(エンコーディング)を判別できるではないか、というわけです。

CPANのモジュールの履歴を眺めていたら、面白そうなものがあったので試してみた。

App::Genpass - Quickly and easily create secure passwords

cpanmでさくっとインストール。
と思ったら、minicpanでミラーできていなかったのでインストール失敗。
そういう事もあるのか。

環境変数でmirror設定しているので、変更するのが面倒だったので、アーカイブファイルを直接指定するやり方でインストールした。

cpanm http://search.cpan.org/CPAN/authors/id/X/XS/XSAWYERX/App-Genpass-0.08.tar.gz

依存しているモジュールが結構あってそこそこ時間がかかったが、インストールは成功。

実行したスクリプトはSYNOPSISそのままだったのだが、Mooseに依存しているせいか動作も重い。
流石に20文字は長いが、眺めてみてもパスワードとしては遜色ない感じ。

1&3XXFXAQG8tIzAi0eC2
9Ukqb!t02bGWPyj#N&uZ
%oywF%)(#*gU%QUA9w2f
#7%A7w)RQoZGEfb$16uh
ifU91Ls2S^KzD#h$tOdu
jGIl2oc9$lTX#6MHVhwV
uiAU*uVszyxsQKY6@#Z&
z3z)%hfffgbYTqflC0rU
XGeR10#pD9g#AZ^HEXrj
Os6c4$MNlSn6XUcIzL6^

色々と細かく設定もできるけれど、すべてデフォルトでも問題はなさそう。
まあ、すべてデフォルトだったら、ここまで重いスクリプトを使うまでも無いか。

Accessorの比較は、App::Benchmark::Accessorsが有名ですよね。
しかし、NanoAで使われている、Class::Accessor::Lite等、比較されていないモジュールもあります。
Accessorとして使う分には十分な機能を持っているLiteを比較してみたかったので、いくつかのモジュールを選んでベンチマークを取ってみました。

Google検索

Last.fm

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

アイテム

  • WS000001.gif
  • pn_preference.gif
  • Satomi-Ishihara-1130277-small.jpg
  • 4d935af2889d691b3afc87f74a311d4d.jpg
  • 93acbcb501ee47c74ceaadfe48754bc1.jpg
  • 44640bcde366aab5b7a664f9f7121065.jpg

Awasete.com

あわせて読みたいブログパーツ

Blog Chart

Creative Commons License
このブログのライセンスは クリエイティブ・コモンズライセンス.
Powered by Movable Type