本ガイドでは、PHPでHTMLをパースする3つのテクニックを検証し、それぞれの強みと違いを比較します。
PHPでのHTMLパースとは、HTMLコンテンツをDOM(Document Object Model)構造に変換することです。DOM形式になれば、HTMLコンテンツのナビゲーションや操作を簡単に行えます。
特に、PHPでHTMLをパースする主な理由は次のとおりです。
- データ抽出:HTML要素のテキストや属性など、Webページから特定のコンテンツを取得します。
- 自動化:コンテンツのスクレイピング、レポート作成、HTMLからのデータ集約といったタスクを効率化します。
- サーバーサイドでのHTML処理:アプリケーションでレンダリングする前に、HTMLをパースしてクリーンアップ、整形、変更します。
コーディングを始める前に、マシンにPHP 8.4+がインストールされていることを確認してください。以下のコマンドを実行すると確認できます。
php -v出力は次のようになります。
PHP 8.4.3 (cli) (built: Jan 19 2025 14:20:58) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.3, Copyright (c) Zend Technologies
with Zend OPcache v8.4.3, Copyright (c), by Zend Technologies
次に、依存関係の管理を簡単にするためにComposerプロジェクトを初期化します。Composerがシステムにインストールされていない場合は、ダウンロードしてインストール手順に従ってください。
まず、PHPのHTMLプロジェクト用に新しいフォルダを作成します。
mkdir php-html-parserターミナルでそのフォルダに移動し、composer initコマンドで中にComposerプロジェクトを初期化します。
composer initこのプロセスではいくつか質問されます。デフォルトの回答で問題ありませんが、必要に応じて、PHPのHTMLパースプロジェクトに合わせてより具体的な内容を指定することもできます。
次に、お好みのIDEでプロジェクトフォルダを開きます。PHP開発には、PHP拡張機能付きVisual Studio CodeまたはIntelliJ WebStormが良い選択肢です。
続いて、プロジェクトフォルダに空のindex.phpファイルを追加します。プロジェクト構成は次のようになります。
php-html-parser/
├── vendor/
├── composer.json
└── index.php
index.phpを開き、プロジェクトを初期化するために次のコードを追加してください。
<?php
require_once __DIR__ . "/vendor/autoload.php";
// scraping logic...次のコマンドでスクリプトを実行します。
php index.phpPHPでHTMLをパースする前に、パースするHTMLが必要です。本セクションでは、PHPでHTMLコンテンツにアクセスする2つの異なるアプローチを見ていきます。あわせて、PHPでのWebスクレイピングガイドも読むことをおすすめします。
PHPは、HTTPリクエストを実行するために一般的に使われるHTTPクライアントであるcURLをネイティブでサポートしています。cURL拡張を有効化するか、Ubuntu Linuxでは次のコマンドでインストールしてください。
sudo apt-get install php8.4-curlcURLを使用すると、オンラインサーバーへHTTP GETリクエストを送信し、サーバーから返されるHTMLドキュメントを取得できます。次の例のスクリプトは、シンプルなGETリクエストを行い、HTMLコンテンツを取得します。
// initialize cURL session
$ch = curl_init();
// set the URL you want to make a GET request to
curl_setopt($ch, CURLOPT_URL, "https://www.scrapethissite.com/pages/forms/?per_page=100");
// return the response instead of outputting it
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// execute the cURL request and store the result in $response
$html = curl_exec($ch);
// close the cURL session
curl_close($ch);
// output the HTML response
echo $html;上記のコードスニペットをindex.phpに追加して実行してください。次のHTMLコードが生成されます。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hockey Teams: Forms, Searching and Pagination | Scrape This Site | A public sandbox for learning web scraping</title>
<link rel="icon" type="image/png" href="/static/images/scraper-icon.png" />
<!-- Omitted for brevity... -->
</html>cURLを使って事前に取得した、Scrape This Siteの「Hockey Teams」ページのHTMLを含むindex.htmlというファイルがあると仮定します。
本セクションでは、PHPでHTMLをパースするために3つの異なるライブラリを使用する方法を説明します。
- 素のPHP向けに
Dom\HTMLDocumentを使用 - Simple HTML DOM Parserライブラリを使用
- Symfonyの
DomCrawlerコンポーネントを使用
いずれのケースでも、ローカルのindex.htmlファイルからHTMLをパースし、ページ上のすべてのホッケーチームのエントリを選択して、そこからデータを抽出します。
最終結果は、次の詳細を含むスクレイピング済みホッケーチームのエントリ一覧になります。
- Team Name
- Year
- Wins
- Losses
- Win %
- Goals For (GF)
- Goals Against (GA)
- Goal Difference
これらは、次の構造を持つHTMLテーブルから抽出できます。
テーブル行の各カラムには固有のclassが付いており、classをCSSセレクタとして要素を選択し、テキストとして内容を取得することでデータを抽出できます。
PHP 8.4+ には組み込みのDom\HTMLDocumentクラスがあります。これはHTMLドキュメントを表し、HTMLコンテンツのパースやDOMツリーのナビゲーションを可能にします。
Dom\HTMLDocumentはStandard PHP Libraryの一部です。ただし、使用するにはDOM拡張を有効化するか、次のLinuxコマンドでインストールする必要があります。
sudo apt-get install php-domHTML文字列は次のようにパースできます。
$dom = \DOM\HTMLDocument::createFromString($html);index.htmlファイルは次のようにパースできます。
$dom = \DOM\HTMLDocument::createFromFile("./index.html");$domはDom\HTMLDocumentオブジェクトで、データパースに必要なメソッドが提供されます。
次のアプローチで、\DOM\HTMLDocumentを使ってすべてのホッケーチームのエントリを選択できます。
// select each row on the page
$table = $dom->getElementsByTagName("table")->item(0);
$rows = $table->getElementsByTagName("tr");
// iterate through each row and extract data
foreach ($rows as $row) {
$cells = $row->getElementsByTagName("td");
// extracting the data from each column
$team = trim($cells->item(0)->textContent);
$year = trim($cells->item(1)->textContent);
$wins = trim($cells->item(2)->textContent);
$losses = trim($cells->item(3)->textContent);
$win_pct = trim($cells->item(5)->textContent);
$goals_for = trim($cells->item(6)->textContent);
$goals_against = trim($cells->item(7)->textContent);
$goal_diff = trim($cells->item(8)->textContent);
// create an array for the scraped team data
$team_data = [
"team" => $team,
"year" => $year,
"wins" => $wins,
"losses" => $losses,
"win_pct" => $win_pct,
"goals_for" => $goals_for,
"goals_against" => $goals_against,
"goal_diff" => $goal_diff
];
// print the scraped team data
print_r($team_data);
print ("\n");
}\DOM\HTMLDocumentは高度なクエリメソッドを提供しません。そのため、getElementsByTagName()のようなメソッドと手動の反復処理に依存する必要があります。
使用したメソッドの内訳は次のとおりです。
getElementsByTagName():ドキュメント内の指定タグ(<table>、<tr>、<td>など)の全要素を取得します。item():getElementsByTagName()が返す要素リストから個別要素を返します。textContent:要素の生のテキスト内容を返すプロパティで、表示されるデータ(チーム名、年など)を抽出できます。
また、テキスト内容の前後にある余分な空白を取り除いてデータを整えるために、trim()も使用しました。
上記スニペットをindex.phpに追加すると、次の結果が得られます。
Array
(
[team] => Boston Bruins
[year] => 1990
[wins] => 44
[losses] => 24
[win_pct] => 0.55
[goals_for] => 299
[goals_against] => 264
[goal_diff] => 35
)
// omitted for brevity...
Array
(
[team] => Detroit Red Wings
[year] => 1994
[wins] => 33
[losses] => 11
[win_pct] => 0.688
[goals_for] => 180
[goals_against] => 117
[goal_diff] => 63
) Simple HTML DOM Parserは軽量なPHPライブラリで、HTMLコンテンツのパースと操作を簡単にします。
次のコマンドで、Composer経由でSimple HTML Dom Parserをインストールできます。
composer require voku/simple_html_domまたは、simple_html_dom.phpファイルを手動でダウンロードしてプロジェクトに含めることもできます。
次に、このコード行でindex.phpにインポートします。
use voku\helper\HtmlDomParser;HTML文字列をパースするには、file_get_html()メソッドを使用します。
$dom = HtmlDomParser::str_get_html($html);index.htmlをパースする場合は、代わりにfile_get_html()を書きます。
$dom = HtmlDomParser::file_get_html($str);これによりHTMLコンテンツが$domオブジェクトに読み込まれ、DOMを簡単に辿れるようになります。
Simple HTML DOM Parserを使用して、HTMLからホッケーチームのデータを抽出します。
// find all rows in the table
$rows = $dom->findMulti("table tr.team");
// loop through each row to extract the data
foreach ($rows as $row) {
// extract data using CSS selectors
$team_element = $row->findOne(".name");
$team = trim($team_element->plaintext);
$year_element = $row->findOne(".year");
$year = trim($year_element->plaintext);
$wins_element = $row->findOne(".wins");
$wins = trim($wins_element->plaintext);
$losses_element = $row->findOne(".losses");
$losses = trim($losses_element->plaintext);
$win_pct_element = $row->findOne(".pct");
$win_pct = trim($win_pct_element->plaintext);
$goals_for_element = $row->findOne(".gf");
$goals_for = trim($goals_for_element->plaintext);
$goals_against_element = $row->findOne(".ga");
$goals_against = trim(string: $goals_against_element->plaintext);
$goal_diff_element = $row->findOne(".diff");
$goal_diff = trim(string: $goal_diff_element->plaintext);
// create an array with the extracted team data
$team_data = [
"team" => $team,
"year" => $year,
"wins" => $wins,
"losses" => $losses,
"win_pct" => $win_pct,
"goals_for" => $goals_for,
"goals_against" => $goals_against,
"goal_diff" => $goal_diff
];
// print the scraped team data
print_r($team_data);
print("\n");
}上記で使用したSimple HTML DOM Parserの機能は次のとおりです。
findMulti():指定したCSSセレクタで識別されるすべての要素を選択します。findOne():指定したCSSセレクタに一致する最初の要素を特定します。plaintext:HTML要素内部の生のテキスト内容を取得するための属性です。
今回は、より包括的で堅牢なロジックでCSSセレクタを適用しましたが、結果は最初のPHPでのHTMLパースアプローチと同じです。
SymfonyのDomCrawlerコンポーネントは、HTMLドキュメントを簡単にパースし、そこからデータを抽出できるようにします。
Note: このコンポーネントはSymfony frameworkの一部ですが、本セクションで行うようにスタンドアロンでも使用できます。
次のComposerコマンドでSymfonyのDomCrawlerコンポーネントをインストールします。
composer require symfony/dom-crawler次に、index.phpファイルにインポートします。
use Symfony\Component\DomCrawler\Crawler;HTML文字列をパースするには、html()メソッドでCrawlerインスタンスを作成します。
$crawler = new Crawler($html);ファイルをパースする場合は、file_get_contents()を使用してCrawlerインスタンスを作成します。
$crawler = new Crawler(file_get_contents("./index.html"));上記の行によりHTMLコンテンツが$crawlerオブジェクトに読み込まれ、データの走査と抽出を容易にするメソッドが提供されます。
DomCrawlerコンポーネントを使用してホッケーチームのデータを抽出します。
// select all rows within the table
$rows = $crawler->filter("table tr.team");
// loop through each row to extract the data
$rows->each(function ($row, $i) {
// extract data using CSS selectors
$team_element = $row->filter(".name");
$team = trim($team_element->text());
$year_element = $row->filter(".year");
$year = trim($year_element->text());
$wins_element = $row->filter(".wins");
$wins = trim($wins_element->text());
$losses_element = $row->filter(".losses");
$losses = trim($losses_element->text());
$win_pct_element = $row->filter(".pct");
$win_pct = trim($win_pct_element->text());
$goals_for_element = $row->filter(".gf");
$goals_for = trim($goals_for_element->text());
$goals_against_element = $row->filter(".ga");
$goals_against = trim($goals_against_element->text());
$goal_diff_element = $row->filter(".diff");
$goal_diff = trim($goal_diff_element->text());
// create an array with the extracted team data
$team_data = [
"team" => $team,
"year" => $year,
"wins" => $wins,
"losses" => $losses,
"win_pct" => $win_pct,
"goals_for" => $goals_for,
"goals_against" => $goals_against,
"goal_diff" => $goal_diff
];
// print the scraped team data
print_r($team_data);
print ("\n");
});使用したDomCrawlerのメソッドは次のとおりです。
each():選択した要素のリストを反復処理します。filter():CSSセレクタに基づいて要素を選択します。text():選択した要素のテキスト内容を抽出します。
ここで取り上げたPHPでHTMLをパースする3つのアプローチを、以下のサマリ表で比較できます。
| \DOM\HTMLDocument | Simple HTML DOM Parser | Symfony’s DomCrawler | |
|---|---|---|---|
| Type | PHPネイティブコンポーネント | 外部ライブラリ | Symfonyコンポーネント |
| GitHub Stars | — | 880+ | 4,000+ |
| XPath Support | ❌ | ✔️ | ✔️ |
| CSS Selector Support | ❌ | ✔️ | ✔️ |
| Learning Curve | 低 | 低〜中 | 中 |
| Simplicity of Use | 中 | 高 | 高 |
| API | 基本 | 充実 | 充実 |
これらのソリューションは動作しますが、ターゲットのWebページがレンダリングにJavaScriptを依存している場合は効果的ではありません。そのようなケースでは、上記のようなシンプルなHTMLパース手法だけでは不十分です。代わりに、Scraping Browserのような、高度なHTMLパース機能を備えたフル機能のスクレイピングブラウザが必要になります。
HTMLパースを省略して構造化データへ即時アクセスしたい場合は、数百のWebサイトを網羅するすぐに使えるデータセットをご覧ください。
今すぐBright Dataアカウントを作成し、無料トライアルで当社のデータおよびスクレイピングソリューションのテストを開始しましょう!



