今回はWebサイトをスクレイピングするにあたって、スクレイピングを効率的に行うための考え方やテクニックについて書いてみようと思います。
スクレイピングとは?
スクレイピングとは、ウェブサイト上から情報(テキストや画像など)を抽出するための技術の事です。
以前、ExcelVBAを利用して様々なサイトから情報を取得する方法についての解説記事を書きましたが、こちらで紹介している様な内容の事ですね。
効率化するメリット
冒頭で「スクレイピングを効率的に行うための考え方やテクニック」と書きましたが、効率化することでどの様なメリットがあるのかを考えてみましょう。
- データ取得が完了するまでに掛かる処理時間の短縮が見込める
スクレイピング処理に影響が出てしまう可能性があるので処理中はPC操作が出来なかったり、プログラムに気を遣ってしまって自由に操作できないなんて事は無いですか?そういうのストレス溜まりますよね。
ただでさえ時間が掛かるのにPCまで自由に操作できない・・・仕方無いから昼休みや打ち合わせの前なんかに動かして放置・・・としていたものが、トイレに行く数分の間に終わる様になるかもしれません。仕事の効率も上がりますね!
- スクレイピング対象サイトへのアクセス回数の減少
これ、なにげに重要です。
スクレイピングする側はあまり意識しない事が多いですが、される側は一つ一つのページ要求全てに応答しなければいけません。一人で何千人分に相当する様なリクエストを送り続けていたら、相手サーバの処理能力を超えてしまい、繋がり難くなるなどの影響が出る可能性もあります。
言ってみればDoS攻撃している様なものですよね。
-
【DoS攻撃】
DoS攻撃(ドスこうげき)(英:Denial of Service attack)は、情報セキュリティにおける可用性を侵害する攻撃手法のひとつ。
ウェブサービスを稼働しているサーバやネットワークなどのリソース(資源)に意図的に過剰な負荷をかけたり脆弱性をついたりする事でサービスを妨害する。
出典元:Wikipedia
https://ja.wikipedia.org/wiki/DoS%E6%94%BB%E6%92%83効率化を行う事は相手サイトへの負荷を和らげる効果もある事を覚えておきましょう。
- 相手サイトの仕様変更に強くなれる(かもしれない)
サイトのレイアウト変更が行われると今まで取得できていた値が取れなくなるという事がよくあります。
そういったケースを予測して、データの取得をレイアウト変更に影響が無さそうな場所にしておく事で、サイトの作りが変わってもプログラムを修正する必要が無くなる「かも」しれません。
ただそういう改修も収入になる案件の一つだったりするので、フリーだと程々に手を抜いt…いやなんでも無い。
とまぁこんな所でしょうか。
最後のは少し違う気もしますが、ごちゃごちゃした文字列操作の処理をスマートな形に書き直してみるのも良いかもしれませんよ。
さて、では次から具体的な効率化の方法について書いていきます。
①不要なページ移動は極力減らす
ショッピングサイトから商品データのスクレイピングを行うシーンをイメージしてみましょう。
商品の絞り込みを行い、表示された商品一覧のデータを収集する際、あなたならどの様にしてデータを取得しますか?一覧に表示された商品一つ一つのページを表示してデータを集める?
それも一つの手ですが・・・
そのデータって、本当にその商品のページを開かないと取得できませんか?
ヤフオクID取得の例
ヤフオク!を例に、検索一覧に表示された各商品の「オークションID」を取得するというケースで考えてみます。
まずはこちらが一覧画面上に表示されている商品情報。
そしてこちらが商品ページに表示されている商品情報。
オークションIDは商品ページ上に記載されていますので、一覧画面から各商品ページを開いていく方法は一見正しい様に見えますが・・・
実は最初の画像である商品一覧のページからでもこのIDの値は取得する事ができます。
先ほどの商品一覧ページに戻り、商品にマウスカーソルをあわせた状態で「右クリック ⇒ 検証(ブラウザによって変わる)」と操作し、この部分のhtmlコードを確認してみましょう。
表示されたhtmlコードをよく見てみると・・・「Product_titleLink」というクラス名を持つアンカータグの「href」という部分に、商品ページで見たオークションIDと同じ値が設定されている事に気付きましたか?
そうです。
ヤフオクの商品ページは「https://page.auctions.yahoo.co.jp/jp/auction/」+「オークションID」いうルールでURLが設定されていますので、その仕組みを理解していればわざわざ商品ページを開く必要は無いんです。
後は「https://page.auctions.yahoo.co.jp/jp/auction/」部分をReplaceなどで取り除いてあげればオークションIDのみが残るという流れです。簡単ですね。
ヤフオクの商品一覧は最大で100件の商品を表示する事が出来ますが、これにより商品ページを一切開くこと無く100件分のデータを取得できる様になりました。
- ページを開いて
- オークションIDを読み取って
- ページを閉じる
という動作が大体2~3秒で終わるとしても、100件あれば最大300秒です。
それが単純に1秒で済む様になれば処理時間は1/300。かなりの効率化になりますね。
スクレイピングにおいて最も時間の掛かる処理は「ページ移動に伴うデータの読み込み」ですので、いかにページ移動を減らすかが効率化のカギになります。
楽天市場 商品名取得の例
ついでにもう一つ、楽天の例を紹介しておきます。
楽天市場の商品一覧ページを見てみると、下図の様に商品名が長い商品は途中で切れて「・・・」となってしまっているのが分かりますね。
データ収集する場合はやはり全文欲しい所。
早速商品ページに移動・・・ではなくまずはhtmlコードを見てみましょう。
ブラウザ上では途中で切れて表示されていましたが、imgタグのalt要素(赤枠部分)を見ると商品名全文を確認する事ができますね。
という事でわざわざ商品ページに行かずとも商品名は取得できるのです。
データは意外と見えない所にも存在しています。
中身(htmlのソースコード)まで確認する事が大事ですね。
②必要な情報以外は取得しない
情報はあればあるだけ良いと思って、使わないデータまで取得していませんか?
「将来的に使う可能性が・・・」ならまだしも、「とりあえず取れるデータは取っとけ!」という理由で集めているデータがあるなら、一度見直して見た方が良いかもしれません。
これは一つ前の内容にも関連していますが、「無くてもいいデータ」を取得するためだけにページ移動をしているのであれば、その分だけページ移動の時間が無駄に掛かってしまいます。効率化の基本はとにかく「無駄を減らす」事です。
■必ずしも必須データと一緒に取得する必要は無い
■必要な時に確認できれば良い
という程度であれば「URLだけ控えておいて後で個別に取得する」、「必要な時だけ取得しにいく」という処理にすれば良いですね。
まだまだ続きます。