CodeGym /コース /Python SELF JA /複雑なHTML構造からデータを抽出する

複雑なHTML構造からデータを抽出する

Python SELF JA
レベル 34 , レッスン 0
使用可能

1. 複雑なHTML構造の基本操作

複雑なHTML構造を検討する前に、まずHTMLがなぜそんなに入り組んで見えるのかを理解することが重要だよ。 Web開発者はコンテンツを整理するために複雑なネストされた要素をよく使うんだ。それが原因で、こうしたページからデータを抽出しようとする人にとっては大変なことになることもある。でも心配しなくていいよ—いい計画とツールがあれば簡単に解決できるから!

HTMLツリーの構造を理解する

HTMLドキュメントをツリーとして想像してみて。各要素はノードとして表され、テキストや他のノードを含むことがあるんだ。このツリーの頂点にはhtmlがあり、その次にheadbodyが続く。そしてさらにその下にはいろんな子要素が配置されるんだ。ネストされた要素はこのツリーの深い部分に存在する。

シンプルなHTML構造の例:

HTML

<html>
  <head>
    <title>例</title>
  </head>
  <body>
    <div class="content">
      <h1>見出し</h1>
      <p>パラグラフ1</p>
      <p>パラグラフ2</p>
      <div class="nested">
        <ul>
          <li>要素1</li>
          <li>要素2</li>
          <li><span>要素3</span></li>
        </ul>
      </div>
    </div>
  </body>
</html>

この例からわかるように、nestedクラスを持つdivがあって、それがulを含んでいる。そして、その中にliが並んでいるんだ。これが要素がネストされる典型的な例だね。

2. BeautifulSoupを使ったデータ抽出

ネストされた要素からのデータ抽出

BeautifulSoupがどう動くのかを思い出してみよう。リストliのテキストを取り出してみようか。 本物の探偵になった気持ちで、ネストされた構造からデータを集めよう!

Python

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, 'html.parser')
nested_items = soup.select('.nested ul li')

for item in nested_items:
    print(item.get_text())

結果:


要素1
要素2
要素3

CSSセレクターを使ってselectメソッドを使い、nestedクラス内のすべてのliを見つけることができたね。 get_text()メソッドを使って、見つけた要素から直接テキストを抽出しているんだ。

3. 多層構造要素の操作

時にはデータが構造の深い部分だけでなく、異なるレベルに分散していることもあるんだ。これがデータ抽出をさらに複雑にする場合がある。 もっと複雑なHTMLツリーからデータを抽出する方法を見てみよう。

複雑な構造の例:

HTML

<html>
  <body>
    <div class="wrapper">
      <div class="header">
        <h1>これは見出しです</h1>
      </div>
      <div class="content">
        <div class="article">
          <h2>記事1</h2>
          <p>記事1の内容</p>
        </div>
        <div class="article">
          <h2>記事2</h2>
          <p>記事2の内容</p>
        </div>
      </div>
      <div class="footer">
        <p>連絡先情報</p>
      </div>
    </div>
  </body>
</html>

レベル毎のデータ抽出

それじゃ、すべての記事タイトルとその内容を抽出してみよう。

Python

articles = soup.select('.content .article')

for article in articles:
    title = article.find('h2').get_text()
    content = article.find('p').get_text()
    print(f'タイトル: {title}')
    print(f'内容: {content}\n')

期待される出力:


タイトル: 記事1
内容: 記事1の内容

タイトル: 記事2
内容: 記事2の内容

selectメソッドとfindメソッドを組み合わせて目的を達成している。selectは親要素を見つけるのに使い、findで子要素の情報を取り出しているよ。

4. ネストされた要素の操作の特徴

Webページを解析するとき、同じクラスやタグを持つ複数のネストされた要素があることに気付くかもしれない。こうした場合は、コンテクスト検索を利用したり、特定の要素を明確に識別することがエラーを回避する手助けになるよ。

複雑なネストの例:

HTML

<html>
  <body>
    <div class="container">
      <div class="item">
        <h2>番号1</h2>
        <div class="details">詳細1</div>
      </div>
      <div class="item">
        <h2>番号2</h2>
        <div class="details">詳細2</div>
        <div class="additional">
          <div class="info">追加情報</div>
        </div>
      </div>
    </div>
  </body>
</html>

ネストを考慮したデータ抽出

混乱を避けるためには、もっと具体的な要素を探す必要がある。

Python

items = soup.select('.container .item')

for item in items:
    number = item.find('h2').get_text()
    details = item.select_one('.details').get_text()
    additional_info = item.select_one('.additional .info')
    
    print(f'番号: {number}')
    print(f'詳細: {details}')
    
    if additional_info:
        print(f'追加情報: {additional_info.get_text()}')
    print()

ここではselect_oneメソッドを使って、最初に見つかった要素だけを返している。これにより、追加ブロック内のデータの重複を避けることができるんだ。

5. 実践的な側面と典型的な間違い

複雑なHTML構造の操作では簡単に混乱したり、エラーに遭遇することがあるんだよ。典型的なエラーの1つが、存在しない要素にアクセスしようとすることで発生するAttributeErrorだね。これを避けるためには、要素が存在するか確認してから操作するようにしよう。

もう1つ重要なことは、すぐにデータを抜き取ろうとするのではなく、まず構造を分析してデバッグの出力を使って中間結果を検証することだよ。

実際のプロジェクトでは、ネストされたHTML構造を操作するスキルが非常に重要になることがある。これはWebスクレイピングだけでなく、Webインターフェースのテスト、テストの自動化、フォーマットされたネストされたAPIレスポンスのデータ分析などにも応用できるんだ。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION