1.

phpQuery 導入と使い方|PHP で jQuery 風 DOM 操作・スクレイピング

編集
この記事の要点
  • phpQuery: PHP で jQuery 風 DOM 操作・スクレイピングができるライブラリ
  • 導入: phpQuery-onefile.phprequire_once
  • 使い方: $doc = phpQuery::newDocument($html); $title = $doc['h1']->text();
  • 古いライブラリ(2009 年最終更新)— 新規プロジェクトでは Symfony DomCrawler / Goutte を推奨
  • 依然として日本語サンプルが豊富で学習教材として残っている

phpQuery とは

phpQuery は PHP 上で jQuery と同じ構文で HTML/XML を操作できるライブラリです。Web スクレイピング・HTML パース・テンプレート操作などに使われます。

導入

  1. 公式アーカイブから最新の phpQuery-onefile.zip をダウンロード
  2. 解凍して phpQuery-onefile.php をプロジェクトに配置
  3. 使うファイルで require_once
require_once 'phpQuery-onefile.php';

// HTML 文字列からドキュメント作成
$doc = phpQuery::newDocument($html);

// または HTML ファイルから
$doc = phpQuery::newDocumentFile('page.html');

// URL から(file_get_contents 経由)
$doc = phpQuery::newDocument(file_get_contents('https://example.com'));

基本的な使い方

require_once 'phpQuery-onefile.php';

$html = file_get_contents('https://example.com');
$doc = phpQuery::newDocument($html);

// jQuery 風セレクタ
$title = $doc['h1']->text();
echo $title;  // → "Example Domain"

// 属性取得
$linkHref = $doc['a:first']->attr('href');

// 複数要素のループ
foreach ($doc['ul li'] as $li) {
    $li = pq($li);  // ★ pq() でラップしてメソッドを使う
    echo $li->text() . "\n";
}

// 属性を持つ要素を絞り込む
foreach ($doc['a[href^=https]'] as $link) {
    $link = pq($link);
    echo $link->attr('href') . " - " . $link->text() . "\n";
}

セレクタの例(jQuery と同じ)

セレクタ意味
$doc['h1']すべての h1
$doc['.classname']class 指定
$doc['#id']id 指定
$doc['div.box']タグ + class
$doc['ul > li']直接の子要素
$doc['a[href*=example]']href 属性に example を含む a
$doc['li:first']最初の li
$doc['li:eq(2)']3 番目の li (0-indexed)
$doc['li:not(.active)']active クラスでない li

DOM 操作(取得だけでなく変更も可能)

$doc = phpQuery::newDocument($html);

// テキスト変更
$doc['h1']->text('新しいタイトル');

// HTML 挿入
$doc['div.content']->html('<p>新しい段落</p>');

// 追加・削除
$doc['ul']->append('<li>新しい項目</li>');
$doc['li.old']->remove();

// 属性変更
$doc['a']->attr('target', '_blank');
$doc['a']->addClass('external');
$doc['a']->removeClass('disabled');

// 変更後の HTML 取得
$modifiedHtml = $doc->html();
// または echo $doc; (toString)

実例: ニュースサイトのスクレイピング

require_once 'phpQuery-onefile.php';

$html = file_get_contents('https://news.example.com/');
$doc = phpQuery::newDocument($html);

$articles = [];
foreach ($doc['article.news-item'] as $item) {
    $item = pq($item);
    $articles[] = [
        'title' => trim($item->find('h2.title')->text()),
        'url'   => $item->find('a.read-more')->attr('href'),
        'date'  => $item->find('time')->attr('datetime'),
        'image' => $item->find('img')->attr('src'),
    ];
}

print_r($articles);
phpQuery::unloadDocuments();  // メモリ解放

メモリ管理(重要)

phpQuery はドキュメントをグローバルに保持するため、ループでドキュメントを何度も作るとメモリリークします:

foreach ($urls as $url) {
    $html = file_get_contents($url);
    $doc = phpQuery::newDocument($html);
    // ... 処理
    phpQuery::unloadDocuments();  // ★ 必ず解放
}

モダンな代替: Symfony DomCrawler / Goutte

phpQuery は 2009 年で更新が止まっている古いライブラリです。新規プロジェクトでは以下を推奨:

Symfony DomCrawler

// composer require symfony/dom-crawler symfony/css-selector
use Symfony\Component\DomCrawler\Crawler;

$crawler = new Crawler($html);
$title = $crawler->filter('h1')->text();

foreach ($crawler->filter('ul > li') as $node) {
    echo $node->textContent . "\n";
}

// CSS セレクタ風に書ける
$titles = $crawler->filter('article.news h2')->each(function ($node) {
    return trim($node->text());
});

Goutte(DomCrawler + HTTP クライアント)

// composer require fabpot/goutte
use Goutte\Client;

$client = new Client();
$crawler = $client->request('GET', 'https://example.com/');

$title = $crawler->filter('h1')->text();

// フォームの操作も可能
$form = $crawler->selectButton('Submit')->form();
$form['username'] = 'foo';
$crawler = $client->submit($form);

比較

phpQuerySymfony DomCrawlerGoutte
導入1 ファイルcomposercomposer
更新2009 年で停止活発活発
HTTP リクエスト別途必要 (curl/file_get_contents)別途必要内蔵
DOM 操作(書き換え)△ (読み取り重視)
JS 実行×× (Panther なら可)×
学習コストjQuery 経験者は速い

スクレイピング時の注意

  • robots.txt の遵守/robots.txt でクローラ拒否されているサイトを叩かない
  • User-Agent を設定 — 多くのサイトはデフォルトの PHP UA をブロック
  • レート制限 — リクエスト間に sleep(1) を入れる
  • JavaScript レンダリングが必要なサイトには Headless Chrome (Puppeteer / Playwright) を別途使う
  • 利用規約の確認 — 商用利用や大量スクレイピングは要許可
編集
Post Share
子ページ

子ページはありません

同階層のページ

同階層のページはありません