何がどう「正しく取得できなかった」のでしょうか?
こちらで試した限りでは特に問題なく動くように見えます。
以下コードを実行してみたのですが内容を正しく取得できませんでした。
どのようにすれば正しく取得できますでしょうか?
perl
1use strict; 2use LWP; 3my $url = 'https://books.rakuten.co.jp/rb/15296059/'; 4my $ua = LWP::UserAgent->new; 5# $ua->ssl_opts( verify_hostname => 0 ); 6$ua->timeout(60); 7my $res = $ua->get($url); 8my $source = $res->content; 9open( F, ">source.html" ); 10print F "$url\n$source"; 11close(F);
403 が返ってくることを「正しくない」とおっしゃってますかね。おそらくですが楽天側で UserAgent をチェックしているのではないかと。(文意が伝わりにくかったので修正)
返信を見落としていました。すみません。
UAについては色々と試してもみたのですが403が帰ってくる感じで困っています。
楽天のHPに1日3回アクセスして「取り寄せ」の文字が消えたら、PCから音を出すようなプログラムの一部になります。
curl で試したところ、現時点ではUserAgent を見ているのは間違いなさそうです。ただ、楽天側が何をもってクローラと判定するかは楽天側の実装によりますし、将来にわたって判定方法が一定とも限りません。こうすれば必ずクローラ判定を回避できるという方法はありません。
$ curl -s -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" https://books.rakuten.co.jp/rb/15296059/ | grep '<title'
<title>楽天ブックス: 初めてのPerl 第7版 - Randal L. Schwartz - 9784873118246 : 本</title>
$ curl -s https://books.rakuten.co.jp/rb/15296059/ | grep '<title'
<title>指定されたページはアクセスが)限されています(エラー403)</title>
ところで、楽天の利用規約によればクローラによるアクセスは禁止されています。
https://corp.rakuten.co.jp/copyright/
> 当社は当社による明示的な許諾がない限り、当社のサービスを通じて提供される全てのコンテンツ及びその編集物について、第三者による複製等一切の利用及び、クローラーなどのデータ収集・抽出ツールの使用、データマイニング等の行為を禁止致します。
楽天と直接交渉して許可を得るか、API を用いてアクセスしましょう。楽天ブックス総合検索APIでは在庫情報もレスポンスを返してくれるようなので、お望みのことが実現できるのではないでしょうか。
https://webservice.rakuten.co.jp/api/bookstotalsearch/#outputParameter
コメントいただきありがとうございます。
そのUA指定でもダメだということは、UA以外を主に見ているのではないでしょうか?
また、1日3回、1ページのためにAPI登録は流石に面倒過ぎます。
そもそもですがブラウザもクローラーも何も変わらなくないでしょうか?例えばアドオンに自動更新をつけて指定文字の消失で音がしたらそれはブラウザだからセーフというのもおかしい気がするのです。perlのLWPであれば(テキスト)ブラウザといっても差し支えないと思いますし。また、規約を遵守する場合でもデータの収集や抽出を行わずマッチのみ検知で音がするものであれば問題ない気もしています。
>1日3回、1ページのためにAPI登録は流石に面倒過ぎます。
登録は最初に一度だけ実行すればいいのです。
>perlのLWPであれば(テキスト)ブラウザといっても差し支えないと思いますし
それらの判断を下すのは楽天であってあなたではありません。自分の考えではOKだといくら主張しても通らないものは通りません。
楽天側がAPIを用意し、これを経由したアクセスは認めると公にしているわけですから、確実性においてこれ以上のものは考えられません。それに、「クロール」してきたhtmlファイルには見栄えを整えるための余計なコードが山ほどくっついてるはずで、そこから必要なデータを抜き出してくるのも大変じゃないですか? APIに移行しない手はないと思います。
私の考えというよりも常識かと。また、収集や抽出、データマイニングではありませんので特に問題ないかと。本題とかなり外れてきますが、そもそもネット空間にパスワード無しで公開されている情報へのアクセスは基本的には自由かと思います。相手のサービスを落とほどのアクセス(岡崎市立中央図書館事件など)など極めて重大な問題があれば別ですが(それでも無罪でしたが)、そうでない限り会社独自で規約を作っても法律上問題がないかと。もし、問題あるという場合、できればその法律を教えていただければ幸いです。
APIは継続的なアクセスがあるならわかりますが、ブラウザでの目視代わりに在庫が入ったかどうかをちょっとチェックする程度ならAPIのドキュメントを読む必要もなく、$_ !~ m/Word/で在庫切れがなくなったことはすぐに判明しますので簡単です。もう少し言えば、この手のプログラムは楽天以外の様々なサイトでRSS配信のないページでも実質自作のRSSとして使え結構便利ですよ。
だ・か・ら、あなたの「常識」なんか関係ないんですよ。楽天がどういうアルゴリズムでNG判定しているか分かりませんが、それが「常識」に沿っていようと居まいと、「法律」との整合性があろうとなかろうと、楽天がダメと判断したら、ダメなんです。
「簡単だ」と貴方はいいますが、事実、問題に引っかかっていて数週間も解決できずに引っ張ってるんでしょう? 全然簡単ではないではないですか。より確実に解決に至れそうな手段がそこにあるのに、なぜそれを試さず、最初の方針にグダグダ拘っているのですか?
私ではなくオープンなネットの世界の常識かと。また、良いリクエスト方法があれば問題ない話で簡単か難しいかはアルゴリズム次第かと思います。
確実な方法としては、実はPythonでの実装は成功しています。雑誌掲載のサンプルプログラムそのままで動作しました。ただ、慣れ親しんだPerlでもできればと思い質問しています。楽天以外にも様々なサイトがありこのような問題はこれからも発生します。その度に規約を読みAPI契約をするなど汎用性がなく面倒なので今回遭遇した事例を解決できればと思っています。その為、拘っています。
あなたの回答
tips
プレビュー