0Pricing
AI Agents · レッスン

BeautifulSoupによるHTML解析

find()、select()、CSSセレクターを使い、HTMLから構造化されたコンテンツを抽出します。

「BeautifulSoupによるHTML解析」はCoddyKit上の無料AI Agentsレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Agents学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Agentsコースには全4レッスンが含まれています。

エージェントでHTMLを解析する理由

多くのデータソースはAPIではなく、Webページとして提供されています。エージェントがHTMLから構造化された情報を抽出する必要がある場合、生のマークアップをたどって操作できるツリーに解析しなければなりません。

BeautifulSoup(bs4)は、この用途で標準的に使われるPythonライブラリです。扱いにくいHTMLを、簡単にクエリできるPythonオブジェクトに変換します。

BeautifulSoupオブジェクトを作成する

生のHTMLとパーサー名をBeautifulSoup()に渡します。'html.parser'はPythonに組み込まれているため、追加インストールは不要です。大きなページをより高速に解析するには、pipで'lxml'を利用できます。

from bs4 import BeautifulSoup
import httpx

# Fetch HTML
response = httpx.get('https://example.com', timeout=10.0)
html = response.text

# Parse it
soup = BeautifulSoup(html, 'html.parser')

# Get the page title
print(soup.title.text)  # 'Example Domain'

find() — 単一の要素を検索する

soup.find(tag, attrs)は、最初に一致した要素を返します。一致するものがない場合はNoneを返します。タグ名、クラス、id、その他の属性で一致させることができます。

結果に対してメソッドを呼び出す前に、必ずNoneかどうかを確認してください。

from bs4 import BeautifulSoup

html = '<div class="content"><h1>Title</h1><p>Body text here.</p></div>'
soup = BeautifulSoup(html, 'html.parser')

# Find by tag + class
content_div = soup.find('div', class_='content')
if content_div:
    heading = content_div.find('h1')
    print(heading.text)  # 'Title'

# Find by id
sidebar = soup.find('div', id='sidebar')  # None if absent

find_all() — 複数の要素を検索する

soup.find_all(tag)は、一致するすべての要素のリストを返します。リスト項目、テーブル行、記事カードなど、繰り返し現れる構造からデータを抽出するために、リストを反復処理します。

from bs4 import BeautifulSoup

html = '<ul><li>Apple</li><li>Banana</li><li>Cherry</li></ul>'
soup = BeautifulSoup(html, 'html.parser')

items = soup.find_all('li')
for item in items:
    print(item.text)  # Apple, Banana, Cherry

# Limit results
first_two = soup.find_all('li', limit=2)

select()によるCSSセレクター

soup.select('css selector')を使うと、なじみのあるCSS構文を利用できます。特に入れ子になった要素を扱う場合、find()を連鎖して呼び出すより簡潔に記述できることがよくあります。

from bs4 import BeautifulSoup

html = '''
<table>
  <tr><td class="name">Alice</td><td class="score">95</td></tr>
  <tr><td class="name">Bob</td><td class="score">87</td></tr>
</table>
'''
soup = BeautifulSoup(html, 'html.parser')

# Select all td elements inside tr inside table
cells = soup.select('table tr td')
for cell in cells:
    print(cell.text)

# Select only name cells
names = soup.select('td.name')
for n in names:
    print(n.text)  # Alice, Bob

.textと.strip()でテキストを抽出する

.text(または.get_text())は、入れ子になったタグを含め、要素内のすべてのテキストコンテンツを返します。HTMLには先頭や末尾の空白が含まれることが多いため、.strip()を使って取り除きます。

from bs4 import BeautifulSoup

html = '<p>  \n  Price: <strong>$29.99</strong>  \n  </p>'
soup = BeautifulSoup(html, 'html.parser')

paragraph = soup.find('p')

# .text includes nested tag content
print(paragraph.text)          # '  \n  Price: $29.99  \n  '
print(paragraph.text.strip())  # 'Price: $29.99'

# get_text with separator
print(paragraph.get_text(separator=' ', strip=True))  # 'Price: $29.99'

.get()で属性を抽出する

href、src、data-*などのタグ属性は、.get('attr_name')を使って辞書と同じように取得できます。属性が存在しない場合も、安全にNoneを返します。

from bs4 import BeautifulSoup

html = '''
<a href="https://example.com/page" data-id="42">Click here</a>
<img src="/images/logo.png" alt="Logo">
'''
soup = BeautifulSoup(html, 'html.parser')

link = soup.find('a')
print(link.get('href'))     # 'https://example.com/page'
print(link.get('data-id'))  # '42'
print(link.get('class'))    # None (no class attribute)

