情報収集や、データ分析を行うときに僕がよく活用しているBeautiful Soup。
上手に使いこなせば、Web上のどんなデータでも取得することができます。
...ですが、意外とBeautiful Soupは奥が深い..。ということで、僕のよく使っているBeautiful Soupの使用方法についてまとめておきます。

今回はテーブル(表)の操作について
Beautiful Soupのテーブル(表)操作
今回はこのような構成のテーブルからデータを取得していきます。
ジャンル | タイトル | 作者 | 中古価格 | 定価 | 発売日 |
---|---|---|---|---|---|
漫画 | 太っちょ大統領のカニ鍋大戦争 | 中田尻男 | 350円 | 770円 | 2020/04/03 |
漫画 | メダカのクリスマス | 神坂半魚人 | 400円 | 484円 | 2020/03/04 |
: | : | : | : | : | : |
HTMLは以下のようになっております。
<table id="table-id" class="dataTable">
<thead>
<!-- ここは省略 -->
</thead>
<tbody id="table-tbody-id" role="alert" aria-live="polite" aria-relevant="all">
<tr class="tr-1">
<td class="table_goods_kind sorting_1">漫画</td>
<td class="table_goods_title"><a href="/old/0019446283" target="_blank">太っちょ大統領のカニ鍋大戦争</a><br>
<div id="item_style_1"></div>
</td>
<td class="table_own"><a href="/disp/CSfSearch.jsp?q=%90X%96%7B%8Es%95v" target="_blank">中田尻男</a>(著者)</td>
<td class="table_usedprice">350円</td>
<td class="table_price">770円</td>
<td class="table_sellday">2020/04/03</td>
</tr>
<tr class="tr-2">
<td class="table_goods_kind sorting_1">漫画</td>
<td class="table_goods_title"><a href="/old/0019413633" target="_blank">メダカのクリスマス</a><br>
<div id="item_style_1"></div>
</td>
<td class="table_own"><a href="/disp/CSfSearch.jsp?q=%90_%94%F6%97t%8Eq" target="_blank">神坂半魚人</a>(著者)</td>
<td class="table_usedprice">400円</td>
<td class="table_price">484円</td>
<td class="table_sellday">2020/03/04</td>
</tr>
<!-- 以下省略 -->
</tbody>
</table>
テーブル(表)要素の全取得
テーブル(表)要素を丸ごと全取得してみます。あまりこの用途はないかもしれませんが...
今回の場合、table要素のclassがdataTable
となっているので、これを指定して取得します。
table_elements = soup.find_all('table', class_='dataTable')
取得したtable要素を分解して利用したい場合はfor文で1要素ずつ処理していきます。
for table_element in table_elements:
#1要素ずつ出力してみたり...
print(table_element)
特定の列の取得
今回のテーブルはジャンル
、タイトル
、作者
、中古価格
、定価
、発売日
の列から成ります。
これら特定の列の取得を行っていきます。
td要素のclassをそれぞれ指定しながら、細かく特定のデータを取得していきます。
#ジャンルの取得
genres = soup.find_all('td', class_='table_goods_kind')
#タイトルの取得
titles = soup.find_all('td', class_='table_goods_title')
#作者の取得
authors = soup.find_all('td', class_='table_own')
#中古価格の取得
oldprices = soup.find_all('td', class_='table_usedprice')
#定価の取得
originalprices = soup.find_all('td', class_='table_price')
#発売日の取得
selldays = soup.find_all('td', class_='table_sellday')
上記のようにして一致する要素の全取得を行います。これらを細かく利用するにはfor文などで取り出します。
試しにタイトルを一つずつ取得していきます。
for title in titles:
#1要素ずつ出力してみたり...
print(title.get_text()) #get_text()で文字データを取得する。
>>太っちょ大統領のカニ鍋大戦争
>>メダカのクリスマス
>>:
テーブル(表)上のデータを値として取得する場合は要素に対してget_text()
を行う必要があります。
href要素(リンク)の取得
上記のタイトル要素にはhref要素も含んでいます。
<td class="table_goods_title"><a href="/old/0019446283" target="_blank">太っちょ大統領のカニ鍋大戦争</a>
このhref=xxx
の部分を取得していきます。
#タイトルの取得
titles = soup.find_all('td', class_='table_goods_title')
#全要素から1つづつ取り出していく
for title in titles:
title_href = title.find('a').get('href')
print(title_href)
>>/old/0019446283
>>/old/0019413633
>>:
特定のtd
全要素から1つずつ取り出した後、find('a').get('href')
でaタグ
のhref要素
を取得します。
組み合わせることで目的の要素を取得することが出来ます。
同じ行に紐づく兄弟要素の取得
少しここらへんからはマニアックな取得方法になりますが、僕が便利だなと思ったのでまとめておきます。
特定の列の兄弟要素の取得をしてみます。td
要素は基本兄弟要素になっていますので、指定した列の要素に紐づく別のtd
要素の取得が可能です。
例としてタイトルに紐づく中古価格、定価を兄弟要素として取得していきます。
#タイトルの取得
titles = soup.find_all('td', class_='table_goods_title')
#全要素から1つづつ取り出していく
for title in titles:
oldprice = title.next_sibling.next_sibling #タイトル要素の次の次の要素
originalprice = title.next_sibling.next_sibling.next_sibling #タイトル要素の次の次の次の要素
print(oldprice.get_text(), originalprice.get_text())
>>350円 770円
>>400円 484円
>>:
兄弟要素を取得するにはnext_sibling
を使います。next_sibling
を使うことで次の兄弟要素を取得できます。さらに次の兄弟要素を取得したい場合はさらに、next_sibling
を使い、さらに次の兄弟要素を取得したい場合はnext_sibling
を...という感じです。
少し間抜けな記述の仕方に見えますが、簡単に兄弟要素を取得することができて便利です。
Beautiful Soupを使いこなそう
今回紹介した記述法で、ある程度のテーブル(表)のデータ取得はできるかと思います。
僕個人的に思うには、soup.find_all('td', class_='xxx')
って記述が非常に便利だし、よく使いますね。
td要素に限らずspan
要素を取得したいならsoup.find_all('span', class_='table_goods_title')
で良いし、div
要素を取得したいならsoup.find_all('div', class_='table_goods_title')
って書けばいい。
beautifulsoupでのデータ取得の8割はこの記述で可能です。
Beautifulsoupを活用して競馬分析をしてみたお話です。


スクレイピングを学んでいきたい方におすすめの本と動画を紹介しています。

コメント