Pythonで簡単スクレイピング(基本から実践編) + docker(おまけ)

Pythonを使いスクレイピング!

はじめに

今回はPythonでスクレイピングを行ってみたいと思います。

皆さんWebサイトのデータを収集したいときはどうしますか?
例えば

  • 株価などのデータ取得
  • オンラインショップの価格比較・変動時に通知
  • 特定のサイトの更新通知
  • 検索結果をCSVダウンロード
  • 定期的にデータを取得して機械学習やディープラーニングに使用

などなど、普段ブラウザでアクセスするページから、直接データを取得したい時ってありますよね!

それらのデータを、ブラウザを開いていちいちコピペで収集・・というのは現実的ではありません。
そこでPythonを使い、Webサイトのデータを自動的に取得してみましょう!

スクレイピングとは

ウェブスクレイピング(Web scraping)とは、ウェブサイトから情報を収集する技術のことです。

身近なところでは、家計簿アプリでも使われているでしょう。
(Zaimやマネーフォワードなど)

連携する金融機関が、以降に説明したAPIに対応していない場合は、スクレイピングでデータを取得していると思います。
金融機関と連携するには、事前にID/パスワードを登録しますよね?
要はユーザーの代わりに、金融機関のサイトにログインして、必要な情報を取得しているのです。

APIについて

ちなみに、サイトにAPIが用意されている場合はスクレイピングの必要はありません

例えば以下のように、APIでお天気情報が取得できるサイトがあります。

以下のようなURLで、お天気情報がJSON形式で取得できます。
http://weather.livedoor.com/forecast/webservice/json/v1?city=400040

APIはサイトが公式に用意している手段ですので、仕様が変わる可能性も低く合法的に取得できますので、この仕組みを使うのが一番良いです。

スクレイピングは、上記のようにAPIなどでデータが取得できない場合に、ウェブサイトのページの内容を解析してデータを取得します。

スクレイピングの注意点

スクレイピングは、ウェブページの内容(HTML)を解析する性質上、対象のウェブページの構成が変わった場合に、スクレイピングのプログラムを修正する必要があります。

また違法かどうかも注意が必要です。

  • 対象サイトが、スクレイピングを禁止している
  • 取得したデータの著作権の問題
  • サーバに過度に負荷をかける

ウェブサイトにスクレイピングする際は各自でご確認ください。

スクレイピングが直接の原因だったわけではありませんが、参考までに過去にも事件があります。

前置きが長くなりましたが、実際にプログラムを作ってみたいと思います。

ソースコードについて

今回使用するソースコードはgithubにて公開しています。

環境

以下の環境があれば、WindowsでもLinux系でも構いません。

  • Python3
  • beautifulsoup4
  • html5lib

それぞれのライブラリはpipでインストールできます。

dockerイメージを使う

以前の記事で、dockerでスクレイピング環境を作る記事を公開しました。

手元にdockerがあれば、それを使う方法が便利です。
dockerを利用すると、環境を用意するのが楽です。

イメージは以下に公開しております。

dockerコマンドで、イメージをダウンロードします。

以下のコマンドで、dockerコンテナを作成しました。

私はWindowsのdockerを使用し、「D:\Docker\share」を共有フォルダとしました。
そのフォルダの中に、Pythonファイルの作成や、HTMLファイルやTXTファイルの保存をしていきます。

コンテナの中に入った後、カレントディレクトリを移動します。
このディレクトリがWindowsと共有されています。

以降、このコンテナを使用した手順も合わせて説明しますが、Pythonが実行できる環境が既にある場合は、dockerは必要ありません

HTMLファイルダウンロード

それではスクレイピングを始めましょう。
まずは、対象ページのHTMLファイルをダウンロードします。

一度に「サイトにアクセス→HTML解析」のような手順で解説しているサイトが多いですが、実際にHTMLの解析については、何度かトライアンドエラーを繰り返します
その都度、サイトにアクセスすると迷惑がかかりますし、効率がよくありません。

そのため、対象サイトのページのHTMLファイルを一度ダウンロードし、以降はそのHTMLファイルを読み込んで解析処理を作っていきます。
(ダウンロードしたHTMLファイルを何度も解析する分には、サイトには迷惑かけませんからね!)

対象は、本サイトの千草ウェブのトップページにしましょう。
(その他のサイトでも構いませんが、規約など確認してください)
念の為お断りですが、高負荷をかけないでくださいね!

HTMLファイルをダウンロードするPythonファイルを作成します。
前述のdockerイメージを使用している場合は、Windowsの共有フォルダの中にPythonファイルを作成します。

例:D:\Docker\share\donwload.py

ソースコードは以下です。UTF-8で保存してください。

Pythonファイルを保存しましたら、実行します。

dockerのコンテナへ入っている状態で、ファイルがあるか確認します。

作成したPythonを実行します。

Pythonファイルと同じ階層に、htmlフォルダが作成され、中にhtmlファイルが作成されます。
dockerコンテナを使用して実行した場合は、Windowsの以下にファイルが作成されます。

