Steamer Lane Studio技術備忘録ユーティリティ

指定のページの指定のclass内を別のサイトのページに取り込むPHPコード

utility 指定のページの指定のclass内を別のサイトのページに取り込むPHPコード
最終更新日: 2025年3月20日

昔PHPが5x頃にかなり複雑なものを作ったが、改めて必要が出たのでPHP8.1対応で作ってみた。
スクレイピングの初歩、簡易的な部分抜き出しってことで。
コンテンツのコピーはSEO上よろしくないが、別ドメインでも同じ所有者だとか、本サイトとサテライトサイトといった関係性なら「コピーコンテンツ」と判定されることはまずないと、いうことなので使用を誤らなければコンテンツの2重投稿などの手間を減らせることになる。
以前はMovableTypeベースで親に投稿都度子にもページからできて、sitemapから全部賄うものを作ったが、今回は単純に指定ページの指定クラス内を取り込むだけなので、拡張子がphpなら何でも利用可能。

<?php$url = "https://ページ指定";
$html = file_get_contents($url);

// '</a>>' を '</a>' に置換・・・これは作った際の対象ページがそうだったのだが何故かaの閉じタグ浴後に>(全角なら良かったが)が付与されていてそのままではエラーになるので全ソースコードをを整形。必要があれば、必要なものを残すという処理前にこうした処理をする。。$html = preg_replace('/<\/a>>/s', '</a>', $html);

function keepOnlySelectedTags($html, $tagName, $class) {
$pattern = "/<{$tagName}[^>]*class=\"{$class}\"[^>]*>(.*?)<\/{$tagName}>/s";
preg_match_all($pattern, $html, $matches);
return implode('', $matches[0]);
}

$tagName = 'ul'; // htmlタグ指定今回はul

$class = 'link_list'; // クラスを指定

$cleanedHtml = keepOnlySelectedTags($html, $tagName, $class);

echo $cleanedHtml;
?>

今回はul.link_list以外を削除して取り込むって内容。
あまり使わないけど、複数サイトを管理するWEBマスターなんかには便利かな。

こちら改修版php8.2up対応他、Wordpress以外対応

<?php// スクレイピング対象のURL(具体的なパスを記述)$url = "https://www.指定のURL"; // ここに実際のURLを記述(例:https://example.com)

// HTMLを取得$context = stream_context_create(['http' => ['timeout' => 10,'header' => "User-Agent: PHP\r\n",]]);$html = @file_get_contents($url, false, $context);if ($html === false) {$error = error_get_last();die("Failed to fetch content from the URL: " . htmlspecialchars($error['message'] ?? 'Unknown error', ENT_QUOTES, 'UTF-8'));}

// エンコーディングの検出と変換$encoding = mb_detect_encoding($html, 'UTF-8, Shift_JIS, EUC-JP', true);if ($encoding && $encoding !== 'UTF-8') {$html = mb_convert_encoding($html, 'UTF-8', $encoding);}

// DOMDocumentでHTMLをパースlibxml_use_internal_errors(true); // パースエラーを無視$dom = new DOMDocument();@$dom->loadHTML('<?xml encoding="UTF-8">' . $html); // UTF-8を明示libxml_clear_errors();

// DOMXPathで特定のクラスを持つ要素を取得(順序指定)$xpath = new DOMXPath($dom);

// 最初のクラス$firstNode = $xpath->query("(//div[contains(@class, 'child_pages')])[1]"); // 1つ目の要素 必要に応じdiv→sectionなどif ($firstNode->length > 0) {echo $dom->saveHTML($firstNode->item(0)) . "\n\n";}

// 2つ目のクラス$secondNode = $xpath->query("(//div[contains(@class, 'child_pages')])[2]"); // 2つ目の要素 必要に応じdiv→sectionなどif ($secondNode->length > 0) {echo $dom->saveHTML($secondNode->item(0)) . "\n\n";}

// 3つ目のクラス$thirdNode = $xpath->query("(//div[contains(@class, 'child_pages')])[3]"); // 3つ目の要素 必要に応じdiv→sectionなどif ($thirdNode->length > 0) {echo $dom->saveHTML($thirdNode->item(0)) . "\n\n";}

// 要素が見つからなかった場合if ($firstNode->length === 0 && $secondNode->length === 0 && $thirdNode->length === 0) {echo "指定されたクラス(child_pages)を持つ要素が見つかりませんでした。\n";}?>