お久しぶりです、エンジニアリードのSakaeです。

本技術ブログ解説以来、弊社スクレイピングエンジニア達がクローリング/RPAにまつわる様々な基礎技術や、クローラーをサーバー上で稼働させるための環境構築方法などについて個別に記事を書きためて来ました。

ここらで、これらのバラバラな基礎技術どうしを一本に繋げて、スクレイピング初級者の方でもモリモリデータ収集を行って頂けるような、1から10まで・・・とはいかないものの、1から5までくらいの技術が身につくまとめ記事を書きたいと思います。

まずはスクレイピングエンジニアとしての心得を学ぶ

拙記事で恐縮ですが、スクレイピング/クローリングエンジニアとはどのような職種で、どのような思考回路が求められるのか?また、データクローリング(データアグリゲーション)が活用されるビジネスの世界について頭に入れて頂ければと思います。

クローラーやbot(ボット)を作る前に、まずRuby実行環境構築

クローリングを始めるために、まずRubyの環境構築が必要です。PythonやJavaScriptなどなど、他のプログラミング言語でももちろんスクレイピングはできますが、Rubyはスクリプト言語、で同期的に動作し、比較的定番化されて選びやすいライブラリ類(Gem)が揃っているのもあり、初心者でも比較的理解がしやすいのと、なによりNokogiriという非常に便利なHTMLパーサーが存在することもあり、弊社ではRuby押しでクローラー開発を進めております。

まずは下記の記事を参考にRubyでクローラーを作成する下準備をして下さい。

クローリングのスイスナイフたる様々なスクレイピングツール達

いよいよクローラーを作って行きますが、ひとえにクローラーと言っても内部的なアプローチ方法には様々な手法があります。ただ、どの方法にも共通しているのが、ようはWebページにHTTPリクエストを送り、レスポンスを受けるということです。

Rubyではクローリングに利用できるライブラリ群が充実しており、HTTPの通信のやり取りを便利にしてくれるツールや、Cookieの管理をしてくれるツール、ほとんどブラウザと同じようにJavaScriptを実行してくれるツールなど、様々なアプローチを選択することができます。そのため、得たいHTTPレスポンスの形に合わせて、スイスナイフのようにどのツールが最適かを選ぶスキルが重要になってくるわけです。

ということで、スクレイピングエンジニアが愛用するスイスナイフのごときツールや手法をご紹介していきます。

まずは何はともあれ、Webサイトのコンテンツを取って来る

「習うよりクローリングしろ」、「考えるなスクレイピングしろ」、そういう過去の偉人の残した格言にならい、まずはHTMLを取ってきてみることから始めましょう。

とりあえずコピペだけでで悩まずにスクレイピングすることのできる(Rubyに標準バンドルされている)open-uriやnet/httpを使った方法で、あなたのターミナルでクローラーを動かして見て下さい。基礎的な手法ではありますが、実はこれだけでも大抵のことができますし、余計なGemも使わず、メモリにも優しく、そして、何より高速にデータを集めることが可能です。

プログラムからHTMLが取って来れるようになっただけで、まるでこの世の全てが手に入るかのような錯覚に陥りますが、最初はその錯覚に浸ってみるのもまた良しです。その「初めて自動的にデータを取ってこれた!」という感動を忘れないで下さい。

クローリングの理解に必須なHTTPの仕組みとHTTPの解析方法を学ぶ

open-uriなどで手元にHTMLを取って来れる感動を覚えたら、次に簡単にその裏側で動いているHTTPの世界にも一歩踏み込んでみましょう。基本的にWebの世界はこのHTTP通信上で構成された世界です。スクレイピングエンジニアはこのHTTPの流れを追っていく人たちです。後述のselenium x Chromeなどのツールを使うと、何も裏側の技術が分からなくてもあっさり目的のWebサイトのデータを取って来れたりしますが、ツールの便利さに頼りすぎず、HTTPの概念や解析手法もきっちりと身につけておいて下さい。

ログイン必須のサイトでHTTPヘッダやcookie(クッキー)を保持しながらのクロール

クローリングロボットを作り始めて最初の壁になってくるのが、ログインが必要なWebサイトのページ遷移です。このあたりにくると、Webサイト/Webアプリを作成するのに必要な、セッションやCookieという概念が登場します。

HTTP通信はステートレス(状態を保持しない)なので、基本的にはログインしているかどうか、ログインしているのが誰なのかというのを把握するために、HTTPのリクエストヘッダ情報や、Cookieの情報が利用されます。つまり、ログインが必要なWebサイトなどでは、ユーザー情報を表す特定の情報を保持し、HTTPのリクエストにそれらの情報を付与しながらクローリングする必要があるわけです。

そういったCookieなどの情報保持を、裏側で自動的に行ってくれるのがMechanizeです。ログインサイトやセッションが保持されるようなサイトの場合、素のRubyで戦うよりもコード量をグッと減らしてくれる強い味方です。ぜひ使ってみてください。

