本書では、スクレイピング・スキルの向上を目的として、様々なスクレイピングの実験を行っています。本書の内容を実験する範囲では問題ありませんが、不正に拡張することは絶対にしないでください。不正アクセス禁止法(不正アクセス行為の禁止等に関する法律)、偽計業務妨害、著作権法違反などに該当する恐れがあります。次に示す事項に合意した方のみ、本書をお読みください。
・本書の内容を不正に使用しない。
・個人や組織、インフラ等に対して攻撃実験しない。
・他人や所属組織が所有する機器を利用しない(自分が所有する機器だけを使う)。
本書ではスクレイピングの手法を解説していますが、不正アクセス禁止法や偽計業務妨害に当たらないよう配慮しています。
また、本書のスクレイピング処理は、執筆時点でのWebサイトのHTML構成をベースとしています。WebサイトのHTML構成が変化した場合、スクレイピング処理が正常に動作しない場合があります。
本書に記載された内容は、情報の提供のみを目的としています。本書を用いた実行・製作・運用は、必ず自らの責任で行ってください。これらの情報による実行・製作・運用の結果について、著者や関係者は責任を負いません。
本書に登場するシステム名や製品名は、関係各社の商標または登録商標です。また本書では、®、™などのマークは省略しています。
本書は、技術系同人誌イベント「技術書典7」において頒布された『スクレイピング・ハッキング・ラボ』を底本として大幅に加筆を行っています。
英語のスクレイプ(scrape)には、「こすり落とす」「削り取る」という意味があります。スクレイピングとは、Webサイトから公開されているデータを収集し1、そのデータから不要なデータを削り取り、実行者の意図した情報を抜き出す作業を指します。我々は通常、ブラウザーを使って、Webサービスの提供者が意図したテキストとデザインのページを閲覧します。一方、スクレイピングでは、実行者が意図した情報が得られるように、プログラムを使ってWebサービスの情報を抽出します。
スクレイピングはとても身近な技術です。わかりやすい事例として、Googleなどが提供している検索エンジンが挙げられます。Googleは、Webサイトからコンテンツの情報提供を受けているのではなく2、Googlebotと呼ばれるクローラーがWebサイトを巡回して、情報を収集しています。その中から本文などのテキストや画像を抽出して、検索エンジン利用者に検索サービスを提供しています。また、近年では機械学習のためのスクレイピングで、データを収集して人工知能開発に役立てる手法も頻繁に使われています。
Webサービスの内容が更新されたとき、私達はいくつかの手段で更新情報を取得します。Webサービスのページを直接ブラウザーで閲覧して、目視で確認することもそのひとつです。しかし、毎回ブラウザーを立ち上げて、更新されているかどうかを確認することは、かなりの手間がかかる退屈な作業です。
あるいは、WebサービスのRSS(Rich Site Summary)フィードを、RSSリーダーで読み取って新着情報を得る手段もあります。現在、サービスを提供している代表的なWebベースのRSSリーダーには、Feedly3やInoreader4などがあります。しかし、SNSの増加やGoogle Readerのサービス終了などで、RSSの役目は歴史的役割を終えたという認識も一部で広まっています。あらゆる情報をRSSフィードで生成・取得する文化は、徐々に衰退しつつあります。大手Webサービスでも、最近はRSSフィードを生成していないサービスが増えています。また、RSSフィードの内容は提供側の意図で決められているため、必ずしも意図どおりの情報を得られるとは限りません。
それ以外では、最近ではスマホアプリのプッシュ通知や、ブラウザーのWeb Pushなどで更新情報を得る手段もあります。近年では、多くのサービスがプッシュ通知に対応しています。しかし、この手段も利用者が意図どおりの結果を得られるとは限りません。また、Web PushはChromeなど主要なブラウザーに限られます。加えて、通知するタイミングや詳細な購読管理ができない、Web Push自体がブラウザーにとってノイズになっている5、などの問題点があります。
スクレイピングは、自分で記述したプログラムを実行して、Webサービスから必要な情報を抽出します。スクレイピングでは、基本的にWebページとして提供されているデータを自由に取得して、加工・整理することができます。また、実行したいタイミングで動かすことができます。スクレイピングは、RSSフィードやプッシュ通知などで見られた、サービス提供側の制約をあまり受けません6。
また、近年はスクレイピング関連のライブラリーが整備されてきており、それらのライブラリーを組み込めば、簡単なプログラムでスクレイピングを実行できる環境が実現できます。プログラミングについて専門知識を持たない人でも、本書に書かれているようなスクレイピングを実行して、自由に情報を得ることができます。スクレイピングは、Webの自由や民主化を補完して拡張するものといえます。
スクレイピングを実行する際には、法律に注意しなければなりません。スクレイピングやクローリングの手法は、Googleを始め多くの企業や公共機関で採用されています。ただし、スクレイピングの実装内容や対象サービスによっては、著作権法や不正アクセス禁止法の違反、あるいは偽計業務妨害に問われる可能性があります。
2010年3月に、愛知県岡崎市の岡崎市立図書館で、蔵書検索システムに障害が発生しました。そして、岡崎市立図書館の蔵書検索システムからクローラーで自動的に情報を収集していた男性が、愛知県警によって偽計業務妨害容疑で逮捕されました。この事件は「岡崎市立中央図書館事件」、または男性がLibrahackというサイト7を開設したことから、「Librahack事件」と呼ばれています。
男性は勾留と取り調べの後に起訴猶予処分となりました。ですが、クローラーは一定間隔空けてからアクセスするように実装されており、これが偽計業務妨害に該当するかは、多くの専門家が疑問視しています。ただ、近年のWizardBible事件やCoinhive事件、アラートループ事件などを見ても、警察はITに関して無知であることが多いようです。そのため、実際には法律に抵触しなくても、家宅捜索や起訴をされるリスクはあります。私達は慎重に行動しなければなりません8。
本書ではWebサイトに設置されたrobots.txtを解析して、それをスクレイピングに組み込んでいく手法も紹介しています。
スクレイピングは様々なプログラミング言語で実装できますが、本書ではPython3を使ったスクレイピング技法について解説していきます。
Pythonは、世界中で多数の開発者が使用している言語です。1991年に登場したこの言語は、オープンソースのスクリプト言語として開発され、現在ではGoogle、Dropbox、Instagramなど、著名なサービスでも使われています。
シンプルでわかりやすい文法と豊富なライブラリーがPythonの特徴で、初心者にも学びやすいコンピューター言語です。数多くのライブラリーをpipコマンドで容易に組み込むことができ、機械学習や深層学習などの人工知能研究でも、Pythonが多数使われています。
これらの豊富なライブラリーを使って、とても短いコードでスクレイピングを実行し、その結果を解析することができます。本書で示しているコードは、いずれも20〜40行ほどの短さで、様々な処理を実現しています。
Pythonを使うデメリットとしては、コンパイル方式の言語と比べて、処理速度が遅い場合があることが挙げられます9。これは、Pythonがインタープリター方式でコード上に書かれた命令を、逐次機械語として読み取って、実行していく言語であるためです。しかし、この処理速度の遅さは、大規模なクローリング処理では問題となりますが、スクレイピングの基礎を練習して学んでいく上では、ほとんど気にならない遅さです。
Pythonは動的型付け言語です。変数の型は特に指定する必要はなく、実行時まで型は決定されません。手軽にコードを書く上ではメリットですが、実装者が意図しない型を返す場合もあります。ただし、mypyなど静的型チェッカーが出てきており、これらを活用した静的型チェックも可能になっています。
また、Pythonはバージョンによって大きく違う場合があります。この点については、次の項で詳しく書いていきます。
Pythonを学ぶ上で避けて通れないのが、Python2とPython3のバージョンの違いです。2008年に公開されたPython3では、Python2と言語仕様が大きく変わり、Python2との文法などの後方互換性が多数失われました。それはPythonを言語として進化させていく上での、苦渋の決断でした。ですが、この大きな変更に対応しきれず、Python2で書かれたり、メンテナンスが続けられたりしているアプリケーションも多数あるのが現状です。
しかし、Python2は2020年1月1日で、サポートが終了しました10。また、Python3がリリースされた当初は、Python2で書かれたライブラリーの方が圧倒的に多くPython3で開発する上での難点となっていました。ですが、今ではかなりPython3で書かれたライブラリーが豊富になってきています。スクレイピング関連のライブラリーも、多数Python3に対応しています。特に、既存アプリケーションとのしがらみがなく、今からコードを書くのであれば、Python3を選択した方が良いでしょう。
# Python2とPython3で違う文法の例
# Python2のPrint出力
print "Hello World"
# 出力結果 Hello World
# Python3のPrint出力
print ("Hello World")
# 出力結果 Hello World
#Python2の割り算
6 / 4
# 出力結果 1
# Python3の割り算
6 / 4
# 出力結果 1.5
本書はこの考え方に立って、Python3での記述を採用しています。しかし、別なソフトウェアの動作のために、Python2がインストールされている場合もあるでしょう。Python2を削除あるいはPython3で上書きしてしまうと、これらのアプリケーションが正常に動かなくなる可能性も考えられます。そこで本書では、Python2がインストールされている場合に環境を残したままにしておき、Python3を別コマンドで実行する方法を取っていきます。これにより、Python2とPython3を同一のマシン内で共存することが可能となります。
Python2とPython3の違い以外に、Python3の中でもマイナーバージョンの違いがあります。Pythonは同一メジャーバージョンの中での後方互換性を重視する言語ですが、マイナーバージョンによって、差異が存在することも確かです。
そのため、Pythonの環境を構築するにあたって、過去のバージョンで書いたソースコードも動くように、特定のPythonバージョンの環境を構築する手法が広く採用されています11。これは、Anaconda・pyenv・pyenv-virtualenv・venv・Pipenvなどのツールを使って、仮想環境を構築することで実現できます。
ただ、このような仮想環境構築が、初期構成からPythonを学ぶ敷居を上げています。過去に特定マイナーバージョンで構築したソースコード資産を持っていないのであれば、少なくとも本書を学習する上では、特に仮想環境を構築せずとも問題ありません。本書では各OSでインストールできるPython3最新版を対象とした書き方で、スクレイピングを実行していきます。Pythonのバージョンをそれぞれ独立した仮想環境にしたい方のために、PyenvやAnacondaでのインストール方法と、バージョン管理も解説していきます。
本書は以下のような方に最適です。
・Pythonの基礎を学習したい
・スクレイピングの基礎を学習したい
・データ解析の基礎を学習したい
・自然言語解析を学習したい
・ネットから得られる情報を自動化処理したい
・スマートフォンにスクレイピング環境を構築したい
・退屈なことを自動化したい
Pythonを導入する手段は複数ありますが、代表的な導入手段を紹介していきます。
もしあなたがGoogleアカウントをお持ちで、Pythonについて1から環境構築を行うのであれば、最も簡単な実行環境の構築は、Google Colaboratoryを使う方法です。
Google Colaboratoryは、Googleが提供する完全にクラウドで実行されるPythonおよびJupyter Notebook環境です(Jupyter Notebookについては、後で解説します)。機械学習を中心に、Pythonを使った研究や教育用途に無料公開されています。
Google Colaboratoryを利用すると、Pythonの実行や解析結果の保存などを、全てクラウド上で行うことができます。実行環境として提供されているインスタンスは、Xeon 2.2GHz CPU2コアとメモリー13GBで、スクレイピング環境には充分すぎるほどです。
Google Colaboratoryを使うには、以下のURLをブラウザーで開きます。
https://colab.research.google.com/
まず右側のログインボタンをクリックして1、Googleアカウントでログインします。既にブラウザーでログイン済みの場合は、この操作は不要です。
続いて左側の「ファイル」メニューをクリックして、"ノートブックを新規作成"をクリックします2。
これで、Pythonの実行環境を作成することができました。
試しにprint("Hello World !")と打ち込んでみます。
次に、入力欄左側の実行ボタンを押します。
これで、画面上に"Hello World !"と表示されました。
Google Colaboratoryは完全にクラウドで実行されるため、コードやデータのプライバシーはGoogleに依存することになります。ローカル環境ではないため、重要なデータを誰にも閲覧させずに保管しておきたい場合は、Google Colaboratoryを実行するたびに、コードをJupyter Notebookにコピーします。そして実行終了後は、Google Colaboratoryから削除しておくなどの自衛策が必要となります。
また、Google ColaboratoryはPythonのコード実行時にインスタンスが立ち上がりますが、このインスタンスは、連続して12時間までしか使用できません。12時間を過ぎると、処理の途中でもインスタンスが停止します(実行環境が停止するだけで、コードの内容は失われません)。また、Jupyter Notebookのセッションが切れるなど、アイドル状態が90分以上続くと、同じくインスタンスが停止します。このため、長い時間がかかるようなクローリングや解析作業には不向きです。ただ、本書に書かれていることを実行する範囲においては、この時間内に充分収まります。
そして、Google Colaboratoryはローカル環境ではないため、本書の第7章のSeleniumを実行することや、第8章のScrapyでクローリングを実行することはかなり大変です。ファイル入出力も、Google Driveと連携させる必要があります。本書を試すのであれば、以降に示すOS別のネイティブインストールの方がおすすめです。
Windowsにネイティブインストールする場合、Python公式サイトにアクセスします3。
https://www.python.org/
メニューのDownloadからWindowsを選択します。
ダウンロードページを開いたら、Stable Releaseを見てみましょう。中ほどにダウンロードリンクがあります。
64bit版のWindowsを使用中ならば「Windows x86-64 executable installer」を、32bit版を使用中ならば「Windows x86 executable installer」をクリックします4。
ダウンロードした実行ファイルをダブルクリックすると、インストーラーが起動します。「Add Python 3.8 to PATH」にチェックを入れ、Install Nowをクリックします5。
スタートメニューから「Windowsシステムツール」→「コマンドプロンプト」を起動させます。検索入力欄にcmdと入力して、起動させてもかまいません。コマンドプロンプトが起動したら、pythonコマンドを実行すると、Pythonのインタラクティブモードを起動できます。
このインタラクティブモードは、quit()と入力してエンターキーを押すか、CtrlキーとZキーの同時押しで、いつでも終了させることができます。
macOS Catalina以降には、標準でPython3がインストールされています。Catalina以降で本書の内容を実行する場合は、特にインストール作業は必要ありません。
Catalina以前のバージョンの場合、標準でPython2がインストールされています。Catalina以前のmacOSにPython3を導入するには、macOS用のパッケージマネージャーであるHomebrewを使うと、簡単にインストールできます。
Homebrewがインストールされていない場合は、以下のコマンドでインストールします6。既にHomebrewがインストール済みの場合は、このコマンドは必要ありません。
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/inst
Homebrewのインストールが完了したら、以下のコマンドでPython3をインストールします。
$ brew install python3
これでインストールは完了です。
LinuxにPythonをインストールする場合、ディストリビューションの種類やバージョン、インストール時のオプションによって、大きく変わります。本書では、執筆時点の最新版のディストリビューションを、標準構成でインストールした場合のPython3導入方法について解説します。7
Debian9やUbuntu18.04の最小構成やKali Linux2020.2の場合は、標準でPython3がインストールされています。しかし、pip3がインストールされていません。以下のコマンドでインストールします。
$ sudo apt install python3-pip
openSUSE Leap 15.1の最小構成の場合は、標準でPython3がインストールされています。しかし、pip3がインストールされていません。以下のコマンドでインストールします。
$ sudo zypper install python3-pip
RHELの最小構成の場合は、Pythonが標準でインストールされていません。以下のコマンドでインストールします。
$ sudo yum install python3
CentOS7やCentOS6の最小構成の場合は、Python2が標準でインストールされています。また、Yumの標準リポジトリーに、Python3のパッケージが追加されていません。以下のコマンドでIUS(Inline with Upstream Stable)のリポジトリーを追加して、Python3をインストールできます。
$ sudo yum install -y https://centos6.iuscommunity.org/ius-release.rpm
$ sudo yum install -y python36u python36u-libs python36u-devel python36u-pip
$ sudo ln -s /usr/bin/python3.6 /usr/bin/python3
$ sudo ln -s /usr/bin/pip3.6 /usr/bin/pip3
Amazon Linuxの場合は、Python2が標準でインストールされています。Amazon Linux1の場合は、以下のコマンドでPython3をインストールできます。
$ sudo yum install python36
pip3のパスが通っていない場合は、以下のコマンドでパスを通します。
$ sudo ln -s /usr/bin/pip-3.6 /usr/bin/pip3
AmazonLinux2の場合は、以下のコマンドでインストールできます。
$ sudo yum install python3
PyenvでPythonのバージョン管理を行う場合について解説します。Pythonのバージョン管理を行わない読者は、飛ばして問題ありません。
まず、Pyenvをインストールします。macOSでHomebrewが導入されている場合は、以下のコマンドでインストールできます。
$ brew install pyenv
macOS以外の環境の場合は、以下のコマンドでインストールします。
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
使用しているシェルに応じて、Pyenvの自動起動設定を行います。
現在使用しているシェルがbashで、OSがUbuntuデスクトップ版以外の場合は、以下のコマンドでパスを設定します。
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
使用しているシェルがzshの場合は、以下のコマンドを入力します。
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.zshrc
Ubuntuデスクトップ版の場合は、以下のコマンドを入力します。
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
シェル環境をexitで一度抜けるか、bashの場合は以下のコマンドで、シェルを再読み込みします。
$ source ~/.bash_profile
Zshの場合は、以下のコマンドで再読み込みします。
$ source ~/.zshrc
Ubuntuデスクトップ版の場合は、以下のコマンドで再読み込みします。
$ source ~/.bashrc
pyenv install --listを実行すると、インストール可能なPythonのバージョンが一覧で表示されます。
$ pyenv install --list
今回は、リストの中で最新版であるPython3.8.2をインストールします。以下のコマンドを入力します。
$ pyenv install 3.8.2
インストールが完了したら、以下のコマンドでバージョンの切り替えを行います。
$ pyenv global 3.8.2
最後にpyenv globalで環境をPython3.8.2に切り替えます。
$ pyenv global 3.8.2
pythonコマンドで、バージョンが切り替わっているかを確認します。
$ python --version
Python 3.8.2
バージョンがPyenvで、インストールしたバージョンになっていれば設定完了です。