書評『Python クローリング&スクレイピング データ収集・解析のための実践開発ガイド』

Pythonを使ってWebサイトをスクレイピングするための本です。様々なWebサイトやWebAPIから必要なデータを切り出して、テキストやデータベースに保存します。さらに取得したデータをグラフ表示、BigQueryに投入、Elasticsearchで全文検索するなど、取得した後のデータの活用方法についても記載があります。

MacとLinux(Ubuntu)での説明です。AppendixでVagrant、VirtualBoxを使ってUbuntuの仮想マシンを作成する説明がありますので、Windowsではそちらを使うことになります。

内容

第1章 クローリング・スクレイピングとは何か

最初の章ではクローリングとスクレイピングについての説明があります。

・クローリング
Webページのハイパーリンクをたどって次々にWebページをダウンロードする作業。
・スクレイピング
ダウンロードしたWebページから必要な情報を抜き出す作業。

また、イメージをつかむためにUnixコマンドを使用したクローリング・スクレイピングが紹介されています。

gihyo.jpから電子書籍の総数を取得する例題ではwgetでgihyo.jp/dp/index.htmlをダウンロードした後、
cat gihyo.jp/dp/index.html | grep -E 'class="paging-number".*-' | sed -E 's@.*/([0-9]+).*@\1@'
で、ページから書籍数を取得します。

この章ではwget、cat、grep、cut、sedなどのUnixコマンドや正規表現などについての簡単な説明があります。

特別なツールをインストールしなくても、Unixコマンドだけでもある程度のクローリング・スクレイピングは可能です。しかし複雑になってくると大変です。そこで…

第2章 Pythonではじめるクローリング・スクレイピング

Python3を使ってクローリング・スクレイピングをしていきます。MacではHomebrew、Ubuntuではaptを使ってインストールしています。またvenvをインストールして、環境を分ける方法も記述されています。

この章ではPythonの文法の簡単な説明があります。そんなに難しい処理はないので、他の言語の知識があればPythonの知識はなくてもついて行けると思います。プログラミング未経験だと厳しいです。

いよいよコーディングです。まずは標準のライブラリのみを使っていきます。urllibモジュールを使ってページを取得します。そして取得したページを正規表現のreモジュールやXMLパーサーのxml.etree.ElementTreeを使って、データを切り出します

そして切り出したデータをcsvモジュール、jsonモジュールを使ってCSVとJSON形式のテキストファイルととして保存します。またsqlite3を使ってsqliteへも保存します。

第3章 強力なライブラリの活用

Pythonの魅力の一つは、強力なサードパーティーライブラリです。この章では便利なライブラリを使ったクローリング・スクレイピングが紹介されています。各ライブラリはpipを使ってインストールします。

この章で使用するライブラリは以下の4つ。

  • Requests
  • lxml
  • Beatuful Soup
  • pyquery

Requestsはクローリングに使用します。このライブラリを使用することで、HTTPヘッダーをいじったり、Basic認証を突破したり、セッションの管理など便利な機能が簡単に利用できるようになります。

その他の3つは使って取得したページを、スクレイピングするためのライブラリです。

書籍では最初の一つとしてlxmlを使用することをお勧めしています。C言語で作成されていて、高速だからというのがその理由です。またBeautiful Soupもpyqueryも内部でlxmlを使うことができ、高速さが享受できますが、トラブった際にはlxmlの知識は役に立つとのこと。

スクレイピングに使うライブラリではXPathかCSSを使用して、要素を指定します。

XPathは

//body//h1
//input[@type="text"]
//h2[text()="概要"]

CSSは
body h1
input[type="text"]

こんな感じで、要素を指定します。

XPathは結構複雑でとっつきにくくはあるんですが、一度覚えると便利ですね。複雑な構造でも結構簡単にとってこれるようになります。CSSはスタイルシートに似ているのでスタイルシートに慣れていれば、とっつきやすさはあります。ただしXpathでは指定できるけど、CSSでは表現できないものもありますので、場合によってはXPathを使わざるを得ません。

Chromeの開発ツールを使って、HTMLの要素からXPathとCSSセレクターの取得する方法が紹介されています。

そしてデータベースへの保存方法についての説明です。特にスクレイピングに特化したものではなく、一般的なデータベース接続の説明になります。対象のデータベースはMySQlとMongoDBです。それぞれのデータベースのインストール方法、ユーザー作成、初期データベース作成方法も記載されています。PythonからMySQLへの接続はmysqlclient、MongoDBへはPyMongoを使います。

最後に上記ライブラリを使って、実際にPythonでクローラーを作成していきます。クローラーは書籍一覧ページから詳細ページのURLを抜き出し、詳細ページから書籍情報を取得して、データベースに保存します。クローリング開始時に取得済み書籍の一覧をデータベースから取得して、取得済みの書籍ページはクローリングしないような仕組みも実装されています。

