CSSセレクターとは、HTMLやXMLの要素を選択するためのパターンマッチングのことです。BeautifulSoup4ではCSSセレクターを使って、目的の要素を簡単に取得することができます。
基本的な使い方
CSSセレクターを使うには、select
メソッドを使います。次の例では、classがtitle
のh1
タグを取得する方法を示します。
from bs4 import BeautifulSoup
html = '<html><body><h1 class="title">Hello, World!</h1></body></html>'
soup = BeautifulSoup(html, 'html.parser')
title = soup.select('h1.title')
print(title) # [<h1 class="title">Hello, World!</h1>]
CSSセレクターの文字列は、HTML要素を選択するためのパターンを記述することができます。上の例では、h1.title
というパターンを使って、h1
タグの中でclass属性がtitle
である要素を選択しています。
IDセレクターの使い方
IDセレクターを使うには、#
を使ってID名を指定します。次の例では、IDがheader
の要素を取得する方法を示します。
from bs4 import BeautifulSoup
html = '<html><body><div id="header"><h1>Hello, World!</h1></div></body></html>'
soup = BeautifulSoup(html, 'html.parser')
header = soup.select('#header')
print(header) # [<div id="header"><h1>Hello, World!</h1></div>]
クラスセレクターの使い方
クラスセレクターを使うには、.
を使ってクラス名を指定します。次の例では、classがsection
の要素を取得する方法を示します。
from bs4 import BeautifulSoup
html = '<html><body><div class="section"><h1>Hello, World!</h1></div></body></html>'
soup = BeautifulSoup(html, 'html.parser')
section = soup.select('.section')
print(section) # [<div class="section"><h1>Hello, World!</h1></div>]
子要素セレクターの使い方
子要素セレクターを使うには、>
を使って親要素と子要素を区切ります。次の例では、div
タグの直下にあるh1
タグを取得する方法を示します。
from bs4 import BeautifulSoup
html = '<html><body><div><h1>Hello, World!</h1></div></body></html>'
soup = BeautifulSoup(html, 'html.parser')
h1 = soup.select('div > h1')
print(h1) # [<h1>Hello, World!</h1>]
複数の条件を指定する方法
CSSセレクターを使って、複数の条件を指定することもできます。次の例では、classがtitle
であるh1
タグの中で、a
タグを持っている要素を取得する方法を示します。
from bs4 import BeautifulSoup
html = '<html><body><h1 class="title"><a href="#">Hello, World!</a></h1></body></html>'
soup = BeautifulSoup(html, 'html.parser')
title = soup.select('h1.title a')
print(title) # [<a href="#">Hello, World!</a>]
属性を指定する方法
CSSセレクターを使って、属性を指定することもできます。次の例では、data-name
属性がauthor
であるdiv
タグを取得する方法を示します。
from bs4 import BeautifulSoup
html = '<html><body><div data-name="author">John Doe</div></body></html>'
soup = BeautifulSoup(html, 'html.parser')
author = soup.select('div[data-name="author"]')
print(author) # [<div data-name="author">John Doe</div>]
findall/find と CSSセレクター の使い分けについては下記ページにまとめました。よかったら見てください。
部分検索を行う
上記まではタグ・ID・クラス名・属性を完全一致で指定していました。実際に使う場面では、クラス名の末尾が連番になっていたりするため、完全一致ではなく、部分一致で取得したい場面が多々出てきます。そのような場合には以下の3つのいずれかを利用することで、取得できます。
前方一致(^=)
from bs4 import BeautifulSoup
html_doc = """
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<div id="content">
<p class="paragraph">This is a sample paragraph.</p>
<p class="paragraph">This is another sample paragraph.</p>
<p class="paragraph-2">This is a third sample paragraph.</p>
</div>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
paragraphs = soup.select('p[class^="paragraph"]')
for p in paragraphs:
print(p.text)
上記の例では、CSSセレクタの「^=」演算子を使用して、class属性が「paragraph」で始まるすべての「p」要素を選択しています。このセレクタは、最初の文字が「paragraph」である「paragraph」と「paragraph-2」の2つの要素を選択しますが、出力結果は次のようになります。
This is a sample paragraph.
This is another sample paragraph.
後方一致($=)
from bs4 import BeautifulSoup
html_doc = """
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<div id="content">
<p class="paragraph">This is a sample paragraph.</p>
<p class="paragraph">This is another sample paragraph.</p>
<p class="paragraph-2">This is a third sample paragraph.</p>
</div>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
paragraphs = soup.select('p[class$="paragraph"]')
for p in paragraphs:
print(p.text)
上記の例では、CSSセレクタの「$=」演算子を使用して、class属性が「paragraph」で終わるすべての「p」要素を選択しています。このセレクタは、最後の文字が「paragraph」である「paragraph」と「paragraph-2」の2つの要素を選択しますが、出力結果は次のようになります。
This is a sample paragraph.
This is another sample paragraph.
部分一致(*=)
from bs4 import BeautifulSoup
html_doc = """
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<div id="content">
<p class="paragraph">This is a sample paragraph.</p>
<p class="paragraph">This is another sample paragraph.</p>
<p class="paragraph-2">This is a third sample paragraph.</p>
<p class="info-paragraph">This is an informative paragraph.</p>
</div>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
paragraphs = soup.select('p[class*="paragraph"]')
for p in paragraphs:
print(p.text)
上記の例では、CSSセレクタの「*=」演算子を使用して、class属性に「paragraph」という文字列を含むすべての「p」要素を選択しています。このセレクタは、「paragraph」を含む4つの要素を選択しますが、出力結果は次のようになります。
This is a sample paragraph.
This is another sample paragraph.
This is a third sample paragraph.
以上のように、PythonのCSSセレクタを使用することで、前方一致、後方一致、部分一致などの検索が容易になります。
まとめ
CSSセレクターを使うことで、HTMLやXMLの要素を簡単に選択することができます。BeautifulSoup4のselect
メソッドを使って、目的の要素を簡単に取得することができます。IDセレクター、クラスセレクター、子要素セレクターなど、さまざまなパターンを組み合わせることで、より複雑な選択が可能です。属性を指定することもできます。