2022年12月31日土曜日
このところ、ブログの広告をいじっている。
元々広告がないと収まりの悪いレイアウトだし、
Web広告の実際のところを知りたいなどの理由で広告を付けている。
ちなみに収益は微々たるもので20円/dayぐらい。
その見直しを最近やっている。
google Adsenseのサイズの違うCMをページに複数入れたのだが、
サイズ違いの同一のCMが表示されることが多くて面白くない。
そこで
A8.netに加入し、別のCMを追加した。
が、まだ面白くない。
希望としては、情報源にもなるようなCMを追加したい。
具体的にはアマゾンのベストセラーリストで
アマゾンのアフィリエイト付きのリンクが貼ってあるものを追加したい。
アマゾン・アフィリエイト提供のブログパーツとして
あっても良さそうなものだが無い。
自作することにした。
最初、アマゾン提供の
Amazon Product Advertising APIで
ベストセラー情報を取得できると思っていたができない。
雰囲気的には、昔はできていたが、できなくなった感じ。
昔はアマゾンのRSSでベストセラー情報が提供されていたが
無くなったらしい。
アマゾンの
ベストセラーのページをスクライピングして取得するものらしい。
スクライピング・プログラム
取得したベストセラー情報はデータベースに残したいので
データベースの操作に慣れているperlで作る。
Web::Scraperを使うと簡単に作れる。
以下のプログラムを作成した。
#!/usr/bin/perl
use URI;
use Web::Scraper;
use Encode;
my $url = 'https://www.amazon.co.jp/bestsellers/books';
my $sc = scraper {
process '#gridItemRoot', 'data[]' => scraper {
process 'span.zg-bdg-text', 'rank' => 'TEXT';
process 'div.a-section img', 'title' => '@alt';
};
};
for (my $pg=1; $pg <=4; $pg++){
my $s = URI->new("$url?pg=$pg");
my $res = $sc->scrape($s);
for my $d (@{$res->{data}}) {
print $d->{rank},' ',Encode::encode('utf8', $d->{title}),"\n";
}
}
ちなみに、このプログラムはWebページのデザインに依存するので、
書籍のベストセラーページでしか動作しないし、
デザインが変更されると動作しなくなる可能性が高い。
現状、動かすと次のようになる
$ perl test1.pl
#1 【Amazon.co.jp 限定】急がばナナメ(特典:おんりーのサイン&...
#2 道をひらく
#3 コミックマーケット 101 企業ブースパンフレット - クーポン...
#4 バカでも英語がペラペラ! 超★勉強法 「偏差値38」からの英会...
#5 silent シナリオブック 完全版
...
一見正しく動作しているように見えるが問題がある。
このプログラムは$url
で指定された
URLに&pg=1などのパラメータを追加し
4ページ分のデータを取得している。
1ページあたり50個のデータが掲載されるので
1位~200位のデータが取れるはずだが抜けがある。
31~50,81~100,131~150,181~200位のデータが抜けている。
原因がわからず色々調べたが
perlの LWP::UserAgentを使用すると
各ページ30個のデータしか取得されない。
それだけなら、そんなものかと諦めるところだが、
Pythonのrequestsを使用すると
50個のデータが取得できる。
LWP::UserAgentと requestsの
各リクエストのヘッダーを比較し、
実験した結果
LWP::UserAgentでも agent名に'python-requests'を
指定してやると50個のデータが取得できることが判明した。
通常のブラウザでベストセラーのページにアクセスした時も
30位までのデータを取得後、scriptで31位~50位のデータを
表示している節があるのでrequestsに対する反応の方が
特別なような気がする。
pythonのrequestsを使用しているツールを
アマゾン内部で使用しているということなのかもしれない。
最後に
そういうわけでアマゾンのベストセラー情報を取得し
表示することができるようになった。
書籍以外の物品のベストセラーや
画像を使った表示などもやってみたい。
デザインが変わり取得できなったら、
改めて対応したい。