第4章 実用のためのメソッド

この章ではクローラーを運用するにあたっての、押さえておくべき注意点や設計方法についての4つのポイントを挙げています。

  • クローラーの分類
  • 注意点
  • 繰り返しの実行を前提とした設計
  • クロール先の変化に対応する

クローラーの分類

クローラーの分類では、クローラーを以下の3つに分けています。

  • ステートフル、ステートレス
  • Javascriptを解釈する、解釈しない
  • 不特定多数のサイトを対象とするか

ステートフルなクローラーが必要ならCookieが使える必要があります。RequestsならSessionオブジェクトで対応できます。

Javascriptの解釈が必要なら、SeleniumやPhantomJを使うと可能です。

これらの特徴に合わせて、適切なクローラーを作成していきます。

注意点

注意点ではクロールするにあたっての注意点の説明がされています。

  • 著作権、利用規約
  • robots.txt
  • XMLサイトマップ
  • クロール先の負荷
  • 連絡先の明示
  • ステータスコードとエラー処理

繰り返しの実行を前提とした設計

繰り返しの実行を前提とした設計をすることを推奨しています。理由として以下の2つを挙げています。

  • 更新されたデータだけを取得できるようにするため
  • エラーなどで停止した後に途中から再開できるようにするため

クロール先の変化に対応する

クローリングではWebサイトの構造に大きく影響をうけます。構造が変わるとデータが取れなくなります。このような場合はいち早くプログラムを書き換える必要があります。そのためにバリデーションのライブラリで変化をキャッチし、メールで通知する方法が紹介されています。

第5章 クローリング・スクレイピングの実践とデータの活用

この章では実際に様々なサイトからクローリング・スクレイピングする方法を紹介しています。

Wikipedia

Wikipediaの記事データを使って、自然言語処理技術を用いて頻出単語を抽出する例です。Wikipediaから文章を抽出、MeCabを使って形態素解析を行い、頻出単語を抜き出します。なおWikipediaのデータはクロールではなく、手動でデータセットをダウンロードします。

Twitter、Amazon、YouTube

Twitter、Amazon、YouTubeのAPIを使った、データの取得例が紹介されています。

TwitterではStreamingAPIを使って取得します。requestsを使った方法とtwitter用のライブラリであるtweepyを使った方法が説明されています。またOAuth認証を使うためのライブラリ、OAuthlibを使用します。

なお、書籍ではAWSのAPIキーを公開してしまったがために数百万の請求が来た例をあげ、APIキーの取り扱いに注意するように指摘しています。この例でもキーはファイルに保存せず、環境変数から取得するようになっています。ファイルにAPIキーを記載したまま、githubなどに公開してしまうのを防ぐためです。foregoというライブラリを使った方法が紹介されています。

他にもAmazon Product Advertising APIで商品情報、YouTubeでGoogle API Client for Pythonを使用して動画情報を取得します。

時系列データ

時系列データとして、為替・国債金利・有効求人倍率の取得の説明があります。ここでは手動でCSVやエクセルファイルをダウンロードし、pandaというデータ分析のためのライブラリを使ってデータを読み込み、matplotlibを使ってグラフを表示する方法が説明されています。

オープンデータ

政府や自治体などが公開しているデータを利用します。新幹線旅客輸送量の推移のPDFからデータを抽出しています。PDFからテキストを抽出するためにPDFMiner.sixを利用しています。

他にもLinked Open DataからSPARQLで日本の美術館の情報を収集する例が紹介されています。Linked Open Dataとは…

Linked Open DataからはSPARQLというクエリ言語でデータを抽出するそうです。

Webページの自動操作

RoboBrowserを使って、あたかもブラウザを手で操作するかのような取得方法の説明です。

例えば以下の動作が

  1. Googleのトップページに行く
  2. 検索語を入力する
  3. 検索ボタンを押す

以下のコードで実行可能です。

他にもアマゾンにログインして、注文履歴を取得する例があります。

Javascript

SeleniumとPhantomJSを使って、Javascriptを解釈するクローラーを作成します。

Seleniumを使ってGoogleで検索してスクリーンショットをとったり、noteでおすすめコンテンツを下にスクロールさせて取得する例などがあります。

またfeedgeneratorというライブラリを使用して、RSSフィードを作成する方法も説明されています。

取得したデータの活用

取得したデータの活用として、

  • 地図による可視化
  • BigQueryによる解析

が紹介されています。

地図による可視化では先ほどのLink Open Dataから取得した美術館の位置をGoogle Maps JavaScript APIを使って地図上に表示します。位置情報がない美術館はYahoo!ジオコーダAPIを使って、住所から位置情報を取得して地図上に表示します。

