通知機能が搭載されていないWebページについて、毎日手動でアクセスして情報を取得するのが面倒なので自動化してみました。
Webスクレイピングとは主にWebサイト上に掲載されている情報を取得したのち、必要な部分のみ抽出(+保存)する作業を指します。例えば任意のページのとある情報(商品情報・天気予報・Web記事)の特定部分を抽出したい場合に利用できます。 また、似た言葉にクローリングというものがありますがこちらはWebサイト全体を網羅的に巡回しデータを収集することを指します。例えばこのクローリングという技術はGoogleの検索インデックスの構築に利用されていますね。
ここまで聞くと「便利やん、使い倒したろ」となるかも知れませんが、チョット待って!!! 賢い方ならお気づきかもしれませんが、この技術、Webサイト運営者の立場としては少々厄介モノだったりするんですわ。個人情報に関わる情報は抽出禁止はもちろんのこと、著作権侵害の恐れもあり、短時間で大量のリクエストを実施することになるのでサーバーへ多少なりとも負荷をかけることになります。そのため、Webスクレイピングを実施する前には必ず事前に当該Webサイトを確認してください。robots.txtの内容や利用規約ページの確認が必要ですが、利用規約内には「スクレイピング」と限定した書き方ではなく、「ロボット等によるデータ抽出・収集」といった書き方がされていることが多いです。スクレイピングはもちろんそれに含まれるため、このような記載がある場合にはスクレイピングはしないように注意してください。本ブログの利用に起因するいかなる損害についても、当方は一切の責任を負いかねます。なお本ブログにおいても利用規約内に同様の記載をしておりますので、スクレイピングはくれぐれもお控えください。とはいえ大変便利な技術ですので早速使い方を紹介しますね。今回は私のブログでWebスクレイピングを実施してみました。自分自身のページにおけるWebスクレイピングであれば誰が文句を言えようか(以下略)。
Webスクレイピングについての概要は前述の通りですが、どうやって実施をしましょうか?まあお決まりの話ですが、Pythonなので便利なライブラリがいくつもあるんですよね。まずはいくつか代表的なものを紹介します。
BeautifulSoup、美味しそうですよね。こちらはHTML・XMLの解析と特定の情報の抽出に特化しており、通常Requestsライブラリと一緒に使われます。DOMツリー構造を使って操作が可能なので静的ページにはもってこいのライブラリです。初学者向けで最も学習コストが低いとも言われていますが、標準のhtml.parserだけでなくC言語で書かれたlxmlパーサーと組み合わせることもできるため、比較的高速な処理が可能で、簡単な処理には重宝されています。一方でHTMLをそのまま解析するだけなので、ブラウザ側(=JavaScript)でレンダリングされるSPAのようなWebサイトや、lazy laodが組み込まれた動的ページの解析には不向きです。
こちらは膨大なデータの処理に向いており、スクレイピングとクローリングの両方が利用可能なフレームワークです。ライブラリではなくフレームワークであることがポイントで、他のライブラリと比較して幅広く機能が提供されています。また並行処理も可能であるため非常に高速な処理が期待できます。一方で、BeautifulSoupと同様に動的ページの解析には不向きです。
Seleniumは既出の2ライブラリとは少し毛色の違うライブラリです。一番の特徴はブラウザをどのように操作するかを指示できることにより、静的ページだけでなく動的ページからの抽出が可能であることです。これにより、例えばJavaScriptによるページの読み込みが完了してから操作を実行できたり、入力フォームへのテキスト入力・ボタン押下・スクロール動作ができたりと、さながら実際にページを手動で操作するような感覚です。RPAっぽいとも言えるかもしれませんね。ここまで褒めちぎりましたが、反対に一番のネックは処理速度です。クライアント上でブラウザを実際に起動しているので、手動よりは格段に速いですがそれはもう時間がかかります。
ここまでの情報を以下の通りまとめてみました。
BeautifulSoup | Scrapy | Selenium | |
---|---|---|---|
HP | URL | URL | URL |
特徴 | 簡単!速い! | 大規模な処理が得意 | 動的ページの処理が可能 |
静的コンテンツの処理 | ✔︎ | ✔︎ | ✔︎ |
動的コンテンツの処理 | - | - (一部可能) | ✔︎ |
処理スピード | ◯ | ◎ | ▲ |
学習コスト | ◎ | ▲ | ◯ |
まずは一番簡単なこちらから。解析するページは以前執筆したPythonでGoogle Driveにファイルをアップロード・ダウンロードする。という記事にします。ここからmeta
タグとh2
タグを取得してみましょう。
まずはbeautifulsoup4
タグとrequests
をインストールします。
pip install beautifulsoup4 requests
続いて以下の通りコードを書いていきましょう。
requests.get()
メソッドを使って4行目のURLに対してHTTP GETリクエストを送信し、HTMLデータを取得します。結果をresponse
に格納します。response
を解析するためにDOMツリー構造に変換します。そのために第一引数にはresponsex.text
を、第二引数にはhtml.parser
をセットしてBeautifulSoup()
メソッドを実行します。response
について.text
という属性をつけたのは、BeautifulSoupが解析可能なテキスト形式に変換する必要があるからです。また、第二引数にhtml.parser
をセットしたのは、あくまでもBeautifulSoupに自体にはパース済みのHTML・XMLを操作する機能しかなく、パース自体はパーサーの役割となるからです。なお、response
については、テキスト属性の他にも、ステータスコードを取得できる.status_code
属性やJSONデータを取得できる.json
属性があります。BeautifulSoup()
メソッド内のメソッドを使って抽出したい要素を探索します。まずはfind()
メソッドを使用して、HTML内の特定のmeta
タグを検索します。ここで第二引数に{'name': 'description'}
を設定することで、name
属性がdescription
となっているページ名が登録されているmeta
タグのみに限定することができます。これをmeta_description
に格納します。meta_description
に格納されたmeta
タグについて、'content'
属性の値を.get()
メソッドで抽出します。この'content'
属性内の値こそが今回欲しかった値です。h2
タグを取得します。こちらは複数存在するため、.find_all()
メソッドで該当するh2
タグをすべて検索します。h2
タグについて、そのまま出力するとタグごと出力されてしまうので、今回も.text
属性を利用してテキスト部分のみ抽出し出力します。ちなみにこちらのブログでは記事の検索もちょっとだけ可能なのですが、検索の実行+結果からの抽出はBeautifulSoupでは難しいんですよね。。これを実現するのが、そう、Seleniumなんです。
ということでSeleniumを使ったスクレイピングについては、検索キーワード入力→検索の実施→検索結果の出力という手順を踏みたいと思います。まずはライブラリをインストールします。
pip install selenium
続いて以下の通りコードを書いていきましょう。
webdriver
とはブラウザを操作するために必要なコンポーネントです。selenium.webdriver.common.keys.Keys
はキーボード操作を受け付けるためのモジュール、selenium.webdriver.common.by.By
はHTMLの要素を検索する際に方法を指定するためのモジュールです。time
もインポートします。webdriver.Chrome()
メソッドを利用してSeleniumのChrome WebDriverを起動します。その後URLを指定して.get()
メソッドでページを開きます。By.CSS_SELECTOR
とすることでCSSセレクタを使うことを指定、第二引数にはinput
タグのtype
属性がtext
であることを指定して、find_element()
メソッドでフィールドを検索します。今回はCSSセレクタを指定する方法を取りましたが、TAG_NAME
やID
も利用できます。Google
としました。それをsend_keys()
メソッドに渡すことでフィールドへの入力を実行し、send_keys(Keys.RETURN)
とすることでEnterキーを押下しました。これにより検索の実行が完了しました。time.sleep(3)
として、検索結果表示までの時間を確保します。div
タグの箱で表示されるようにしていますが、クラス名はいずれもArticleItem_eachArticle
を含むことがわかっています。そのため、部分一致を表す*=
でクラス名を指定してfind_element()
メソッドの第二引数に設定します。検索結果はelements
内にリスト形式で入っているのでlen()
メソッドで個数を確認します。Except
を記述します。.quit()
でブラウザを切ります。スクレイピングについて解説してきましたが、どのライブラリを使うにしろ一番のネックはWebページの構造・デザイン自体が変更されるリスクです。海外の有名なSaaSアプリ等は単なる機能追加だけでなくデザインのアップデートも頻繁になされるため、その度にコードを修正するのは骨が折れると思います。提供されているのであればWebAPI経由の方が、抜け漏れの少ない構造的な情報を取得可能なのでそちらをおすすめしたいです。
よろしければこちらの記事も参考にしてみてください。
Loading...