Amazonで物販をしていると、いろんなwebサイトからデータを取得したいということがあります。
たとえば商品の情報・データとか。
- Amazonなら価格や出品者数
- モノレートならランキング変動回数など。
Amazonであれば、MWS APIやPA-APIといった、AmazonのAPIを利用することで効率よく、かつ、webサイトの正面玄関から堂々とデータを取得することができます。
しかし、AmazonのAPIだけでは取得できないデータもたくさんあります。たとえばセラーIDをもとにした扱っている商品の一覧など。
そういった場合にはAPIを使うのではなく、webスクレイピングという技術を使うことになります。
webスクレイピングってなに?
このwebスクレイピング、今回わけあって本腰入れてかなり調査・検証をしておりました。
今回はこの先、誰かがAmazonを使った物販でwebスクレイピングしたい、という人に向けて、わたしがハマった点について書き残しておきます。
webスクレイピング・クローリングのプログラムの種類
webスクレイピング・クローリングの方法としては、大きく分けて3種類あります。
まずは概要からご紹介します。
ブラウザを遠隔操作したwebスクレピング・クローリング
IE OLEを使ったプログラム
Microsoft謹製のアプリケーションにはOLEという名前の自動化・遠隔操作機能を持っています。Microsoft謹製のアプリとは、
- Internet Explorer
- Excel
- Access
などなど。Wordとかも全部そうですが、列挙すると大変なので主にOLE機能が使われる傾向のあるアプリケーションを列挙しました。
わたしがよくやる・好んで使うのはIEのOLEを使ったものです。プログラムがIEを遠隔操作し、IEが取得したデータを解析するというタイプ。
少し前まではこれで十分でしたし、わたしのPC環境でもこれで十分です。
しかし、実際にプログラムを色んな人に使ってもらった結果、環境に依存する問題がチラホラ挙がってきました。orz
どういう問題かというと、
- プログラムが生成したIEのコントローラ的なものを見失う。(実行中にIEオブジェクトのインスタンスが消失する)
- IEのコントローラ的なものを終了させても、終了できない。
IEの最新バージョンでは1つのタブでwebページを遷移していても、内部的には別ウィンドウとして扱われることがあるようです。
これはセキュリティに関するものであるという意見がweb上の情報ではよく見かけられますが、どうがんばっても対処不能。
ただ1つ言える絶対的なことは、
- IE OLEはオワコン(終わったコンテンツ)
IE OLEはVBスクリプトでも使えるのでかなり重宝していたのですが…。
VBスクリプトはコンパイル環境不要で手軽に書けてすぐ動かせるプログラムだったので好きだったのですけどねぇ。
seleniumを使ったプログラム
ブラウザの遠隔操作プログラムとして有名なのがseleniumというものです。
seleniumってなに?
OLEがIEに限定されたものに対し、seleniumはIEだけではなく、Firefox・Googlg Chrome、これらも遠隔操作ができるものです。
こいつについて調査して使ってみたのですが…。使った瞬間わかった。
- seleniumはOLE以上に、環境に強く依存する
どう依存するかというと、ブラウザのバージョンです。FirefoxやChromeブラウザに更新が入る度に、seleniumも最新版にアップデートしたりする必要が出てきそうだと判断しました。
場合によってはダウングレードも必要でしょう。あまりにもめんどくさすぎます。
seleniumはあくまでもweb系のエンジニアがテストするために用いるもの、といった感じですね。
ブラウザをプログラム内部に埋め込んだwebスクレイピング・クローリング
C#やVBAにもあるのですが、ブラウザをプログラム内に埋め込むためのライブラリが用意されています。
- WebBrowserクラス
ちょっとこいつを使ってみました。
…しかし、こいつも結構クセがあることがわかりました。orz
どうやらWebBrowserクラスにはもともとバグがあるようです。メモリが解放されないというスーパー致命的な不具合です。
長時間使っているとメモリを食いつぶしてアプリが落ちます。ハード的なメモリを全部を食い尽くすのではなく、WebBrowserクラスが使えるメモリの総量が決まっているようです。
と思いつつも、こいつをどうやってうまく使っていくか、ということを考えていました。
結果、WebBrowserクラスを使ってwebスクレイピング・クローリングをやる場合には、専用の別アプリにしておくという結論になりました。
メモリ解放漏れという致命的不具合があっても、アプリケーション自体を終了させればメモリ解放漏れも解消できますからね。
- WebBrowserクラスを使ったアプリを、こまめに起動・終了を繰り返す制御アプリを別に作る。
たとえば、webサイトAからデータを取得したいとして、『webサイトAから10ページ分のデータを取得する』というプログラムを『100回繰り返す』という制御アプリを作る、というイメージです。おかげさまでデバッグが大変です。
HTTP通信をトレースしたwebスクレイピング・クローリング
ここまで説明してきたことは、どちらかというとwebスクレイピングではなくクローリングと呼ぶのが適切でしょう。
webスクレイピングというのは、最小限のHTTP通信のみを行うプログラム・その行為を指すとわたしは認識しています。C#ならHttpClientクラスを使ったものです。
- webスクレイピングなんて簡単だぜ!
- プログラムのド素人だけどwebスクレイピングツール作ってみた!
…とかいう意見をネット上でたまに見かけますが、わたしとしましては『ちょっと待った!』と言いたいところだったりします。
webスクレイピングというのは、単純にwebサイトからデータをダウンロードすれば良い、というだけのものではないと思っているからです。
わたしがこういったツールを避けてきたのには理由があります。まずは下記をご覧ください。
これはWireSharkというパケット解析ツールを使った結果です。Amazon Primeで配信されている『フェイス サイバー犯罪特捜班 』というドラマでも登場したツールだったりします。使い手によって善にも悪にもなるツールです。
HTTP通信をトレースするということは、ざっくり言ってしまえばインターネット通信プロトコルを理解し、実際に通信したログをプログラムを使って再現させるようなもの。
webサイトによりますが、完璧にトレースできなければアクセスブロックされる可能性があります。
これはちょっと大変…。なので、わたしは好んでブラウザを遠隔操作するようなプログラムを作っていました。
ぶっちゃけ、WireSharkをしっかり使いこなせるエンジニアっていうのは上位35%程度だと思ってます。(ちなみにわたしはたいしたことないエンジニアですがネットワーク関係の仕事しているので知っているだけです。)
よくわからない人には、こうやって画像にモザイクかけることすらできないはずです。
ゆえに、webスクレイピング系のツールを本当の意味でしっかり作るというのは難易度が高い部類です。Amazon API使うプログラムのほうが10倍は簡単ですね。
ブラウザを操作する系のwebスクレイピング・クローリングの良いところ
ブラウザを遠隔操作したり、埋め込んだプログラムのメリットとしましては、上述したようなHTTP通信を考える必要がないことです。
webサイト側からすればアクセスしてきたのがwebスクレイピング・クローリングツールには見えず、人間がブラウザを操作してアクセスしてきたようにしか見えないんですよね。
ですが、webサイトによっては1日にアクセスできる回数が決まっていたりもするようですし、バレないから大丈夫といって過度なアクセスをしてサーバに負荷を与えるのはよろしくないです。
さらにありがたいのが、ブラウザの機能を使うのでDOM操作ができることです。
DOM操作とは、たとえばブラウザ上のボタンを押したりjavascriptを実行させたり、webページを編集したり。
ブラウザを操作する系のwebスクレイピング・クローリングの問題点
わたしは好んでブラウザを操作するタイプのwebスクレイピング・クローリングを作ったりしましたが、問題点がいくつかあります。
- ブラウザ・環境に依存する
- webページの遷移(ページ送りなど)でコケる
環境依存が強いというのが一番の問題ですね。セキュリティ関係やブラウザのバージョンなど、完璧なプログラムを書くのは実質不可能です。
あとから問題が出て来る、ということもあります。おそらくWindowsのアップデートにひもづいてIEがアップデートされたり、とか。
しっかり作り込んでも、環境しだいでブラウザ自身がwebページの遷移にコケることもあります。
ちょっとデータを取りこぼしただけでも、プログラム的にはうまく解析できなくなってしまったり。
まとめ webスクレイピング・クローリングするならブラウザを取り込むかHTTP通信をトレースする
- IE OLEはオワコン
- seleniumは開発者向け
- WebBrowserクラスはバグあり
- WebBrowserクラス使うならこまめに起動・終了を繰り返す制御アプリ必須
- HttpClientクラス使うならHTTP通信はトレースしたほうが良さげ
- 開発者のたしなみ。ちゃんとインターネッツプロトコルは理解した上でWireShark使おうね
わたしの本業はアプリ屋さんではなく、ネット屋さん?ファーム屋さん?ちょっと曖昧ですが、インフラ周り?なエンジニアです。
わかっている人はこういったことにすらハマらないことでしょう。精進します…。
結論としては、webスクレイピングやるなら、最終的にたどり着くのはやはりHttpClientを使ったタイプのものでしょうね。
どうやらここは避けて通れなさそうです。ちょっと勉強したいと思います。
Amazonをwebスクレイピングするサンプルプログラムを価格改定ツールのプライスター・マカドの特典として公開しています。もしよければご検討ください。