この記事は CAMPHOR- Advent Calender 2015 延長戦、29日目の記事です。
今回はスクレイピングについてです。スクレイピングのやり方なんかは他にたくさん記事が上がっているのでそういうのはやめて、昔クローラーとしてたくさんのサイトを継続的にスクレイピングして回っていた(google botかな?)ときに経験したことについて書いていこうかなと思っています。これからクローラーを構築しようとしている方の参考になればと。
DOS攻撃をしない
基本ですね。スクレイピングをするときはサーバーへの負荷も考えて、あまり一度にたくさんのリクエストを送らないようにしましょう。
サイトのリニューアルを検知
webサイトは時として何の前触れもなくリニューアルがされて全く違う構造になることがあります。ECサイトなんかは企業の買収や合併も激しく、リニューアルも頻繁に行われることでしょう。イケイケなテック企業だったら突然フロントエンドにReact.jsを導入したりすることでしょう。ですので、そういったときにすぐ気づけるよう、大きくDOM構造が変わった時やそれまで取得できていた情報が取得できなかったときには検知できるようにしておきましょう。
情報の更新
店舗やホテルの予約状況、商品の在庫数や価格など、ページの情報は日々変化していきます。こちらで持っている情報も更新できるように一意の値をつけて管理したいです。ページのURLだけで判断すると、キャンペーンなどのLPから来た場合には通常とURLが異なるなどの場合に対応ができません。品番や店舗コードなどの一意の値で管理したいところです。(とはいえ、大規模リニューアルの際にはそれすらも変わることがあります...)
リダイレクト
商品が売り切れたり店舗がなくなったときに違う商品や店舗のページにリダイレクトをかけるようにしているサイトがあります。また、ステータスコード200を返して404 Not Foundと表示されたページに誘導したりといったサイトもあります。h1タグの内容をチェックするなどの対策も考えておきましょう。
イベント発火・Ajax通信
静的なHTMLを取得してスクレイピングというのが通用しないサイトがあります。クリックイベントによるAjax通信が必要な場合などです。どうにかしてイベントを発火しましょう。選択肢としては PhantomJS やそれをラップした CasperJS を使うなどがあるかと思います。諦めず戦いましょう。
関連リンク
- 【連載】CasperJS でスクレイピング (1) - CasperJS の基本
- [CasperJSで動的ページをスクレイピング、あるいは毎月100円ゲットする方法について] (http://blue1st.hateblo.jp/entry/2014/11/09/064556)
クエリパラメータに注意
少し細かい話になりますが、ページ番号をクエリパラメータに含めたりする場合( http://example.com?page=2 など)に、最後のページの数字より大きい数字を指定した場合にページ内容が最後のページのまま変化しないということがあります。スクレイピングが終わらなくなってしまいます。大抵の場合は最後ページ以降への導線がなかったりするので、リンクが存在するかチェックしましょう。
まとめ
いかがでしたか?スクレイピングを継続してやるのは結構大変です。とはいえ欲しい情報を勝手に取ってきてくれるのはなかなか爽快なものです。
最近は AirbnbScrape というのを教えてもらったのですが、Airbnbのスクレイピングなんかは面白そうでぼくもやってみたいなぁと思っています。
明日の30日目は3回目の @ryota-ka の記事です!