本文へスキップ
BecomeCoder

Pythonスクレイピングコース · 第3章 CSSセレクタと構造をたどる · レッスン10

構造をたどる ― 親・子・要素内検索

ブラウザで完結

導入

セレクタで大きなブロックを取ってから、その中でさらに探す、という段階的な取り方が実務では効きます。「商品カードを取る → 各カードの中で名前と価格を取る」のような流れです。

説明

find / select は、soup 全体だけでなく、取り出した要素に対しても呼べます。

from bs4 import BeautifulSoup

html = """
<div class="product">
  <span class="name">りんご</span>
  <span class="price">120</span>
</div>
<div class="product">
  <span class="name">みかん</span>
  <span class="price">80</span>
</div>
"""

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

# まず商品カードごとに取り、そのカードの中で名前と価格を取る
for card in soup.select(".product"):
    name = card.find("span", class_="name").text
    price = card.find("span", class_="price").text
    print(f"{name}: {price}円")
  • 外側のループ.product を1つずつ取り出し、その card の中だけで card.find(...) を呼ぶのがポイント。
  • こうすると「1件ぶんの名前と価格」が正しく対応します。全体に対して find_all("name")find_all("price") を別々に取ると、対応がずれやすいので、この「カード単位でループ」が安全です。

実行結果:

りんご: 120円
みかん: 80円

やってみよう

3つ目の商品 <div class="product"><span class="name">ぶどう</span><span class="price">300</span></div> を足すと、ループがそのまま3件ぶん回ります。「まとまり(カード)でループ → 中を取る」は、この後の抽出でずっと使う型です。

演習

上の HTML で、各商品の名前だけを「商品: りんご」の形で1行ずつ print してください。

ヒント1を見る

for card in soup.select(".product"): print("商品:", card.find("span", class_="name").text)

実際に動かしてみよう

下のエディタにPythonを書いて「実行」を押すと、本物の BeautifulSoup(Pyodide)でHTMLの解析をその場で試せます。初回だけ読み込みに少し時間がかかります。本文のHTMLを書き換えたり、抜き出すタグを変えたりして、結果の変化を確かめましょう(ネットからの取得は第5章の読み物で解説します)。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。