BeautifulSoup

【Python】Beautiful SoupによるWebスクレイピングの基本

【Python】Beautiful SoupによるWebスクレイピングの基本

PythonでBeautifu Soupを使ってWebスクレイピングする基本について解説します。

Beautiful SoupによるWebスクレイピングの基本

Webスクレイピングとは、Webサイトで公開されている情報から特定の情報を抽出してきて活用する技術のことを言います。

似たような言葉にクローリングという言葉がありますが、クローリングはWebを巡回してWebページを収集してくることを言います。クローリングするプログラムをクローラーと言いますが、代表的なものにGoogleの検索エンジンがインデックスを作るためのクローラーがあります。

スクレイピングは「こすること」「削ること」といった意味があるので、必要な情報を明示的に抽出するという意味があるのでクローリングとは少し異なります。

PythonでWebスクレイピングとなるとよく出てくるのが「Beautiful Soup」と「Selenium」です。本記事ではBeautiful SoupでWebスクレイピングをするにあたっての基本を紹介します。

Note

Beautiful Soupの公式ドキュメントページはこちらを参考にしてください。

Note

Seleniumは本来はテストの自動化ツールで、Webブラウザの操作を自動化することでWebシステムのテストを人手ではなくプログラムで実行できるものです。

例えば健全性テスト項目を実行するテストプログラムをSeleniumを使って用意しておけば、システム改修時に改修箇所以外の主要なプログラムが一通り正常に動作するかを簡単に確認できます。その技術の中でWeb構造を取得できるため、Webスクレイピングの方法としても使用されることがあります。

Seleniumの使い方については「SeleniumによるWebスクレイピングの基本」でまとめているので興味があれば参考にしてください。

Beautiful Soupのインストール

Beautiful Soupを使用するにはpipにてインストールを実施してください。

pip install beautifulsoup4

以降で紹介するコードは、バージョン4.11.1で実行した例になります。

Beautiful Soupを使ってみる

今回はPython公式ページからhtmlを取得してきて、情報を抽出してみることを考えてみようと思います。

from bs4 import BeautifulSoup
import requests

# 対象となるURLを取得する
html = requests.get('https://www.python.org/')
# print(html.text)

# Beautiful Soupに対象のHTMLテキストを設定する
bs = BeautifulSoup(html.text, features='html.parser')

# タイトルを取得してみる
titles = bs.find_all('title')
print(titles[0].text)

# タグの内容を取得してみる
intro = bs.find_all('div', {'class': 'introduction'})
print(intro[0].text)
【実行結果】
Welcome to Python.org

Python is a programming language that lets you work quickly and integrate systems more effectively. Learn More

※実行結果は参照先ページ構成により異なる又は取得失敗する可能性があります。

【詳細解説】

以降で、各部分について詳細を説明していきます。まずはBeautiful Soupをimportする必要があります。また、WebからHTMLを取得するためにrequestsについてもimportしています。

from bs4 import BeautifulSoup
import requests

対象となるURLからHTMLを取得してきて、Beautiful Soupへ渡しているのが以下の部分です。BeautifulSoupへは対象のHTML文字列とfeatures引数で’html.parser’を指定します。

# 対象となるURLを取得する
html = requests.get('https://www.python.org/')
# print(html.text)

# Beautiful Soupに対象のHTMLテキストを設定する
bs = BeautifulSoup(html.text, features='html.parser')

ここまでくると、HTMLの情報が解析されるため、各情報を抽出する準備が整った状態になります。以降で各情報取得をしている部分について説明します。

タグを指定して情報を取得する

titleタグを指定して取得している部分を説明します。Chromeの場合、ブラウザ上で右クリックし「ページのソースを表示」とするとHTMLの内容を見ることができます。なおEdge等の他のブラウザでも同様の機能があります。

今回対象とするPython公式ページのソースを見てみるとtitleタグとして以下のような部分があります。

<title>Welcome to Python.org</title>

この部分の情報をBeautiful Soupで取得しているのが以下の部分です。

# タイトルを取得してみる
titles = bs.find_all('title')
print(titles[0].text)

Beautiful Soupのfind_allメソッドを使用することで、titleタグの情報を取得してくることができます。HTML内に複数のtitleタグがある場合があるため、リストで返却がされます。そのため今回の例では[0]と指定して表示をしています。タグの内容については、textプロパティで取得ができます。

タグとclassを指定して取得する

次は、画面上で表示されている部分の文字列を取得してみることを考えてみます。

BeautifulSoup Webスクレイピング

※公式ページから引用しています。表示内容は変更されている場合があります。

上記の部分ではHTMLでは以下のようになっています。

<div class="introduction">
<p>Python is a programming language that lets you work quickly <span class="breaker"></span>and integrate systems more effectively. 
<a class="readmore" href="/doc/">Learn More</a></p>
</div>

この部分を取得するには、divタグのclass=”introduction”の部分を取得してくるようにBeautiful Soupで指定します。具体的には以下の部分です。

# タグの内容を取得してみる
intro = bs.find_all('div', {'class': 'introduction'})
print(intro[0].text)

titleタグを取得してきたときと同様で、find_allメソッドを使用するのは同じです。

‘div’タグを指定するとともに加えて引数で{‘class’: ‘introduction’}という辞書の形式で指定をしています。

titleタグの取得例と同じようにリストで返却がされます。そのため今回の例では[0]と指定して表示をしています。タグの内容については、textプロパティで取得ができる点は同様です。

このようにタグやclassを指定して情報を取得することが可能です。

【補足】パーサーの明示について

上記で紹介したコードでBeatutiful Soupのインスタンスを生成する際に、「features=’html.parser’」というものを指定していました。この引数を以下のように除いても実行することは可能です。

# Beautiful Soupに対象のHTMLテキストを設定する
bs = BeautifulSoup(html.text)

しかし、以下のようなWarningが出力されます。内容を見るとパーサーが明示されていないという警告で、html.parserを使用しているけれども他の環境では動作が異なる場合があると言っています。

GuessedAtParserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("html.parser"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.

さらには以下のメッセージも出力され、Warningを除去にはfeatures=’html.parser’を明示的にコンストラクターに渡すようにメッセージが出ます。実行結果が把握できるようにパーサーはfeaturesで明示するようにしましょう。

To get rid of this warning, pass the additional argument 'features="html.parser"' to the BeautifulSoup constructor.

※Beautiful Soupのバージョンによりメッセージは異なる場合がありますので、各実行環境にてWarningメッセージはよく読むようにしてください。