・Perl の LWP::Simple で UserAgent を変更する方法は?
・Google がインデックスしている文字種は?
あたりについてつらつらと。
■きっかけ
いつもきっかけは些細なことで。
米国でRuby関連書籍の売り上げが減速か − @IT
この記事を読んでて・・・いろいろ参考になったけど、Ruby とか別の意味(宝石のルビー)を持つ単語を Google Trends でそのまま比較するなと
あれほど。
・・・と、これは今回の本題ではなくて。気になったのは C# が Google Trends の結果でちゃんと検索されていること。Google ってちゃんと # なんて記号つきの文字もインデックスしてるんだなあ。確かに C# とか C++ とかの検索で困ったことはない気がする。
実際どういう文字がインデックスされてるかちょっと調べてみることに。
■方法
ひとまず「C<記号>」で検索した結果が「C」の検索結果と同一であればその記号はインデックスされない、という判断でいいかなと。
■LWP::Simple でちょっと拾ってみる(失敗)
ということで Perl の LWP::Simple で試しにやってみる。
>perl -MLWP::Simple -e "getprint q{http://www.google.com/search?q=c}"
403 Forbidden <URL:http://www.google.com/search?q=c>
・・・あー。そういえば Google ってそれっぽい UserAgent を指定しないとダメだった。
■LWP::Simple で UserAgent を変更する
LWP::UserAgent 使えば UserAgent 変更できるけど、いきなりお手軽さがなくなるから嫌なんだよなぁ。LWP::Simple って UserAgent 変更できないの?
と、LWP::Simple ソースを読んでみると、実は
@EXPORT_OK = qw($ua);
なんてことになってて、UserAgent を外部からいじれそうなことがわかる。であれば、
>perl -MLWP::Simple -e "$LWP::Simple::ua->agent(undef); getprint(q{http://www.google.com/search?q=c});"
みたいに書けそうなもんだけど、
この書き方だと $LWP::Simple::ua が undef になってしまうので NG。これは LWP::Simple::import 内で「use のリストに $ua が指定されてたら LWP::UserAgent の初期化を行う」なんて記述がされているため。
なので、こんな感じで明示的に import 指定してやる必要がある。Windows だと
>perl -MLWP::Simple=:DEFAULT,$ua -e "$ua->agent(undef); getprint(q{http://www.google.com/search?q=c});"
こんな感じ。Linux だと
>perl '-MLWP::Simple=:DEFAULT,$ua' -e '$ua->agent(undef); getprint(q{http://www.google.com/search?q=c});'
みたいにシングルクォートで囲まないと $ua が展開されちゃうので注意。
(2011-07-30 追記)いつの間にか動くようになっているみたいです
Google は UserAgent ヘッダがなくてもちゃんとレスポンスを返してくれるらしいけど、サイトによっては UserAgent として undef じゃなくてそれっぽい値('Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)' とか)を指定してやらないとダメだと思う。
■で、インデックスされている文字は?
実際にスクリプト書いて調べてみます。
use strict;
use warnings;
use LWP::Simple qw/:DEFAULT $ua/;
$ua->agent(undef);
my @chars = (0x21 .. 0x2f, 0x3a .. 0x40, 0x5b .. 0x60, 0x7b .. 0x7e);
for my $char (@chars) {
my $content = get(q{http://www.google.com/search?q=c} . sprintf('%%%x', $char));
printf("%c - %s\n", $char, ($content =~ m{about <b>([0-9,]*)</b>})[0]);
sleep 1;
}
文字コードの指定のところがわかりにくいかもしれませんが、0x30〜0x39(0-9)、0x41〜0x5a(A-Z)、0x61〜0x7a(a-z)以外の ASCII printable characters ってことになります。
実行すると・・・
>perl -w google_check_charclass.pl
! - 4,290,000,000
" - 4,270,000,000
# - 63,700,000
$ - 4,270,000,000
% - 4,270,000,000
& - 2,290,000,000
' - 4,270,000,000
( - 4,290,000,000
) - 4,290,000,000
* - 4,880,000,000
+ - 6,600,000
, - 4,270,000,000
- - 4,260,000,000
. - 4,270,000,000
/ - 4,270,000,000
: - 4,260,000,000
; - 4,270,000,000
< - 4,260,000,000
= - 4,260,000,000
> - 4,270,000,000
? - 4,260,000,000
@ - 4,260,000,000
[ - 4,270,000,000
\ - 4,270,000,000
] - 4,290,000,000
^ - 4,290,000,000
_ - 9,560,000
` - 4,290,000,000
{ - 4,290,000,000
| - 4,270,000,000
} - 4,270,000,000
~ - 4,270,000,000
こんな感じと。「C」で検索した結果は 4,300,000,000 前後だとあらかじめわかってたので、これから大きく外れているものに注目してみます。
まずヒット数が増えてるのは *。これはまあワイルドカード指定だからそうなりますね。
ヒット数が減ってるのは #、&、+、_ の 4 文字。_ は標準的な識別子の構成文字だから当たり前として、# や + は冒頭に書いたとおり C# や C++ が引っかかってるので納得。& が入ってるのは、会社名なんかで hoge&fuga とかあるからかな?
これ以外のものはおそらくインデックスの対象外と。「1.5」みたいな文字列もちゃんと検索できるので、一概に「これらの文字が対象外」といえるわけではなさそうですけど、まあ参考程度に。