BeautifulSoup4のselect()メソッドの使い方について

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

今回は、BeautifulSoup4のタグ検索用メソッドの一つ「.select()」と「.select_one()」の使い方について説明したいと思います

構成

以下のコードを前提に説明しています

from bs4 import BeautifulSoup
html = """<html><head><title>せなブログ</title></head>
<div 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>
</div>
</html>
"""
soup = BeautifulSoup(html, 'html.parser')

select()メソッドについて

まず初めに、select()とよく似ているfind_all()との違いについて説明しておきます

find_all()の引数は「find_all(‘要素名’, ‘属性’, ‘キーワード引数’)」となるのに対して
select()の引数は「select(‘CSSセレクタ’, ‘キーワード引数’)」となります

例えば以下のコードはどちらも同じ結果を返します

print(soup.find_all('a', href=True))
print(soup.select('a[href]'))

このように、find_all()select()では引数への設定する方法が違うことがわかるかと思います

まとめると

全ての要素一つの要素引数
find_all()find() 要素名・属性・キーワード引数
select()select_one()CSSセレクタ・キーワード引数

基本的にはselect()を使う方がきれいに書ける気がするので、select()を個人的におすすめします
結局のところ臨機応変に使えば良いと思いますが…

select()とselect_one()メソッドの使い方

select()メソッドではfind_all()などとは指定する時の方法なども異なります

以下にselect()を使った処理方法の一部を記述します

# idを指定
print(soup.select('#tag2'))
# [<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>]
# classを指定
print(soup.select('.item'))
# [<div 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>
# </div>]
# 指定タグの直後を検索
print(soup.select('html > head > title'))
# [<title>せなブログ</title>]
# (自分以外)全ての兄弟要素を検索
print(soup.select('#tag1 ~ .category'))
# [<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>]
# 次の兄弟要素を検索
print(soup.select('#tag1 + .category'))
# [<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>]
# 属性の有無
print(soup.select('a[href]'))
# [<a class="category" href="https://senablog.com/category/programming/python/" id="tag2">Python</a>]
# 完全一致
print(soup.select('a[href="https://senablog.com/category/programming/"]'))
# [<a class="category" href="https://senablog.com/category/programming/" id="tag1">プログラミング</a>]
# 部分一致
print(soup.select('a[href*="gory/pro"]'))
# [<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>]
# 前方一致
print(soup.select('a[href$="zakki/"]'))
# [<a class="category" href="https://senablog.com/category/zakki/" id="tag3">雑記</a>]
# 後方一致
print(soup.select('a[href^="https://senablog.com/category/programming/"]'))
# [<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>]

上記の記述方法はselect_one()でも同じです