第6章 フレームワーク Scarpy

Scrapyはクローリング・スクレイピングのためのフレームワークです。どのWebサイトでも使える共通処理はフレームワークが行ってくれるので、こちらは各Webサイトに特化した部分だけをコーディングするだけでよくなります。

この章では約80ページ近くにわたってScrapyについての説明があります。インストール方法、Scrapyプロジェクトの作成、spiderの作成へと進んでいきます。

Scrapy Shellを使ったインタラクティブな操作の説明もあります。このShellがとても便利です。まずはこれでページを取得して構造を解析、Xpathで情報を取得することが簡単にできます。

Scrapyは様々なコンポーネントが連携して処理を行います。Scrapy Engine、Scheduler、Downloader、Spider、Feed Exporter、Item Pipeline、Downloader Middleware、Spider Middleware等。書籍ではこのアーキテクチャの説明もあり、理解が深まります。

さらに実践的なクローリングとして、リンクを抽出しそのリンクをたどる処理が説明されています。Scrapyではルールを記述することで簡単にこういった処理を行うことができます。またXMLサイトマップをクロールする例も紹介されています。

そして抽出したデータを Item Pipelineで処理します。例えば、データの検証を行ったり、データベースに保存したり。

またScrapyの設定項目の説明や、Middlewareを作ってScrapyを拡張する方法が記載されています。

コラムでは簡単にではありますが、ScrapyでJavascriptに対応できるSplashの説明があります。

そして食べログのクロールや、はてなブックマークを起点に不特定多数のサイトをクローリングする例が紹介されています。

最後は取得したデータをElasticsearchをインストールして、データ投入し全文検索できるようにします。さらにはOpenCVを使って画像から顔を検出する例まで。

第7章 クローラーの継続的な運用・管理

最後の章ではクローラーの運用についての説明です。クローラーを継続的に動かし続けるために必要な運用・管理の方法を紹介しています。

  • サーバーでのクローラーの実行
  • クローラーの大規模化への対応
  • クラウド・外部サービスの活用

サーバーでのクローラーの実行

ここではAWSのEC2でUbuntuを使用する例が紹介されています。AWSアカウント作成からIAMユーザーの作成、キーペアの作成、仮想サーバーの起動までAWSでの操作も丁寧に説明されています。

そしてローカルで作成したPython環境をpip freezeを使って、サーバーで再構築する方法の説明もあります。

さらにcronで定期的に実行、cronでのエラー発生時はPostfixを使ってメール送信する方法などの説明があります。

クローラーの大規模化への対応

クローリングとスクレイピングを分離することを著者は進めています。理由としては

  • スクレイピングの処理が失敗してもクロールしなおす必要がない。
  • 2つの処理のうち、一方の処理を止めたとしても、もう一方の処理を継続できる。
  • 単純な2つの処理に分割できるのでコードの見通しが良くなる。
  • クローリングとスクレイピングの処理をそれぞれ独立スケールさせやすくなる。

分離したクローリングとスクレイピングの処理の連携のためにメッセージキューRQ+Redisを使用する方法を説明しています。また実際にキューを使って連携するコードも記載されています。

またマルチプロセス、マルチスレッド、非同期IO(asyncio)を使った処理の高速化についても説明があります。

クラウド・外部サービスの活用

クラウドを利用するメリットして、著者は以下を挙げています。

  • リソースを観点に調達でき、増減させやすい
  • クラウド事業者に運用を任せられる
  • クラウドのサービスをAPIで操作できる

また役に立つサービスとしてAWSの以下を挙げています。

  • Amazon RDS(リレーショナルデータベース)
  • Amazon ElastiCache(メモリキャッシュ)
  • Amazon SQS(メッセージキュー)
  • Amazon SES(メール送信)
  • Amazon S3(ストレージ)

感想

クローリング・スクレイピングに限らず、データの活用方法や運用方法まで非常に幅広い内容です。とりあえずこれ1冊あれば、クローリング・スクレイピングに関しては、かなりの要件は満たすのではないでしょうか。もちろん一つの書籍ですべてを詳細に解説することは不可能なので、細かいところはそれぞれの専門書に委ねることにはなりますが、とにかくポイントが抑えられているという印象です。

私もクローラーが必要だったため、この書籍を購入しました。私はScrapyを使うことに決め、開発し実際に運用しています。Scrapyの場合はちょっと大掛かりなフレームワークということもあり、実際の開発に関してはこの書籍+公式サイトの説明などを必要としましたが、基本的なクロール・スクレイピング・データの保存に関しては、この書籍だけでも大丈夫でした。

Pythonを使うということに問題なければ、スクレイピングするなら是非持っておきたい書籍です