BeautifulSoupのclassを使った完全一致・部分一致

Webスクレイピングを行う際に、HTMLの要素を抽出する必要があります。BeautifulSoupは、Pythonのライブラリであり、HTMLやXMLの構文解析を行うことができます。この記事では、BeautifulSoupのclass属性を使った完全一致と部分一致について解説します。

BeautifulSoupのclass属性について

HTMLの要素には、class属性があります。class属性は、その要素に対してCSSでスタイルを適用するために使われます。class属性には、複数のクラスを指定することができます。

<p class="red bold">このテキストは赤くて太字です</p>

このように、class属性に複数のクラスを指定する場合は、スペースで区切って指定します。

完全一致でのclass属性の利用方法

BeautifulSoupでは、class属性を指定してHTMLの要素を抽出することができます。class属性を完全一致で指定する場合は、以下のようにします。

from bs4 import BeautifulSoup
html = '''HTML
<div class="box">
  <p class="red">赤いテキスト</p>
  <p class="blue">青いテキスト</p>
  <p class="green">緑のテキスト</p>
</div>
'''
soup = BeautifulSoup(html, 'html.parser')
# class属性が"box"のdiv要素を抽出
box = soup.find('div', class_='box')
# class属性が"red"のp要素を抽出
red = box.find('p', class_='red')
print(red.text) # 赤いテキスト

このように、findメソッドを使ってclass属性を指定する場合は、class_という引数を使います。class_という引数を使うことで、Pythonの予約語のclassと区別することができます。

部分一致でのclass属性の利用方法

class属性を部分一致で指定する場合は、以下のようにします。

from bs4 import BeautifulSoup
html = '''HTML
<div class="box">
  <p class="red">赤いテキスト</p>
  <p class="blue">青いテキスト</p>
  <p class="green">緑のテキスト</p>
</div>
'''
soup = BeautifulSoup(html, 'html.parser')
# class属性に"e"を含むp要素を抽出
elems = soup.find_all('p', class_=lambda x: x and 'e' in x)
for elem in elems:
    print(elem.text) # 赤いテキスト 青いテキスト

このように、find_allメソッドを使ってclass属性を部分一致で指定する場合は、lambda式を使います。lambda式では、class属性に’e’が含まれる要素を抽出するように指定しています。

完全一致と部分一致の違いについて

完全一致でclass属性を指定する場合は、指定したクラス名と完全に一致する要素が抽出されます。一方、部分一致でclass属性を指定する場合は、指定した文字列を含むクラス名を持つ要素が抽出されます。

例えば、以下のようなHTMLがあるとします。

<div class="foo">
  <p class="foobar">テキスト1</p>
  <p class="barfoo">テキスト2</p>
  <p class="foo bar">テキスト3</p>
</div>

この場合、class属性が”foo”の要素を完全一致で指定すると、<p class=”foo bar”>テキスト3</p>が抽出されます。一方、部分一致で指定すると、3つのタグpが抽出されます。

実際のサンプルコードでの解説

以下は、実際にBeautifulSoupのclass属性を使った完全一致と部分一致のサンプルコードです。

from bs4 import BeautifulSoup
import requests
# Webページの取得
url = 'http://example.com'
res = requests.get(url)
html = res.text
# BeautifulSoupの初期化
soup = BeautifulSoup(html, 'html.parser')
# class属性が"header"の要素を抽出
header = soup.find('div', class_='header')
# class属性が"nav"の要素を抽出
nav = soup.find('ul', class_='nav')
# class属性に"link"を含むa要素を抽出
links = nav.find_all('a', class_=lambda x: x and 'link' in x)
# 結果の表示
print(header)
print(nav)
for link in links:
    print(link)

このプログラムでは、requestsライブラリを使って、http://example.comというWebページを取得しています。取得したWebページをBeautifulSoupで解析し、class属性が”header”の要素と”nav”の要素を抽出しています。また、class属性に”link”を含むa要素を抽出しています。

注意点とトラブルシューティング

BeautifulSoupを使ってclass属性を指定する場合は、以下の点に注意してください。

  • class_という引数を使うことで、Pythonの予約語のclassと区別することができます。
  • 部分一致でclass属性を指定する場合は、lambda式を使います。
  • class属性には複数のクラスを指定することができます。複数のクラスを指定する場合は、スペースで区切って指定します。
  • class属性には、日本語や記号なども使えます。
  • class属性を指定しても、該当する要素が見つからない場合は、Noneが返されます。

まとめ

この記事では、BeautifulSoupのclass属性を使った完全一致と部分一致について解説しました。完全一致でclass属性を指定する場合は、指定したクラス名と完全に一致する要素が抽出されます。一方、部分一致でclass属性を指定する場合は、指定した文字列を含むクラス名を持つ要素が抽出されます。BeautifulSoupを使ってHTMLの要素を抽出する際に、class属性を活用して効率的なWebスクレイピングを行いましょう。