概要
Beautiful Soup で条件を指定して要素を検索する方法を解説します。
関連記事
[blogcard url=”https://pystyle.info/scraping-beautiful-soup-how-to-edit-dom-tree”]
[blogcard url=”https://pystyle.info/scraping-beautiful-soup-how-to-refer-elements”]
機能一覧
引数で検索条件を指定する find
系のメソッドと CSS セレクタで検索条件を指定する select
系のメソッドがあります。
find(), find_parent(), find_next_sibling(), find_previous_sibling(), select_one()
は条件に該当する最初に見つかった要素を返します。find_all(), find_parents(), find_next_siblings(), find_previous_siblings(), select()
は条件に該当するすべての要素を一覧で返すようになっています。find
系のメソッドは検索範囲によって使い分けます。
検索範囲 | 返り値 | |
---|---|---|
find() |
子孫要素 | 条件に該当する最初に見つかった要素 |
find_all() |
子孫要素 | 条件に該当するすべての要素 |
find_parent() |
先祖要素 | 条件に該当する最初に見つかった要素 |
find_parents() |
先祖要素 | 条件に該当するすべての要素 |
find_next_sibling() |
この要素より前のすべての兄弟要素 | 条件に該当する最初に見つかった要素 |
find_next_siblings() |
この要素より前のすべての兄弟要素 | 条件に該当するすべての要素 |
find_previous_sibling() |
この要素より後のすべての兄弟要素 | 条件に該当する最初に見つかった要素 |
find_previous_siblings() |
この要素より後のすべての兄弟要素 | 条件に該当するすべての要素 |
select_one() |
子孫要素 | 条件に該当する最初に見つかった要素 |
select() |
子孫要素 | 条件に該当するすべての要素 |
サンプルの HTML
以下の HTML をサンプルとして使用します。
Beautiful Soup では、HTML テキストを解析し、以下のような DOM ツリーで表現します。要素の検索、追加はこの階層構造を元に行いますので、解析する HTML の階層構造がどうなっているかをまず理解するようにしましょう。
root (BeautifulSoup) └── html (Tag) ├── head (Tag) │ └── title (Tag) │ └── 'ニュース' (NavigableString) └── body (Tag) ├── h1 (Tag) │ └── 'ニュース' (NavigableString) ├── div (Tag) │ ├── h2 (Tag) │ │ └── 'トピック一覧' (NavigableString) │ └── ul (Tag) │ ├── li (Tag) │ │ └── 'トピック1' (NavigableString) │ └── li (Tag) │ └── 'トピック2' (NavigableString) ├── div (Tag) │ ├── h2 (Tag) │ │ └── '注目の画像' (NavigableString) │ └── ul (Tag) │ ├── li (Tag) │ │ └── img (Tag) │ └── li (Tag) │ └── img (Tag) └── p (Tag) ├── 'お気に入りに' (NavigableString) ├── a (Tag) │ └── 'このサイト' (NavigableString) └── 'を登録してください。' (NavigableString)
find 系の関数
find
系の関数は、検索範囲が異なるだけで、引数の指定方法は共通です。
find() と find_all()
Tag.find_all()
は、子孫要素を検索し、条件に該当するすべての要素を bs4.element.ResultSet
オブジェクトで返します。これはリストと同様で iterate やスライスが行えます。

[<li>トピック1</li>, <li>トピック2</li>, <li><img alt="画像1" src="sample1.jpg"/></li>, <li><img alt="画像2" src="sample2.jpg"/></li>] <li>トピック1</li> [<li>トピック2</li>, <li><img alt="画像1" src="sample1.jpg"/></li>, <li><img alt="画像2" src="sample2.jpg"/></li>]
条件に該当する要素が1つしかない場合でも返り値は bs4.element.ResultSet
オブジェクトになります。
[<p>お気に入りに<a href="sample.com">このサイト</a>を登録してください。</p>]
一方、Tag.find()
は Tag.find_all()
と異なり、条件に該当する最初に見つかった要素を返します。

<li>トピック1</li>
4つの指定方法
find 系のメソッドは条件の指定方法として、次の4つがあります。
- 名前で検索:
name
引数で指定 - 属性で検索:
attrs
引数または属性=値
で指定 - 値で検索:
string
で指定
各引数では、次の指定方法があります。
- True
- 値
- 値のリスト
- 正規表現 (
re.Pattern
オブジェクト) - bool 関数
指定した名前の要素を検索する
検索する要素名を name
引数で指定します。要素名はリストで複数指定できます。
[<p>お気に入りに<a href="sample.com">このサイト</a>を登録してください。</p>] [<img alt="画像1" src="sample1.jpg"/>, <img alt="画像2" src="sample2.jpg"/>, <p>お気に入りに<a href="sample.com">このサイト</a>を登録してください。</p>]
要素名の指定には、正規表現が利用できます。
html head h1 h2 h2
True
を指定することで、すべての要素を取得できます。
html head title body h1 div h2 ul li li div h2 ul li img li img p a
要素を受け取り、bool 値を返す関数を指定すると、関数が True
を返す要素を検索します。
html head body
指定した属性を持つ要素を検索する
引数に 属性名=値
を指定することで、その属性値を持つ要素を検索します。
ただし、属性 class
を指定する場合、class
は Python の予約語なので、代わりに class_
を使用します。
ul ul
複雑の属性を指定できます。
ul
正規表現を使用できます。
ul ul
属性値を True
にすることで、その属性を持つ要素を検索します。
div ul div ul
属性値を受け取り、bool 値を返す関数を指定すると、関数が True
を返す要素を検索します。
[<ul class="list" id="menu"><li>トピック1</li><li>トピック2</li></ul>, <ul class="list"><li><img alt="画像1" src="sample1.jpg"/></li><li><img alt="画像2" src="sample2.jpg"/></li></ul>]
attrs
引数でも属性の条件を指定できます。
[<ul class="list" id="menu"><li>トピック1</li><li>トピック2</li></ul>]
指定した値を持つ要素を検索する
string
引数のみ指定した場合は、指定した値をもつ NavigableString
オブジェクトを返します。
name
引数で要素名も指定した場合、指定した値を Tag.string
に持つ要素を返します。値はリストで複数指定できます。
['トピック1'] [<li>トピック1</li>] [<li>トピック1</li>, <li>トピック2</li>]
正規表現も使用できます。
['トピック一覧', 'トピック1', 'トピック2']
値を受け取り、bool 値を返す関数を指定すると、関数が True
を返す要素を検索します。
[<li>トピック1</li>, <li>トピック2</li>]
返り値の要素数の上限を指定する
limit
引数で上限を設定できます。
[<li>トピック1</li>, <li>トピック2</li>, <li><img alt="画像1" src="sample1.jpg"/></li>]
再帰的に検索する深さを指定する
デフォルトでは、find_all()
を呼び出した要素の子孫要素がすべて検索となりますが、recursive=False
を指定した場合は、その子要素のみを検索対象とします。
[<h1>ニュース</h1>] []
Tag オブジェクトの呼び出しメソッド
bs4.BeautifulSoup
オブジェクトまたは bs4.element.Tag
オブジェクトの呼び出しメソッドは、find_all()
と同じ意味になります。
[<h1>ニュース</h1>] [<h1>ニュース</h1>] [<h1>ニュース</h1>]
select
系のメソッド
select()
及び select_one()
は、検索条件を CSS セレクタで指定します。CSS セレクタを使用することで、「div
タグの子要素の h1
タグ」「div
タグの2番目の子要素」といった find
系のメソッドでは複数行のコードが必要となる検索処理を1つの関数呼び出しで実現できます。
CSS セレクタの指定方法は沢山あるので、「CSS セレクタ」で検索してでてくる情報を参照してください。
コメント