BeautifulSoup4でclass名を指定して要素を得る
- 作成日: 2020-11-22
- 更新日: 2023-12-24
- カテゴリ: BeautifulSoup4
クラス名を指定して要素を得る
「BeautifulSoup4(ビューティフル・スープ・フォー)」はHTML/XMLをパースするPythonの外部ライブラリです。
最近のPythonを使ったスクレイピングではひんぱんに利用されるライブラリの1つです。
HTMLの要素(タグ)の属性にclass
とそのクラス名を指定できますが、BeautifulSoup4でこの要素のクラス名を指定して、要素を検索し取得する方法を解説します。
結論から言うとよく使われるclass
名の指定方法は↓のうちのどれかです。
soup.find('p', class_='myclass')
soup.find_all('p', class_='myclass')
soup.select('p.myclass')
↑の方法の他にもclass
名の指定方法はありますが、それは以降の記事で解説します。
今回は具体的には↓を見ていきます。
- find()でクラス名を指定する
- find_all()でクラス名を指定する
- select()でクラス名を指定する
find()でクラス名を指定する
BeautifulSoup
クラスのオブジェクトはfind(ファインド)
メソッドを持っています。
これは単一の要素を検索したい時に使用するメソッドです。
find()
はbs4.BeautifulSoup
やbs4.element.Tag
のオブジェクトから使用できます。
find()の構造
find()
メソッドは↓のような構造になっています。
find(
self,
name=None, # タグ名を表す文字列
attrs={}, # 属性値を表す辞書
recursive=True, # 再帰するならTrue
text=None, # タグのテキストを表す文字列
**kwargs # キーワード引数
)
↑のうちclass
名の検索に使用するのはattrs
引数と**kwargs
引数です。
find()の返り値
find()
の返り値はbs4.element.Tag
かNone
です。
要素が見つかった場合はbs4.element.Tag
を返し、見つからなかった場合はNone
を返します。
Tag
はfind()
やfind_all()
, select()
メソッドを持っているので再帰的に検索が可能です。
attrs引数にクラス名を指定する
find()
メソッドのattrs
引数にクラス名を指定して検索すると、そのクラス名の要素を得ることが出来ます。
soup.find('p', attrs={ 'class': 'myclass' })
例えば↓のように使います。
from bs4 import BeautifulSoup
html = '''
<p>1</p>
<p class="bird">2</p>
<p class="bird">3</p>
'''
soup = BeautifulSoup(html, 'html.parser')
# class名がbirdのpタグを検索
el = soup.find('p', attrs={ 'class': 'bird' })
# タグのテキストを表示
print(el.text)
↑の出力結果↓。
2
find()
メソッドは最初に見つけた要素を返します。
↑の場合、クラス名にbird
を持っているタグは2つありますが、find()
では最初のタグを見つけて返しています。
attrs引数にクラス名のリストを指定する
attrs
引数の辞書の値にはリストを指定することも出来ます。
リストの要素にクラス名を指定することで、クラス名をOR
検索することが可能です。
soup.find('p', attrs={ 'class': ['bird', 'cat'] })
たとえば↓のように使います。
from bs4 import BeautifulSoup
html = '''
<p>1</p>
<p class="bird">2</p>
<p class="dog">3</p>
'''
soup = BeautifulSoup(html, 'html.parser')
# class名がbirdまたはcatのpタグを検索
el = soup.find('p', attrs={ 'class': ['bird', 'cat'] })
# タグのテキストを表示
print(el.text)
↑の出力結果↓。
2
↑の場合、find()
のclass
名にbird
またはcat
をリストで指定しています。
そのためこのfind()
のクラス名の検索はOR
検索になります。
つまりクラス名にbird
またはcat
を持つ要素を取得するようになります。
↑の場合、クラス名にbird
を持っているp
タグがヒットしています。
attrs引数に正規表現を指定する
attrs
引数の辞書の値には正規表現オブジェクトを指定することも出来ます。
正規表現でクラス名を検索したい時は↓のようにします。
import re
soup.find('p', attrs={ 'class': re.compile(r'blue-.*') })
↓のように使います。
from bs4 import BeautifulSoup
import re
html = '''
<p class="red-ocean">1</p>
<p class="blue-ocean">2</p>
<p class="green-ocean">3</p>
'''
soup = BeautifulSoup(html, 'html.parser')
# 正規表現「blue-.*」にヒットする要素を取得
el = soup.find('p', attrs={ 'class': re.compile(r'blue-.*') })
# タグのテキストを表示
print(el.text)
↑の出力結果↓。
2
attrs
引数にはリストを指定できますが、リスト内の要素にも正規表現オブジェクトは指定できます。
soup.find('p', attrs={ 'class': [re.compile(r'blue-.*'), re.compile(r'red-.*')] })
キーワード引数でclass名を指定
find()
のキーワード引数class_
にクラス名を指定することで検索することも出来ます。
soup.find('p', class_='blue')
↓のように使います。
from bs4 import BeautifulSoup
html = '''
<p class="red">1</p>
<p class="blue">2</p>
<p class="green">3</p>
'''
soup = BeautifulSoup(html, 'html.parser')
# クラス名blueにヒットする要素を取得
el = soup.find('p', class_='blue')
# タグのテキストを表示
print(el.text)
↑の出力結果↓。
2
キーワード引数class_
の値にはリストや正規表現オブジェクトを指定することも出来ます。
リストの場合はOR
検索になります。
# OR検索
soup.find('p', class_=['blue', 'red'])
# 正規表現による検索
import re
soup.find('p', class_=re.compile(r'blue-.*'))
タグ名を無視してクラス名のみを指定する
find()
の引数name
にTrue
を指定すると、タグ名を無視した検索を行えます。
from bs4 import BeautifulSoup
html = '''
<p class="red">1</p>
<p class="blue">2</p>
<p class="green">3</p>
'''
soup = BeautifulSoup(html, 'html.parser')
# クラス名blueにヒットする要素を取得
el = soup.find(True, class_='blue')
print(el.text)
↑の出力結果↓。
2
find_all()でクラス名を指定する
find_all(ファインド・オール)
メソッドは検索条件にヒットした複数の要素をまとめて取得するメソッドです。
find_all()
はfind()
に似たインターフェースを持っています。
find_all()
はbs4.BeautifulSoup
やbs4.element.Tag
のオブジェクトから使用できます。
find_all()の構造
find_all()
の構造は↓になります。
find_all(
self,
name=None, # タグ名を表す文字列
attrs={}, # 属性を表す辞書
recursive=True, # 再帰をするならTrue
text=None, # 要素内のテキストを表す文字列
limit=None, # 再帰上限数
**kwargs # キーワード引数
)
find()
と同様に、クラス名の指定に使うのはattrs
引数と**kwargs
引数です。
find_all()によるクラス名の検索方法
クラス名を指定するfind_all()
の使い方は、find()
と同じです。
違いは、find_all()
の検索結果がbs4.element.ResultSet
で返ってくる点です。
attrs
引数によるクラス名の指定↓。
soup.find_all('p', attrs={ 'class': 'blue' })
attrs
引数の値にリストを指定する↓。
この場合はOR
検索です。
soup.find_all('p', attrs={ 'class': ['blue', 'red'] })
attrs
引数の値に正規表現オブジェクトを指定する↓。
import re
soup.find_all('p', attrs={ 'class': re.compile('blue-.*') })
attrs
引数のリストに正規表現オブジェクトを指定する↓。
import re
soup.find_all('p', attrs={ 'class': [re.compile('blue-.*'), re.compile('red-.*')] })
タグ名を無視してクラス名のみで指定する↓。
soup.find_all(True, class_='blue')
find_all()の返り値(ResultSet)
find_all()
の結果はbs4.element.ResultSet
で返ってきます。
els = soup.find_all('p', class_='blue')
print(type(els))
# <class 'bs4.element.ResultSet'>
このResultSet
はlist
を継承したクラスです。
そのため↓のようにfor
文で回したり、インデックス参照したりできます。
els = soup.find_all('p', class_='blue')
for el in els:
print(el.text)
print(els[0].text)
select()でクラス名を指定する
select()
はセレクターを指定して要素を検索できるメソッドです。
find()
やfind_all()
より視覚的にわかりやすく検索することが出来ます。
select()の構造
select()
の構造は↓のようになっています。
select(self, selector, _candidate_generator=None)
selector
にはセレクターを指定します。
これはCSSなどでお馴染みの記法です。
select()
の返り値はfind_all()
と同じResultSet
です。
クラス名を指定して検索する
たとえばクラス名blue
がくっついているp
タグを検索したい場合は↓のようにします。
el = soup.select('p.blue')
↓のように使います。
from bs4 import BeautifulSoup
html = '''
<p class="red">1</p>
<p class="blue">2</p>
<p class="green">3</p>
'''
soup = BeautifulSoup(html, 'html.parser')
# クラス名blueにヒットする要素pを取得
els = soup.select('p.blue')
print(els[0].text)
↑の出力結果↓。
2
また、クラス名単体で検索したい場合は↓のように指定します。
el = soup.select('.blue')
おわりに
BeautifulSoup4では柔軟にクラス名を指定して要素を検索することが出来ます。
もしよかったら、ぜひこの記事をブックマークして使い方を覚えるまで参照してみてください。
🦝 < クラス名を制する者はHTMLを制す