【Python】BeautifulSoupのfindとfind_allの使い方【スクレイピング】
目次
はじめに
BeautifulSoupのfind
メソッドの使い方を解説しています。
findの使い方
find
メソッドは↓のようにして使います。
from bs4 import BeautifulSoup html = ''' <h1>海賊王に俺はなる!</h1> <p>俺は世界一の海賊になるんだ!</p> ''' soup = BeautifulSoup(html, 'html.parser') el = soup.find('h1') print(el)
↑のコードを実行すると↓のような結果になります。
<h1>海賊王に俺はなる!</h1>
find
メソッドの公式ドキュメントとヘルプを見てみます。
bs4.elementモジュールのfindメソッドのヘルプ: find(name=None, attrs={}, recursive=True, text=None, **kwargs) bs4.BeautifulSoupインスタンスのメソッド 指定されたタグに一致するこのタグの最初の子のみを返します。
find
メソッドは引数name
で指定されたタグ名を検索し、最初に見つけた要素を返します。
たとえば↓のようなHTMLがあった場合、
<p>にっちも</p> <p>さっちも</p> <p>どっちも</p>
soup.find('p')
したときに取得できる要素は<p>にっちも</p>
になります。
これはsoup.find_all('p', limit=1)
やsoup.p
と等価です。
soup.find_all('p', limit=1) soup.p
find
メソッドは指定した要素が見つからなかった場合はNone
を返します。
el = soup.find('nothing') print(el) # None
attrsで属性を指定する
find
メソッドの引数attrs
に属性を指定することが出来ます。
attrs
は辞書で指定します。この辞書の値には文字列、文字列のリスト、正規表現オブジェクト、
または文字列を引数に取りその文字列が「matches」のカスタム定義に一致するかを返す
呼び出し可能なオブジェクトを指定できます(つまりただのラムダ式です)。
たとえばクラス名を指定して検索したい場合は↓のようにします。
soup.find('p', attrs={ 'class': 'cat' })
クラス名についてはclass_
というショートカットが利用できます。
soup.find('p', class_='cat')
IDについても同様です。
soup.find('p', attrs={ 'id': 'bird' }) soup.find('p', id='bird')
文字列のリストを指定した場合はOR
検索を行います。
たとえばcat
またはdog
のクラス名を持つ要素にヒットさせたい場合は↓のようにします。
soup.find('p', attrs={ 'class': ['cat', 'dog'] }) # OR検索
正規表現を指定するにはre
モジュールを使います。
import re soup.find('p', attrs={ 'class': re.compile('c.*') }) # 正規表現
リスト内にも正規表現を指定できます。
import re soup.find('p', attrs={ 'class': [re.compile('c.*'), re.compile('d.*')] }) # リストと正規表現のOR検索
関数オブジェクトを指定すると内部でマッチされるたびにその関数オブジェクトが呼び出されます。
例えば↓のコードでは、
from bs4 import BeautifulSoup import re html = ''' <p class="cat dog">猫と犬</p> <p class="cat bird">猫と鳥</p> ''' soup = BeautifulSoup(html, 'html.parser') soup.find('p', attrs={ 'class': lambda val: print(f'val[{val}]') }) # OR検索
↓のような結果になります。
val[cat] val[dog] val[cat dog] val[cat] val[bird] val[cat bird]
関数オブジェクトがマッチのたびに呼び出されているのがわかります。
この関数オブジェクトがTrue
を返すと検索にヒットします。
例えば↓のようにです。
soup.find('p', attrs={ 'class': lambda val: val in ['cat', 'dog'] })
再帰を無効にする
↓のようなHTMLから、
<div> <p>ライ麦畑で捕まえて</p> </div>
p
タグを取りたいとします。
その場合↓のようにすれば取れますが、
soup.find('p') # <p>ライ麦畑で捕まえて</p>
recursive=False
を指定すると再帰的な検索が無効になります。
soup.find('p', recursive=False) # None
タグの内容を指定する
find
メソッドの引数text
にタグの内容を指定することが出来ます。
たとえばThe cat
という内容を持つタグp
を取得したい場合は↓のようにします。
soup.find('p', text='The cat')
また、re
モジュールを使って正規表現を指定することも出来ます。
import re soup.find('p', text=re.compile('The .*'))
find_allの使い方
find_all
は複数のタグを取得したい時に使います。
from bs4 import BeautifulSoup html = ''' <h1>海賊王に俺はなる!</h1> <p>俺は世界一の海賊になるんだ!</p> <p>たくさんの仲間! 女! 酒!</p> ''' soup = BeautifulSoup(html, 'html.parser') els = soup.find_all('p') print(els)
↑のコードを実行すると↓のような結果になります。
[<p>俺は世界一の海賊になるんだ!</p>, <p>たくさんの仲間! 女! 酒!</p>]
find_all
の公式ドキュメントとヘルプを見てみます。
bs4.elementモジュールのfind_allメソッドのヘルプ: find_all(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs) bs4.BeautifulSoupインスタンスのメソッド 指定された基準に一致するTagオブジェクトのリストを抽出します。 タグの名前と、タグに付ける属性を指定できます。 引数の辞書attrsの値には文字列、文字列のリスト、正規表現オブジェクト、 または文字列を引数に取りその文字列が「matches」のカスタム定義に一致するかを返す 呼び出し可能なオブジェクトを指定できます。
引数はほとんどfind
と一緒です。
find_all
メソッドは指定した要素が見つからなかった場合に空のリストを返します。
soup.find_all('nothing') # []
要素の最大取得数を指定する
find_all
メソッドの引数limit
に要素の最大取得数を指定することが出来ます。
from bs4 import BeautifulSoup html = ''' <p>海賊王に俺はなる!</p> <p>俺は世界一の海賊になるんだ!</p> <p>たくさんの仲間! 女! 酒!</p> ''' soup = BeautifulSoup(html, 'html.parser') els = soup.find_all('p', limit=1) print(els) # [<p>海賊王に俺はなる!</p>] els = soup.find_all('p', limit=2) print(els) # [<p>海賊王に俺はなる!</p>, <p>俺は世界一の海賊になるんだ!</p>] els = soup.find_all('p', limit=3) print(els) # [<p>海賊王に俺はなる!</p>, <p>俺は世界一の海賊になるんだ!</p>, <p>たくさんの仲間! 女! 酒!</p>]
おわりに
find
とfind_all
が使えればほとんど用は足りそうです。
それぐらいポピュラーなメソッドといえます。
美しいスープを飲んで満腹になりましょう
関連記事
- BeautifulSoupの美しさを知りませんでした。実際に使ってみるまでは - narupoのブログ
- Python3 + Selenium + BeautifulSoup4: Chromeドライバを利用した実装例 - narupoのブログ
- 【Python】BeautifulSoupでclassを指定して要素を取得する方法【スクレイピング】 - narupoのブログ
- 【Python】BeautifulSoupのfindとfind_allの使い方【スクレイピング】 - narupoのブログ
- 【Python】BeautifulSoupのselectの普通の使い方【スクレイピング】 - narupoのブログ
- 【Python】BeautifulSoupでhrefの値を取得する【スクレイピング】 - narupoのブログ
姉妹ブログを見に行く。