CSSセレクタやXPathで指定したページ内のノードだけのスクリーンショットを撮りつつ、指定ノード以下のHTMLだけを取得する方法の解説です。
chrome-php/chrome だけでスクレイピングしていきます。
前提条件
- PHP 8.2以降インストール済(Laravel11の要件)
- Composerインストール済
- WSL2経由のUbuntu上で作業しています。
- chrome-php/chromeを使います
- Google Chromeインストール済
※WSL2経由のUbuntuはデフォルトではGUIが使えません。
※スクリーンショットを撮るにはGoogle Chromeが必用です。
※▼こちらのページを参考にGoogle Chromeをインストールしてください。

※AWS EC2でもインストール可能です。(確認済)
※ロリポップのような共用サーバではインストール不可です。
これからやること
- PHPプロジェクト新規作成
- chrome-php/chromeインストール
- ダミーWEBサイト立ち上げ(Laravel)
- 指定箇所の確認
- コード作成
- コード実行
PHPプロジェクト新規作成
フォルダ「using-chrome」を作成し、中に入ります。
mkdir using-chrome
cd using-chrome

各種ファイル保存用のフォルダを作っておきます。
mkdir -p storage/screenshots
mkdir storage/html
mkdir src

chrome-php/chromeインストール
chrome-php/chrome をインストールします。
composer require chrome-php/chrome

ダミーWEBサイト立ち上げ(Laravel)
外部WEBサイトに迷惑を掛けないように
ダウンしても構わないダミーWEBサイトを立ち上げます。
composer create-project laravel/laravel:^11 dummy-web

「dummy-web」フォルダに入り、
Laravelのビルトインサーバーを起動します。
cd dummy-web
php artisan serve

WEBブラウザで http://localhost:8000/ にアクセスします。

Laravelのデフォルトページが表示されました。
指定箇所の確認
Laravelのデフォルトページ内にある、
「Documentation」の見出しとアイコンのある個所の
親ノードのブロックをCSSセレクターで指定することにします。

この箇所のCSSセレクターは
#docs-card-content
となります。
コード作成
「src/getScreenshotAndHtml.php」
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use HeadlessChromium\BrowserFactory;
use HeadlessChromium\Clip;
use HeadlessChromium\Dom\Dom;
use HeadlessChromium\Dom\Selector\CssSelector;
use HeadlessChromium\Dom\Selector\XPathSelector;
use HeadlessChromium\Page;
use headlessChromium\Utils;
// 保存先フォルダ
$storagePath = __DIR__ . '/../storage/';
$dirScreenshot = $storagePath . 'screenshots/';
$dirHtml = $storagePath . 'html/';
// URL
$url = 'http://localhost:8000/';
// セレクター(CSSセレクター、またはXPath)
$selector = '#docs-card-content';
//$selector = '//*[@id="docs-card-content"]'; // XPath
// Chromeのウィンドウサイズ
$width = 800;
$height = 600;
// Chrome起動
$browserFactory = new BrowserFactory();
$browser = $browserFactory->createBrowser([
'windowSize' => [$width, $height],
]);
try {
// URLへアクセス、Javascriptレンダリング完了まで待ち
$page = $browser->createPage();
$page->navigate($url)->waitForNavigation(Page::INTERACTIVE_TIME);
$page->evaluate('document.documentElement.innerHTML');
// 指定箇所の位置取得
$position = Utils::getElementPositionFromPage(
$page,
new CssSelector($selector)
//new XPathSelector($selector) // XPathのときはこちら
);
// 指定箇所の要素の枠指定
$clip = new Clip(
$position['left'],
$position['top'],
$position['width'],
$position['height']
);
// スクリーンショット保存(ページ全体)
$page->screenshot([
'captureBeyondViewport' => true,
'clip' => $page->getFullPageClip(),
])
->saveToFile($dirScreenshot . '/localhost_top_full_page.png');
// スクリーンショット保存(指定要素のみ)
$page->screenshot([
'captureBeyondViewport' => true,
'clip' => $clip,
])
->saveToFile($dirScreenshot . '/localhost_top_seleced.png');
// ページ全体のHTML取得&保存
$html = $page->getHtml();
file_put_contents($dirHtml . 'localhost_top.html', $html);
// 指定箇所以下のHTML取得&保存
$selectedNodes = (new Dom($page))->search($selector);
file_put_contents(
$dirHtml . 'localhost_top_selected.html',
// 複数の該当ノードのHTMLを改行コードで結合
implode(
PHP_EOL,
array_map(
// $node: HeadlessChromium\Dom\Node
// HeadlessChromium\Dom\Node->getHtml()
// で該当ノード以下のHTMLを文字列で取得できます。
fn ($node) => $node->getHtml(),
// $selectedNodes: array<int, HeadlessChromium\Dom\Node>
$selectedNodes
)
)
);
} finally {
// Chrome終了
$browser->close();
}
コード実行
実行してみます。
php -f src/getScreenshotAndHtml.php
数秒経って、スクリーンショットとHTMLが保存されました。

まずはスクリーンショットを確認してみます。
▼ページ全体

▼CSSセレクターでの指定箇所

続いてHTMLを確認してみます。
▼ページ全体のHTML

▼CSSセレクターでの指定箇所のHTML

しっかりキャプチャできていますね。
- 1
- 0
- 0
- 0


コメント