BeautifulSoup4で検索を行うときに使うメソッドについて

2019年12月13日

みなさまおはこんばんにちは、せなです

今回はBeautifulSoup4でBeautifulSoupオブジェクトを検索するときに使う、メソッドを解説したいと思います

始めに

BeautifulSoup4における代表的な検索メソッドはfind_all()です
基本的にはfind_all()を使いつつ用途に応じてほかのメソッドを使用することになります(一つだけ取得したいときにfind()を使ったり)

ほかにも5つ(×2)のメソッドがありますので、そちらについても解説したいと思います

タグオブジェクトの使いかたなどを理解しておくとより簡単に理解できると思いますので、良ければ下の記事にも目を通して見て下さい

リンク:BeautifulSoup4のタグオブジェクトの使い方
リンク:BeautifulSoup4で親子要素間の移動と検索を行う方法

HTML構成

以下のコードを使用することを前提に説明します

from bs4 import BeautifulSoup

html = """<html><head><title>せなブログ</title></head>
<p id="site"><a href="https://senablog.com/">せなブログ</a></p>
<p class="desc">疑問に思ったことをサクッと解説!一日一記事22時更新です</p>
<p class="item">
<a href="https://senablog.com/category/programming/" class="category" id="tag1">プログラミング</a>
<a href="https://senablog.com/category/programming/python/" class="category" id="tag2">Python</a>
<a href="https://senablog.com/category/zakki/" class="category" id="tag3">雑記</a>
</p>"""

soup = BeautifulSoup(html, 'html.parser')

find_all()

find_all()メソッドは最も使用頻度の高いメソッドです
find_all()メソッドを使用することで、タグオブジェクトの子孫要素から一致した要素を全て取得できます

print(soup.find_all('a', limit=2))
print(soup.find_all('a', 'category', limit=2))
print(soup.find_all(id='tag1'))

----結果----
[<a href="https://senablog.com/">せなブログ</a>, <a class="category" href="https://senablog.com/category/programming/" id="tag1">プログラミング</a>]

[<a class="category" href="https://senablog.com/category/programming/" id="tag1">プログラミング</a>, <a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>]

[<a class="category" href="https://senablog.com/category/programming/" id="tag1">プログラミング</a>]

find_all()メソッドの引数については以下のリストをご覧ください

  • name:タグ名を対象にして検索
  • attrs:タグの値を対象にして検索(class_= とすることでCSSクラス名を検索)
  • recursive:デフォルトでTrue、Falseで直下の子要素のみ検索(find_all()とfind()のみ使用可)
  • text:タグに含まれるテキストを対象に検索
  • limit:必要な検索結果の数を指定

find()

find()メソッドは一つの結果のみを取得したいときに使用します

find_all()メソッドでも同じことができますが、全体を読み込むため時間がかかります
なので、一つの結果のみを取得したい場合にはfind()メソッドを使用するほうがよいです

print(soup.find('title'))

----結果----
<title>せなブログ</title>

find_all()メソッドとの違いは以下の点が上げられます

find_all()find()
読み込み全体を読み込む対象を発見するまで読み込む
要素あり返却リスト形式要素と同じ
要素なし返却空のリストNone

find()メソッドの引数は以下のようになります

  • name:タグ名を対象にして検索
  • attrs:タグの値を対象にして検索(class_= とすることでCSSクラス名を検索)
  • recursive:デフォルトでTrue、Falseで直下の子要素のみ検索(find_all()とfind()のみ使用可)
  • text:タグに含まれるテキストを対象に検索

find_parents() & find_parent()

find_parents()find_parent()find_all()などと違うの一つだけです

find_all()は子孫要素を取得しますが、find_parents()は親要素を取得します

parent_soup = soup.find(text='Python')
print(parent_soup.find_parents('a'))
print(parent_soup.find_parent('p'))

----結果----
[<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>]

<p class="item">
<a class="category" href="https://senablog.com/category/programming/" id="tag1">プログラミング</a>
<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>
<a class="category" href="https://senablog.com/category/zakki/" id="tag3">雑記</a>
</p>

find_parents()とfind_parent()メソッドは親要素を取得すると言いましたが、厳密には直接の親要素に当たります
以下をご覧ください

print(parent_soup.find_parents(id='site'))

----結果----
[]

実際「id='site'」は存在していますが、取得されていません
なぜなら直接の親要素ではなく親要素の兄弟に当たるからです

引数:find_parents(name=None, attrs={}, text=None, limit=None, **kwargs)
引数:find_parent(name=None, attrs={}, text=None, **kwargs)

find_previous_siblings() & find_previous_sibling()

find_previous_siblings()find_previous_sibling()メソッドは前にある兄弟要素を取得するために使用します

find_previous_siblings()は前方にある全ての兄弟要素を、
find_previous_sibling()は前方にある最初の兄弟要素を取得します

sibling_soup = soup.find(id='tag3')
print(sibling_soup.find_previous_siblings('a'))
print(sibling_soup.find_previous_sibling('a'))

----結果----
[<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>, <a class="category" href="https://senablog.com/category/programming/" id="tag1">プログラミング</a>]
<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>

引数: find_previous_siblings(name=None, attrs={}, text=None, limit=None, **kwargs)
引数: find_previous_sibling(name=None, attrs={}, text=None, **kwargs)

find_next_siblings() & find_next_sibling()

find_next_siblings()find_next_sibling()メソッドは後ろの兄弟要素を取得するために使用します

find_next_siblings()メソッドは後ろにある全ての兄弟要素を取得し、
find_next_sibling()メソッドは後ろにある最初の兄弟要素を取得します

sibling_soup = soup.find(id='tag1')
print(sibling_soup.find_next_siblings('a'))
print(sibling_soup.find_next_sibling('a'))

----結果----
[<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>, <a class="category" href="https://senablog.com/category/zakki/" id="tag3">雑記</a>]

<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>

引数: find_next_siblings(name=none, attrs={}, text=None, limit=None, **kwargs)
引数: find_next_sibling(name=None, attrs={}, text=None, **kwargs)

find_all_previous() & find_previous()

find_all_previous()find_previous()は前方のタグ、文字列要素を取得するために使用します

find_all_previous()メソッドは前にある対象の要素をすべて取得します
find_previous()メソッドは前にある最初の対象要素を取得します

element_soup = soup.find(id='tag1')
print(element_soup.find_all_previous(text=True))
print(element_soup.find_previous('title'))

----結果----
['\n', '\n', '疑問に思ったことをサクッと解説!一日一記事22時更新です', '\n', 'せなブログ', '\n', 'せなブログ']
<title>せなブログ</title>

引数: find_all_previous(name=none, attrs={}, text=None, limit=None, **kwargs)
引数: find_previous(name=None, attrs={}, text=None, **kwargs)

find_all_next() & find_next()

find_all_next()find_next()メソッドは後方にあるタグ、文字列要素を取得するために使用します

find_all_next()メソッドは後ろにある対象の要素をすべて取得します
find_next()メソッドは後ろにある最初のの対象要素を取得します

element_soup = soup.find(id='site')
print(element_soup.find_all_next(text=True))
print(element_soup.find_next('p', 'desc'))

----結果----
['せなブログ', '\n', '疑問に思ったことをサクッと解説!一日一記事22時更新です', '\n', '\n', 'プログラミング', '\n', 'Python', '\n', '雑記', '\n']
<p class="desc">疑問に思ったことをサクッと解説!一日一記事22時更新です</p>

引数: find_all_next(name=none, attrs={}, text=None, limit=None, **kwargs)
引数: find_next(name=none, attrs={}, text=None, **kwargs)