img = soup.find('img')
print(img.get('src'))       # '/images/logo.png'

解析ツリーをたどる

BeautifulSoupの要素には、たどって移動できる親、子、兄弟の関係があります。.parent、.children、.next_sibling、.previous_siblingを使って、見つかった要素の周辺を移動します。

from bs4 import BeautifulSoup

html = '''
<div class="article">
  <h2>Headline</h2>
  <p>First paragraph.</p>
  <p>Second paragraph.</p>
</div>
'''
soup = BeautifulSoup(html, 'html.parser')

h2 = soup.find('h2')
print(h2.text)                    # 'Headline'
print(h2.parent['class'])         # ['article']
print(h2.next_sibling.next_sibling.text)  # 'First paragraph.'

ページからすべてのリンクを抽出する

エージェントでよく行う処理の1つに、後続のクロールに使うためにページ上のすべてのリンクを収集することがあります。すべての<a>タグを見つけてhref属性を抽出し、空のものを除外します。

from bs4 import BeautifulSoup
import httpx

def extract_links(url: str) -> list:
    response = httpx.get(url, timeout=10.0)
    soup = BeautifulSoup(response.text, 'html.parser')

    links = []
    for tag in soup.find_all('a'):
        href = tag.get('href')
        if href and href.startswith('http'):
            links.append(href)
    return links

# urls = extract_links('https://news.ycombinator.com')
# print(urls[:5])

不正なHTMLを適切に処理する

実際のWeb上のHTMLは、閉じられていないタグ、対応していない要素、エンコーディングの問題などによって壊れていることがよくあります。BeautifulSoupのパーサーは寛容で、エラーを自動的に修正しようとします。ただし、入れ子になった要素にアクセスするときは、必ずNoneに備えてください。

from bs4 import BeautifulSoup

# Broken HTML — missing closing tags
html = '<div><p>Hello <strong>World</div>'
soup = BeautifulSoup(html, 'html.parser')

# BS4 repairs the tree automatically
print(soup.prettify())
# <div><p>Hello <strong>World</strong></p></div>

# Safe chained access
price = soup.find('span', class_='price')
price_text = price.text.strip() if price else 'N/A'
print(price_text)  # 'N/A'

完全なエージェント用スクレイパーツール

ここまでの内容を組み合わせて、エージェントがツールとして呼び出せる完全なスクレイパー関数を作成します。ページを取得して解析し、エージェントが推論できる形式の構造化データを返します。

from bs4 import BeautifulSoup
import httpx

def scrape_article(url: str) -> dict:
    response = httpx.get(url, headers={'User-Agent': 'MyAgent/1.0'}, timeout=10.0)
    response.raise_for_status()
    soup = BeautifulSoup(response.text, 'html.parser')

    title = soup.find('h1')
    paragraphs = soup.find_all('p')

    return {
        'url': url,
        'title': title.text.strip() if title else '',
        'text': ' '.join(p.text.strip() for p in paragraphs[:5]),
        'links': [a.get('href') for a in soup.find_all('a', href=True)][:10]
    }

理解度チェック:BeautifulSoup

BeautifulSoupによるHTML解析についての理解度を確認しましょう。

振り返り:BeautifulSoupでHTMLを解析する

これで、エージェント内のHTMLページから構造化データを抽出できるようになりました。

  • BeautifulSoup(html, 'html.parser')でsoupオブジェクトを作成する
  • 単一の要素にはfind()を、複数の要素にはfind_all()を使用する
  • CSSセレクターによる検索にはselect()を使用する
  • .text.strip()でテキストを取得し、.get('attr')で属性を取得する
  • .parent、.children、兄弟要素を使ってツリーをたどる

HTTPクライアントと組み合わせることで、BeautifulSoupによってエージェントはあらゆるWebページを読み取れるようになります。

よくある質問

「BeautifulSoupによるHTML解析」レッスンは無料ですか?

はい。「BeautifulSoupによるHTML解析」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Agentsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Agentsコースには全4レッスンが含まれています。

「BeautifulSoupによるHTML解析」で何を学びますか?

find()、select()、CSSセレクターを使い、HTMLから構造化されたコンテンツを抽出します。 ブラウザで直接実行するハンズオンコードでAI Agentsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

AI Agentsを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAI Agentsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「BeautifulSoupによるHTML解析」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAI Agentsレッスンでコードを書いて実行できますか?

はい。すべてのAI Agentsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. エージェント向けHTTPクライアント:httpxとrequests
  2. BeautifulSoupによるHTML解析
  3. ページネーションと動的コンテンツの処理
  4. 適切なスクレイピングの実践
← AI Agentsに戻る