Coro::LWPを使ってPerlで非同期スクレイピング!
以前、よくわかってないながらAny::Eventの紹介記事を書きました。
Perlで非同期処理を行う - takepierrot Editor Note
正直、あれ以来ぜんぜん使っていません。Any::Eventは高機能なんでしょうが、いかんせん書くのが面倒くさいです。Any::HTTPを使いながらスクレイピングとか、自分レベルでは書く気力がわきません。
そんな面倒臭いことは抜きにして、さっさとスクレイピングを終わらせたいという人におすすめなのが、Coro::LWPというモジュールです。Coroはコルーチンという機能を扱うモジュールらしいです。Coro::LWPは、LWP::UserAgent, LWP::Simpleを、できるだけ処理をブロックさせないように処理してくれるモジュールです。Web::ScraperやWeb::QueryなんかもバックエンドではLWP::UserAgentを使っているので、Coro::LWPをuseするだけでその恩恵をうけることができます。
サンプルコードはこんなかんじです。
#!/usr/bin/env perl use v5.16; use warnings; use utf8; use Web::Query; use Coro; use Coro::LWP; use Encode; my @list = qw| http://www.yahoo.com/ http://www.yahoo.co.jp/ http://d.hatena.ne.jp/ https://creative.adobe.com/plans http://www.google.com/ |; my @coro; for my $url (@list) { push @coro, async { say encode_utf8(wq($url)->find('title')->text); }; } $_->join for @coro;
使い方は簡単です。非同期処理をさせたい処理をasyncブロック内に書いて、「@coro」配列に突っ込んできます。あとは、@coro配列の各要素から「join」メソッドを呼び出すだけです。
Web::QueryがLWP::UserAgentをバックエンドで使っているので、上記スクリプトでも「Coro::LWP」は一応効果を発揮してくれているみたいです。
スクリプトの結果は以下のとおり。
ブログなら「はてなダイアリー」 - 写真・画像・動画付き日記を無料で Adobe Creative Cloud Yahoo! JAPAN Google Yahoo!
意外とはてなダイアリーが最初に来ましたね。
スクリプト内のURLの順番と、結果のタイトルの順番がちょくちょく変わっているのが確認できます。
これなら僕でも簡単に非同期処理が書けそうです(細かな設定は放置……)。