雑記帳

このページは下の方が新しい項目です。

CSSの収集/phpQuery

この記事へのリンク

古いままのページをなんとかしたいと思って、CSSを収集、解析するスクリプトを組もうとしています。「スクレイピング」ということになるのかな。スクレイピングではPythonを使うのが一般的なようですが、それよりも気楽に書けるような気がするのでPHPを使うことにしました(「気楽」に書けるからといって「容易」に完成するとは限らないのだけど)。

PHPでのスクレイピングではphpQueryがよく使われているようなので、これ(phpQuery-onefile)を使います。

こんな感じ。

<?php
require_once("./phpQuery-onefile.php");
$url = "http://example.jp/foo/bar/hoge.html"; // 取得するHTML
$html = file_get_contents($url);     // 読み込む
$doc = phpQuery::newDocument($html); // 読み込んだHTMLをphpQueryに渡す

// CSSファイルへのリンク
foreach($doc["link[rel$='stylesheet']"] as $tt )
{
	echo pq($tt)->attr("href")."\n";
}

// STYLE要素
foreach($doc["style"] as $tt )
{
	echo pq($tt)->text();
}

// STYLE属性
foreach($doc["*[style]"] as $tt )
{
	echo pq($tt)->attr("style")."\n";
}
?>

このコードでは画面に表示するだけですが、取得できたCSSから必要な部分を抜き出したり、指定された外部CSSファイルを読みに行ったりする処理を加えていくわけです。

さて困ったことがあります。文字化けしたりしなかったりするのです。

phpQueryの中身を見てみると、<meta http-equiv="Content-Type" content="text/html;charset=(文字コード)"> の形での文字コード指定をチェックしている部分がありますが、取りこぼしがあるようです。さらに、この文字コードの指定方法は古いもので、HTML5の書式 <meta charset="(文字コード)"> には対応してないようです。

読み込んだHTMLをphpQueryに渡すのではなく、phpQueryに直接WEB上のHTMLファイルを読みに行かせるとレスポンスヘッダの文字コード指定を見てくれるようですが(たぶん)、皆さんご存知の通りレスポンスヘッダに文字コード指定のない場合が多いので解決にはなりません。

ということで、読み込んだHTMLをphpQueryに渡す前に文字コード変換してやることにしました。そしてphpQueryの方でさらに文字コード変換するとまずいので、META要素を削除しています。

$html = mb_convert_encoding($html, "UTF-8", "SJIS,JIS,EUC-JP,UTF-8");
$html = preg_replace ("/<meta.*?>/i", "", $html );
$doc = phpQuery::newDocument($html);

UTF-8へ変換しているのはもちろんこのPHPスクリプトをUTF-8で記述しているからです。