【Python】スクレイピング:BeautifulSoup4によるHTML解析

/

【Python】スクレイピング:BeautifulSoup4によるHTML解析

本記事ではPythonによるスクレイピング時に利用する、BeautifulSoup4によるHTML解析について解説していきます。

Pythonは様々な用途で利用されるプログラミング言語ですが、スクレイピング時に利用されることも非常に多いです。

IT用語の確認

スクレイピングとは、プログラムを用いてWebサイトから大量のデータを集める手法です

スクレイピングではクローリングにSeleniumを用い、HTML解析にBeautifulSoup4を利用します。

ここではBeautifulSoup4によるHTML解析手法を詳しく説明していきます。

スクレイピング

インターネット上には多種多様なWebサイトがあり、非常に多くの情報がインターネット上に存在します。

それらデータを利用するために、手作業で大量のデータを集めようと思うと多くの時間を有してしまいます。そこで利用するのがスクレイピングです。

スクレイピングとはインターネット上のWebサイトから、大量のデータを集める作業をプログラムに行わせる手法です。

Pythonでスクレイピングを行う際に利用するモジュールは次のようなものがあります。

  • webbrowser:Webサイトをブラウザで開く
  • Requests:インターネットからWebページをダウンロードする
  • Beautiful Soup:HTMLの解析を行う
  • Selenium:Webブラウザを操作する

WebサイトはHTMLというプログラミング言語で書かれています。HTMLを解析することで必要な情報を抽出して利用できるようにするのがスクレイピングです。

BeautifulSoup4

BeautifulSoup4とは

BeautifulSoup4はWebサイトのHTMLから情報を抽出するためのライブラリです。
抽出したHTMLを解析して、目的のデータを取得できます。

BeautifulSoup4のモジュール名はbs4(Beautiful Soup バージョン4)です。

標準ライブラリではないため、pipコマンドでインストールする必要があります。

pip install beautifulsoup4

PythonをAnacondaでインストールしている方は、すでにインストール済みなのでpipでのインストールは不要です。

Pythonスクリプトでインポートする際はbs4と書くので注意してください。

import bs4

本記事執筆時のBeautifulSoup4のバージョンは4.8.0です。

Seleniumと組み合わせる

スクレイピングではBeautifulSoup4とSeleniumを組み合わせることが多いです。

なぜならログインが必要なWebサイトやJavaScript、Ajaxを利用しているWebサイトからHTMLを取得するには、Seleniumでブラウザ操作を行う必要があるからです。

現代では多くのWebサイトでログイン必須であったり、Ajaxでデータを読み込むWebサイトが多いです。

SeleniumだけでもHTML分析が可能ですが、BeautifulSoup4の方が高速なため、クローリングにはSelenium、HTML分析にはBeautifulSoup4を利用することをお勧めします。

Seleniumの使い方については以下記事をご参照ください。

BeautifulSoup4の利用方法

次の流れでWebページのスクレイピングを行います。

  1. ソースコード(HTML)の取得
  2. BeautifulSoupオブジェクトの生成
  3. BeautifulSoupオブジェクトから要素の検索
  4. 要素からテキストや属性を取得

ソースコード(HTML)の取得

スクレイピングには対象WebページのHTMLを取得する必要があります。
WebページのHTMLを取得する方法は次の2つあります。

  • Requestsモジュールのget()メソッドを利用
  • Seleniumモジュールのpage_sourceを利用

Requestsモジュール

requests.get()の引数には対象のWebページのURLを指定します。

import requests
res = requests.get(URL)

request.get()はWebサーバーへリクエストを送信し、サーバーからのレスポンスをレスポンスオブジェクトとして返します。

返ってきたレスポンスオブジェクトに対してtextを使うことでHTMLテキストを取得できます。

res.text

Seleniumモジュール

WebDriverオブジェクトに対してpage_sourceを利用することで、HTMLを取得できます。

driver.page_source

BeautifulSoupオブジェクトの生成

取得したHTMLテキストをbs4.BeautifulSoup()関数に渡すことでBeautifulSoupオブジェクトが返ってきます。

構文

BeautifulSoup(HTMLテキスト, パーサー)

オブジェクトを作成するためのパーサーには以下のパーサーが指定できます。

パーサー名 説明
html.parser 標準ライブラリに含まれる
lxml 高速なパーサー。pipでインストールが必要
html5lib pipでインストールが必要

基本的にはどのパーサーを使っても違いはないです。

私の場合

Python3に最初から組み込まれているhtml.parserを主に利用しています

パーサーのlxmlは整っていないHTMLでもパースできる利点があります。
パーサーのhtml5libはlxmlよりさらに問題のあるHTMLをパースすることができます。

タグが欠けている、規則に従っていないHTMLを解析する場合はlxmlかhtml5libを利用してみましょう。

BeautifulSoup()関数で返ってきたBeautifulSoupオブジェクトに用意されているメソッドを利用することで、HTML文書内から必要な情報だけを抽出できます。

import requests
import bs4

res = requests.get("https://office54.net/")
html_text = bs4.BeautifulSoup(res.text, 'html.parser')
print(type(html_text))
# <class 'bs4.BeautifulSoup'>

BeautifulSoupオブジェクトから要素の検索

BeautifulSoupオブジェクトに用意されているメソッドを利用することで、HTMLから要素を抽出できます。

メソッドには以下に記す「select系」と「find系」の2種類あります。
それぞれ引数に条件(CSSセレクタや要素名、属性値)を指定して、条件に合った要素を取得します。

メソッド名 説明
select() 条件に合うすべての要素を取得
select_one() 条件に合う最初の要素を取得
find_all() 条件に合うすべての要素を取得
find() 条件に合う最初の要素を取得

select()とfind_all()は、Tagオブジェクトのリストを返します。
select_one()とfind()は、Tagオブジェクトを返します。

selectとfindの違い

selectとfindの各メソッドの機能は同じです。条件に合う要素を取得できます。

これらの違いは、引数に指定する条件の指定方法です。

selectでは引数に「CSSセレクタ」を指定します。
findでは引数に「要素名, 属性キーワード」で指定します。

例えばa要素でhref属性がhttps://office54.netの要素を取得するにはそれぞれ次のように指定します。

html_text.select("a[href='https://office54.net']")
html_text.find_all("a", href="https://office54.net")

私の場合

CSSセレクタの方が慣れているので主にselect系のメソッドを利用しています。

import requests
import bs4

res = requests.get("https://office54.net/")
html_text = bs4.BeautifulSoup(res.text, 'html.parser')
href = html_text.select("a[href='/']")
print(type(href))
# 
str(href[0])
# '<a href="/"><div id="logo">OFFICE54</div></a>'

要素からテキストや属性を取得

selectまたはfindメソッドで取得したTagオブジェクトから内部テキストを取得するには、get_text()メソッドを使用します。

href[0].get_text()
# 'OFFICE54'

Tagオブジェクトにattrsを使用すると、要素の属性を辞書として返します。

href[0].attrs
# {'href': '/'}

Tagオブジェクトの属性値のみを取得する場合はget()メソッドを利用し、引数に属性名を指定します。

href[0].get('href')
# '/'

まとめ

本記事「【Python】スクレイピング:BeautifulSoup4によるHTML解析」はいかがでしたか。

BeautifulSoup4とSeleniumを駆使して、スクレイピングプログラムを作成してみてください。