Python & BeautifulSoupでWebスクレイピングをレベルアップ
Ethan Miller
Product Engineer · Leapcell

包括的なHTML処理チュートリアル:解析からデータ抽出まで
I. はじめに
Webページの基礎となる言語として、HTML(Hypertext Markup Language)は、Webデータ処理やWeb開発などの分野で広く使用されています。開発者がWeb構造を最適化する場合でも、データアナリストがWebページから情報を抽出する場合でも、HTML処理は不可欠です。このチュートリアルでは、HTML解析、変更、データ抽出などのコア操作に焦点を当て、読者がHTMLを処理するための包括的な方法と技術を習得できるようにします。
II. HTMLの基本の復習
2.1 基本的なHTML構造
標準的なHTMLドキュメントは、<!DOCTYPE html>
宣言で始まり、2つの主要なセクション(<head>
と<body>
)をネストする<html>
ルート要素が含まれます。<head>
セクションには通常、ページに関するメタ情報(タイトル、文字エンコーディング、CSSスタイルシートへのリンクなど)が含まれます。<body>
セクションには、テキスト、画像、リンク、フォーム、その他の要素など、ページの表示コンテンツが含まれます。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>My Page</title> </head> <body> <h1>Hello, World!</h1> <p>This is a simple HTML page.</p> </body> </html>
2.2 HTML要素と属性
HTMLは、段落の<p>
やリンクの<a>
など、タグで表されるさまざまな要素で構成されています。要素には、追加情報を定義する属性を含めることができます。たとえば、<a href="https://example.com">
のhref
属性は、リンクのターゲットアドレスを指定します。属性は通常「名前と値」のペアであり、属性値は引用符で囲む必要があります。
III. HTML解析
3.1 解析ツールとライブラリ
さまざまな開発環境で、複数のツールとライブラリがHTMLを解析できます。
- ブラウザ:ブラウザには、HTMLコードを視覚的なページにレンダリングする強力なHTML解析エンジンが組み込まれています。ブラウザの開発者ツール(Chrome DevToolsなど)を使用すると、解析されたDOM(Document Object Model)構造を表示し、要素のスタイルや属性を分析できます。
- Pythonライブラリ:
- BeautifulSoup:Pythonで最も一般的に使用されるHTML解析ライブラリの1つで、HTMLおよびXMLドキュメントを簡単に解析し、解析ツリーをナビゲート、検索、および変更するためのシンプルなAPIを提供します。
- lxml:libxml2およびlibxsltライブラリ上に構築されたPythonライブラリで、解析が速く、HTMLとXMLの両方の解析をサポートし、XPath式と組み合わせて効率的なデータ抽出に使用できます。
- html5lib:このライブラリは、最新のブラウザと非常によく似た方法でHTMLを解析するため、不規則なHTMLコードの処理に適しています。
- JavaScript:ブラウザ環境では、JavaScriptは
document
オブジェクトによって提供されるメソッド(getElementById
やgetElementsByTagName
など)を使用してDOMを直接操作し、HTMLを解析および操作できます。Node.js環境では、jsdom
のようなライブラリがブラウザ環境をシミュレートしてHTMLを解析できます。
3.2 Pythonを使用したHTML解析
3.2.1 BeautifulSoup解析の例
まず、BeautifulSoupライブラリをインストールします。
pip install beautifulsoup4
BeautifulSoupを使用してHTMLを解析するための基本的なコードを次に示します。
from bs4 import BeautifulSoup html_doc = """ <html> <head><title>Sample Page</title></head> <body> <p class="intro">This is an introductory paragraph.</p> <p class="content">Here is some content.</p> </body> </html> """ soup = BeautifulSoup(html_doc, 'html.parser') # Pythonの組み込みパーサーを使用 # 他のパーサー(lxmlなど)も使用できます:soup = BeautifulSoup(html_doc, 'lxml') print(soup.title.string) # 出力:Sample Page
3.2.2 lxml解析の例
lxmlライブラリをインストールします。
pip install lxml
lxmlを使用してHTMLを解析し、XPath経由でデータを抽出します。
from lxml import etree html = """ <html> <body> <div class="box"> <p>First paragraph</p> <p>Second paragraph</p> </div> </body> </html> """ tree = etree.HTML(html) paragraphs = tree.xpath('//div[@class="box"]/p/text()') print(paragraphs) # 出力:['First paragraph', 'Second paragraph']
IV. HTMLドキュメントツリーのナビゲーションと検索
4.1 HTMLドキュメントツリーのナビゲーション
BeautifulSoupを例にとると、解析後、HTMLドキュメントはドキュメントツリーを形成し、複数の方法でナビゲートできます。
- 子要素へのアクセス:タグ名で子要素に直接アクセスできます(例:
soup.body.p
は<body>
要素の下の最初の<p>
要素にアクセスします)。contents
属性を使用して子要素のリストを取得したり、children
属性を使用して子要素をジェネレーターとして反復処理したりすることもできます。 - 親要素へのアクセス:
parent
属性を使用して現在の要素の直接の親を取得し、parents
属性を使用してすべての祖先要素を再帰的にトラバースします。 - 兄弟要素へのアクセス:
next_sibling
およびprevious_sibling
属性は、それぞれ次の兄弟要素と前の兄弟要素を取得します。next_siblings
およびprevious_siblings
属性は、後続および先行するすべての兄弟を反復処理します。
4.2 HTMLドキュメントツリーの検索
find_all()
メソッド:BeautifulSoupのfind_all()
メソッドは、指定された基準に一致するすべての要素を検索します。これらは、タグ名、属性などでフィルタリングできます。たとえば、すべての<p>
タグを検索するには:soup.find_all('p)
; クラスcontent
を持つすべての要素を検索するには:soup.find_all(class_='content')
。find()
メソッド:find()
メソッドは、基準に一致する最初の要素を返します。たとえば、soup.find('a')
は、ドキュメント内の最初の<a>
要素を返します。- CSSセレクター:CSSセレクター構文で
select()
メソッドを使用すると、より柔軟な要素検索が可能です。たとえば、クラスbox
を持つすべての<div>
要素を選択するには:soup.select('div.box)
; IDmain
を持つ要素の下のすべての<li>
要素を選択するには:soup.select('#main li')
。
V. HTMLの変更
5.1 要素属性の変更
PythonライブラリとJavaScriptの両方で、HTML要素の属性を簡単に変更できます。
-
Python(BeautifulSoup):
from bs4 import BeautifulSoup html = """ <html> <body> <a href="https://old-url.com">Old Link</a> </body> </html> """ soup = BeautifulSoup(html, 'html.parser') link = soup.find('a') link['href'] = 'https://new-url.com' # href属性を変更 print(soup.prettify())
-
JavaScript:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <img id="myImage" src="old-image.jpg" alt="Old Image"> <script> const image = document.getElementById('myImage'); image.src = 'new-image.jpg'; // src属性を変更 </script> </body> </html>
5.2 要素の追加と削除
-
Python(BeautifulSoup):
-
要素の追加:
from bs4 import BeautifulSoup html = """ <html> <body> <ul id="myList"></ul> </body> </html> """ soup = BeautifulSoup(html, 'html.parser') ul = soup.find('ul') new_li = soup.new_tag('li') new_li.string = 'New Item' ul.append(new_li) # 新しい要素を追加
-
要素の削除:
from bs4 import BeautifulSoup html = """ <html> <body> <p id="removeMe">This paragraph will be removed.</p> </body> </html> """ soup = BeautifulSoup(html, 'html.parser') p = soup.find('p', id='removeMe') p.decompose() # 要素を削除
-
-
JavaScript:
-
要素の追加:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <div id="parentDiv"></div> <script> const parentDiv = document.getElementById('parentDiv'); const newParagraph = document.createElement('p'); newParagraph.textContent = 'This is a new paragraph.'; parentDiv.appendChild(newParagraph); // 新しい要素を追加 </script> </body> </html>
-
要素の削除:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <p id="removeParagraph">This paragraph will be removed.</p> <script> const paragraph = document.getElementById('removeParagraph'); paragraph.remove(); # 要素を削除 </script> </body> </html>
-
VI. HTMLデータ抽出
6.1 テキストコンテンツの抽出
-
Python(BeautifulSoup):要素内のテキストコンテンツを取得するには、
string
属性またはget_text()
メソッドを使用します。例:from bs4 import BeautifulSoup html = """ <html> <body> <p class="text">Extract this text.</p> </body> </html> """ soup = BeautifulSoup(html, 'html.parser') text = soup.find('p', class_='text').string print(text) # 出力:Extract this text.
-
JavaScript:テキストコンテンツを取得するには、
textContent
またはinnerText
属性を使用します。例:const element = document.getElementById('myElement'); const text = element.textContent;
。
6.2 属性値の抽出
PythonとJavaScriptの両方で、HTML要素の属性値を簡単に抽出できます。たとえば、<a>
タグのhref
属性値を抽出するには:
- Python(BeautifulSoup):
href = soup.find('a')['href']
- JavaScript:
const link = document.querySelector('a'); const href = link.getAttribute('href');
6.3 複雑なデータ抽出
実際のアプリケーションでは、データは多くの場合、複雑なHTML構造から抽出する必要があります。たとえば、製品リストを含むWebページから製品名、価格、リンクを抽出するなどです。このような場合は、ループと条件付きステートメントを上記のナビゲーションおよび検索メソッドと組み合わせて、必要なデータをトラバースおよび抽出します。
from bs4 import BeautifulSoup import requests url = "https://example.com/products" response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') products = [] for product_div in soup.find_all('div', class_='product'): name = product_div.find('h2', class_='product-name').string price = product_div.find('span', class_='product-price').string link = product_div.find('a')['href'] products.append({'name': name, 'price': price, 'link': link}) print(products)
VII. 不規則なHTMLの処理
実際には、HTMLコードには、閉じられていないタグや欠落している属性引用符など、不規則な形式がよくあります。異なるパーサーは、不規則なHTMLを異なる方法で処理します。
- html5lib:このパーサーはブラウザーと同様に動作し、エラーのある構造を修正しようとすることで、不規則なHTMLをより適切に処理できます。
- lxml:lxmlパーサーは比較的厳格ですが、ある程度のフォールトトレランスがあります。非常に不規則なHTMLを処理する場合は、最初に前処理するか、
recover=True
パラメーターを指定してlxml.etree.HTMLParser
を使用してリカバリモードを有効にする必要がある場合があります。 - BeautifulSoup:選択したパーサーの特性に基づいて、不規則なHTMLを処理します。複雑な不規則ドキュメントの場合は、html5libパーサーを優先することをお勧めします。
VIII. パフォーマンスの最適化とベストプラクティス
8.1 適切なパーサーの選択
特定のニーズに基づいてパーサーを選択します。
- lxml:HTMLが比較的標準化されている場合に、速度を重視する場合に最適です。
- html5lib:不規則なHTMLの処理により適しています。
- html.parser(Python組み込み):シンプルさと適度なパフォーマンス要件で基本的なニーズを満たします。
8.2 冗長な解析の削減
複数のHTMLドキュメントを処理する場合、または同じドキュメントを複数回操作する場合は、冗長な解析を避けてください。解析された結果をキャッシュするか、1回の解析パスですべての関連操作を完了します。
8.3 検索メソッドの適切な使用
要素を検索する場合は、不必要なトラバースを減らすために、より正確なフィルタリング条件を使用します。たとえば、CSSセレクターまたはXPath式を使用すると、ターゲット要素をより効率的に見つけることができます。
IX. 結論
このチュートリアルでは、基本的な構造、解析方法、ドキュメントツリーのナビゲーション、変更操作、データ抽出、および不規則なHTMLを処理するためのテクニックなど、HTML処理のすべての側面を包括的に学習しました。実際には、特定のシナリオに基づいて適切なツールと方法を選択し、パフォーマンスの最適化とベストプラクティスに焦点を当てることで、HTML処理タスクをより効率的に完了できます。Web開発でもデータ収集でも、HTML処理スキルを習得すると、作業が大幅に促進されます。
このチュートリアルでは、HTML処理の重要な側面について説明します。学習中に特定のユースケースがある場合、または特定のセクションをより深く掘り下げたい場合は、いつでもお気軽にご連絡ください。
最高のサーバーレスWebホスティング:Leapcell
最後に、Pythonサービスをデプロイするための最適なプラットフォームをお勧めします:Leapcell
🚀 お気に入りの言語で構築
JavaScript、Python、Go、またはRustで簡単に開発。
🌍 無制限のプロジェクトを無料でデプロイ
使用量に応じてのみ支払い—リクエストも料金もなし。
⚡ 従量課金制、隠れたコストなし
アイドル料金はなく、シームレスなスケーラビリティのみ。
🔹 Twitterでフォローしてください:@LeapcellHQ