例:D:\Docker\share\html\chigusa.html

上記のHTMLファイルをテキストエディタで確認してみてください。このサイトのトップページのHTMLになります。
引き続きこのHTMLファイルを解析していきます。

今回の例では単一のURLでしたが、例えば検索URLであれば、getパラメータを動的に変えて取得といったことも可能かと思います。

HTMLの解析

次に、先程ダウンロードしたHTMLファイルを読み込み、解析を行っていきます。
本サイトのトップページを例としています。

文字列をピンポイントで取得

以下のタイトルの文字列を取得してみます。

まずは該当の文字列の場所を特定します。
実際はHTMLを解析しますので、特定方法はCSSのセレクターを取得します。

ブラウザのFirefoxを使用します。
(Chromeや他のブラウザですと以降の手順で上手くできません)

Firefoxで該当のURLを開きます。(今回は本サイトのトップページ)

F12キーを押し、開発ツールを起動します
起動後、以下の赤枠の矢印マークをクリックします。

ブラウザの方に戻り、取得したい文字列を選択しクリックします。

開発ツールに戻り、選択された文字列を右クリックし、コピー→CSSセレクターをクリックします。

以下のような文字列がクリップボードに格納されました。
今回のページの中で、取得したい文字列の場所を特定するものです。

.entry-body > h2:nth-child(4)

上記の文字列が分かれば、Python側で文字列を取得してみたいと思います。

処理内容としては、先にダウンロードしたHTMLファイルの中身を読み込み、HTMLを解析することによって、ピンポイントで文字列を取得します。
HTMLの解析にはBeautifulSoupを使用し、該当の文字列を取得する際に先に取得したCSSセレクターを指定しています。

それではPythonを実行してみましょう。
「Cliborとは」という文字列を取得できましたね!

繰り返し要素を複数取得

次は、複数の要素を取得してみたいと思います。
例えばTableタグなど、複数のデータがある場合です。
(データ数が決まっていればピンポイントで取得できますが、データ数が可変の場合)

例として、このサイトのトップページの、ブログ記事一覧の各タイトルを取得したいと思います。

先程同様に、Firefoxの開発ツールでCSSセレクターを探しましょう。
CSSのclassで良さげなものがあればよいのですが、今回は少し難しそうです。

まずはブログの記事一覧のエリアのCSSセレクターを取得します。

CSSセレクターは以下です。

div.postList:nth-child(4)

HTMLを見てみると、このエリアの中のh1タグを全て取得し、さらにその中のaタグの値を取得すると、タイトルが取れそうです。
プログラムは以下のようにしました。

実行してみると以下のようになり、上手く取得ができました!

find_allを使用すると、Tableタグのtrタグを複数取得するのも可能です。
このようにHTMLの中身を見ながら、色々考え試してみることが大事です。

スクレイピング結果をテキストファイルに保存

取得した情報を、テキストファイルに保存しましょう。
先程のタイトル一覧を保存するプログラムを作成しました。

実行したPythonファイルと同階層にTXTファイルを出力しました。
dockerコンテナからPythonを実行すると、以下の共有フォルダにTXTファイルが出力されていると思います。

例:D:\Docker\share\save.txt

テキストファイルの中身にタイトルの一覧が保存されます。

またスクレイピングした結果を、例えばCSVファイルに保存すると便利ですね!

dockerで一発実行!

スクレイピングするPythonファイルが完成したら、定期的にデータを取得する想定で考えてみましょう。

dockerコンテナに毎回入りPythonを実行せずとも、コマンド一つでPytonを実行しファイルへ保存できると便利ですよね!

まず、ダウンロードと解析を行うPythonを実行するシェルスクリプトを、共有フォルダの直下に作りましょう。
(改行コードはLFにします)

例:D:\Docker\share\start.sh

以下のようにdokcerコマンドを実行します。

–rmを指定することにより、コンテナ実行後、自動でコンテナが削除されます。
-wを指定することにより、コンテナ内のカレントディレクトリを移動しています。

そして、作成したstart.shを実行し、Pythonを実行し、HTMLダウンロード・解析・テキストファイルを保存し終了します。

その後、Windows側の共有フォルダに、save.txtが作成されることを確認してください。

これにより、バッチファイルを作成しタスクで定期的に保存できますね!
(Linux系だったらcron)

最後に

今回はPythonを使用して、htmlファイルをダウンロードし、解析を行いました。
意外にやってみると簡単にできますね!

ただし、Webページによっては、Javascriptで動的にページを表示する場合もあるかと思います。
その場合には今回のやり方はではできず、また別なやり方で行うことができます。
そのやり方も別途まとめて行きたいと思います。

お気軽にフォローください!

シンプルで高機能なクリップボード履歴フリーソフト「Clibor」

シンプルで高機能なクリップボード履歴ソフトです。
Cliborはフリーソフトです。

普段よく文字を入力する方や、ブラウザに決まったキーワードを張り付ける方など、テキストの入力がとても便利になりますので是非ご利用ください!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)