Pythonによるクローリング・スクレイピング入門 – WordPressのページの内容を取得する
2018.1.29
こんにちは。データサイエンスチーム tmtkです。
この記事では、クローリング・スクレイピングの入門を行います。題材として、WordPressで作られている当ブログ:DATAHOTEL Tech Blog | NHN テコラス株式会社の記事の情報を取得します。
はじめに
ウェブページから(自動的に)情報を収集することをクローリングやスクレイピングといいます。たとえば、Googleが検索エンジンに載せるためにGooglebotにいろいろなページの情報を収集させているのはクローリングの一例です。クローリングとスクレイピングはあまり区別されないことが多いようですが、クローリングはリンクを辿ってウェブページを移動していくことを指し、スクレイピングはウェブの情報を抽出することを厳密には指すようです。
クローリング・スクレイピングはデータ分析・機械学習をするうえで、分析データの収集や教師データの作成などのために使われます。そのため、データサイエンティストには必須の技術です。
この記事では、Python3とそのライブラリを使って当ブログの記事をスクレイピングしてみることで、スクレイピングの方法の実際を紹介します。
スクレイピングが禁止されていないか確認
この記事では当ブログ https://techblog.nhn-techorus.com をスクレイピングします。スクレイピングをする前に、スクレイピングしようとしているウェブサイトがクローリングなどを拒否していないか確認します。
robots.txt
ウェブサイトのルートに robots.txt
を配置することで、検索エンジンのクローラにアクセスされたくないサイトを指定することができます。当ブログの場合は、 https://techblog.nhn-techorus.com/robots.txt です。これを確認すると、その内容は
User-agent: * Disallow: /techblog/adm/wp-admin/ Allow: /techblog/adm/wp-admin/admin-ajax.php Sitemap: https://techblog.nhn-techorus.com/sitemap.xml
となっており、普通のページのクローリングを拒絶する記述は見つからないことが確認できます。したがって、スクレイピングをしても大丈夫そうだと推測できます。
その他必要に応じて、robots metaタグや著作権、ウェブサービスの利用規約などについても確認します。
ページ構造の観察
スクレイピングに取り掛かる前に、まずは普通のブラウザで当ブログにアクセスし、ページの構造を観察してみます。次のことがわかります。
- 記事の一覧が https://techblog.nhn-techorus.com/page/1, https://techblog.nhn-techorus.com/page/2, …, https://datehotel.io/page/14 で表示される
また、https://techblog.nhn-techorus.com/page/1 のソースを読むと、次のことがわかります。
<article>
タグに囲われた部分で記事へのリンクが定義されている<article>
タグの中の<h2>
タグの中の<a>
タグで記事へのリンクが定義され、タイトルが表示されている- CSSセレクターの記法でいうと、
article>h2>a
- CSSセレクターの記法でいうと、
<article>
タグの中の<ul>
タグの中の<li class="entry_date">
タグの中の<a>
で記事の執筆日が書かれている- CSSセレクターの記法でいうと、
article>ul>li[class="entry_date"]>a
- CSSセレクターの記法でいうと、
次に、記事の詳細ページを見てみます。すると、次がわかります。
- たとえば記事IDが
185
のページは、 https://techblog.nhn-techorus.com/archives/185 に置かれている - 本文は
<div class="entry_content">
タグ以下に書かれている- CSSセレクターの記法でいうと、
div[class="entry_content"]
- CSSセレクターの記法でいうと、
準備
Ubuntu 16.04のターミナル上で実行することを前提とします。
必要なプログラムをインストールします。
sudo apt install ipython3 python3-lxml libxml2-dev libxslt-dev python-dev python3-pip sudo pip3 install cssselect html2text
lxmlはHTMLのパースをするために、html2textはHTMLの内容を地の文に変換するために使います。
スクレイピングの実行
いよいよ実際にスクレイピングします。
Python3のインタプリタを起動します。ここでは、標準の対話環境より便利なIPythonを使います。
ipython3
必要なライブラリを import
し、変数を定義します。
import requests, lxml.html, time, html2text from lxml.cssselect import CSSSelector base_url = "https://techblog.nhn-techorus.com/" num_of_pages = 14
記事の一覧を取得します。記事のIDをキー、日付とタイトルのタプルを値とする辞書 articles
を作成します。
def get_attrs(article): """ CSSSelector で抽出された article タグを受け取り、記事のID、日付、タイトルのタプルを返す """ id = CSSSelector("h2>a")(article)[0].get("href").split("/")[-1] date = CSSSelector("ul>li[class=\"entry_date\"]>a")(article)[0].text title = CSSSelector("h2>a")(article)[0].text return (id, date, title) articles = {} for i in range(1, num_of_pages + 1): r = requests.get(requests.compat.urljoin(base_url, "page/{}".format(i))) # HTTPSリクエストを送信 parsed_html = lxml.html.fromstring(r.content) # レスポンスのHTMLを lxml.html でパース for article in CSSSelector("article")(parsed_html): # articleタグを抽出 articles[get_attrs(article)[0]] = get_attrs(article)[1:] # articles変数に情報を追加
articles
にページの情報が格納されます。
In [46]: articles Out[46]: {'1047': ('2015年12月18日', 'gulp+babelでのフロントエンド開発について ? 3. bootstrapのビルド'), '7555': ('2017年12月25日', 'k平均法による減色処理に混合ガウスモデルを適用してもうまくいかない'), '2620': ('2016年03月31日', 'IT業界研究に役立つハンズオンセミナー\u3000レポート'), '185': ('2015年06月24日', 'AWSが簡単&すぐに使える「ECO Pack」のご紹介'), ...
記事の本文も取得します。ここでは、辞書 articles
を上書きし、値のタプルに記事の本文を追加することにします。
現時点で記事が130前後あり、記事を1つ取得するごとに1秒間の sleep()
を入れているため、実行に5分程度かかります。
h = html2text.HTML2Text() h.ignore_links = True # ここではリンクを無視することにする def get_content(id): """ 記事IDを受け取って、記事の本文を返す """ r = requests.get(requests.compat.urljoin(base_url, "archives/{}".format(id))) parsed_html = lxml.html.fromstring(r.content) content = CSSSelector("div[class=\"entry_content\"]")(parsed_html)[0] return h.handle(lxml.html.tostring(content).decode()) for id in articles.keys(): articles[id] = articles[id] + (get_content(id), ) time.sleep(1) # サーバの負荷軽減のため、記事ごとに1秒間の間隔をあける
これで、辞書 articles
に記事IDごとに日時、タイトル、本文が保存されました。このデータを使ってデータ分析などを行うことができます。
まとめ
この記事では、当ブログの記事をスクレイピングすることで、クローリング・スクレイピングのやり方の実際を示しました。
参考文献
- search engine – What is the difference between web-crawling and web-scraping? – Stack Overflow
Stack Overflowでの、クローリングとスクレイピングの違いについての話題です。(英語) - robots.txt ファイルについて – Search Console ヘルプ
- Robots Exclusion Standard – Wikipedia
robots.txt
の説明です。 - セレクタの種類-CSSの基本
CSSセレクタの解説がされています。 - 加藤耕太『Pythonクローリング&スクレイピング -データ収集・解析のための実践開発ガイド-』
- 岡崎市立中央図書館事件 – Wikipedia
図書館のシステムに負荷をかけたクローラの作成者が逮捕された事件です。 - lxml – Processing XML and HTML with Python
- Requests: HTTP for Humans — Requests 2.18.4 documentation
- html2text 2018.1.9 : Python Package Index
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitterデータ分析と機械学習とソフトウェア開発をしています。 アルゴリズムとデータ構造が好きです。
Recommends
こちらもおすすめ
-
Rで実践!欠損データ分析入門【2】
2017.12.20
-
ディープラーニングを使ったウェブアプリケーションをすばやく作る
2018.12.1
-
Docker Composeで3層ウェブアーキテクチャを構成する
2019.3.15
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16