Javascriptにより動的にコンテンツ生成されるサイトをクロールする

さらにさらに、クローリングをしていくとぶつかる次の壁が、自分の端末のChromeで見たときのHTMLとクローラーが取ってきたHTMLの中身が違う!!という問題です。例えば、Chromeブラウザで見ると「XXランキング」という表があるのに、クローラーでみると「XXランキング」部分の表(tableタグ)がゴッソリ消えている・・・。という感じです。

そんなときはたいてい、JavaScriptがサイト内のコンテンツ(上記例では「XXランキング」)を後からHTMLに追加で付け足しているという場合が多いです。これはWebアプリの作り手からすれば自然な考え方で、データはデータとして、構造を表すHTMLや見栄えを装飾するCSSとは別に管理しておきたいからです。

例えば、リアルタイムに刻々と中身の変わるようなデータの見せ方として多いのが、JavaScriptなどで後からデータベースの最新情報を動的に取得し、Webページ上に掲載されたデータ表記を都度書き換えることです。このタイプのWebサイトをクローリングすると、クローラーが取ってくるのはJavaScriptで情報が書き加えられる前のHTMLになってしまいます。

ということで、最後の最後はクローラーの上でJavaScriptを動かし、動的コンテンツが書き込まれた状態のHTMLを取得する方法が求められます。

高速・軽量に動かすためにJavaScriptの中までみて、JavaScriptが行っているデータのやり取りをクローラー側で再現させるという方法もありますが、お手軽な方法としては素直にブラウザ搭載型のクローラーを使ってしまうという方法が一般的です。

なかでも、GUI環境(画面)の無いサーバー上のクローラープロセスから実行できるヘッドレスブラウザというのがスクレイピングエンジニアが求めるクローリング用ブラウザに当たります。その昔はPhantomJSというヘッドレスブラウザが一世を風靡していました。しかし、PhantomJSのメンテナンスが終わってしまい、大変なことになったと業界がザワザワしだしたところで、皆さんもお使いのChromeがヘッドレスモードを搭載して世界を救ってくれました。(弊社もこの波にすぐにのっからせて頂きました。

ということで、長い前置きになりましたが、動的にJavaScriptを動かしながらクローリングするならChromeヘッドレスと、それをクローラーRubyロジックから操作するためのSeleniumというツールを使うといいよというお話です。環境構築が大変なので、以下の記事を参考にそこから勉強してみて下さい。

Chromeブラウザをnode.jsで直接自動操縦する

前述したChromeブラウザをヘッドレスモードで扱う方法は、chromedriverとseleniumを経由して、Chromeの操作を行うというものでした。RubyからChromeを操作するために様々なツールを使って、ようやくRubyからのChromeの操作を実現しています。

しかし、経由するものが多くなればそれだけオーバーヘッドが大きくなり、Rubyから見たChrome本体が抽象化されてしまうので、本来できるような細かなチューニングや操作が逆にやりずらくなったりします。

ということで、Chromeヘッドレスをシンプルに、高機能に扱う方法としてpuppeteer(パペティアー)というnode.jsライブラリが注目されています。特にフロントエンドのテストを行う方の間で注目を集めているような気がします。

このpuppeteerの売りはChromeやChromiumのDevTools開発社チーム自身が開発していることや、seleniumからでは扱えないような操作(slowMoなど)を行えるところなどにあります。Seleniumではどうしても実現できないような壁にぶつかった際の突破口になる可能性もあるので、余裕があればpuppeteerを使った方法もチェックしておくと良いかと思います。

用途に合わせて、複数のクローリングプロダクトを組み合わせる

様々なクローリング用のツール・ライブラリを取り上げて来ました。これらの各種ツールをニーズに合わせて選定していくのがスクレイピングエンジニアの仕事の一つです。しかし、時には基本的にはopen-uriを利用するが、ある1つのWebページのみJavaScriptの実行が必要なのでピンポイントでそこだけseleniumを利用したいという、複合的にライブラリを組み合わせてクローリングすることもあります。

その場合、各スクレイピングライブラリ間でユーザー情報やセッション情報を受け渡す必要がありますが、例えばCookieのデータ構造などはライブラリごとに異なってきます。応用編になりますが、ライブラリ間でCookieを上手に受け渡す方法なども抑えておくと一つ上の高度なクローラー設計が可能になります。

さいごに

この記事ではスクレイピングエンジニアとして初めの一歩を踏み出すために必要な基礎知識をまとめてきました。基本的に記事の上から下に読みながら、ご自分の端末で写経ベースで進めてもらうだけで、スクレイピングエンジニアの基礎の基礎を修得できる情報がそろっているかと思います。

これらの技術を使えばある程度のWeb上のコンテンツの収集は可能になりますが、クローリングの1リクエストごとにクロール先に負荷をかけていることを忘れずに、必ず節度をもってボット作成を行うようにしてください。そしてWebサイト上のコンテンツは著作物である点も、利用の際には考慮してください。

それでは、楽しいスクレイピングライフを!