Lightweight Languageの最近のブログ記事

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;

便利ですね。

しばらく前に、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を比較してみたかったので、いくつかのモジュールを選んでベンチマークを取ってみました。

cpanmを快適に使っていますが、毎回minicpanをミラー指定するのも疲れたので、ちょっと考えてみました。

helpによると、「PERL_CPANM_OPT」という環境変数にパラメータを入れておけば良いようなので、「--mirror file:///C:/strawberry/minicpan」を指定します。
Windowsの場合、マイコンピュータのプロパティあたりから環境変数の設定ができると思います。

WS000001.gif

これで、ミラー指定をしなくてもminicpanを使ってくれるようになりました。
めでたしめでたし。

Google検索

Last.fm

このアーカイブについて

このページには、過去に書かれたブログ記事のうちLightweight Languageカテゴリに属しているものが含まれています。

前のカテゴリはLifeです。

次のカテゴリはPersonです。

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

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