阿部寛のホームページをPHPでDOMる
HTML を正しい文字コードで DOMDocument にしたい
DOMDocument が勝手に meta 検出してくれたら良いのだけど。
とりあえず自前で文字コード検出して、うまく変換して、DOMDocument を作る実験。
阿部寛のホームページが安定して昔ながらの文字コードを使ってくれているので実験材料に良い。
http://abehiroshi.la.coocan.jp/
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=x-sjis">
<title>阿部寛のホームページ</title>
</head>
<frameset cols=18,82>
<frame src=menu.htm marginheight=0 marginwidth=0 scrolling=auto name=left>
<frame src=top.htm marginheight=0 marginwidth=0 scrolling=auto name=right>
</frameset><noframes></noframes>
そもそも frame が懐かしい。
作成したコード
<?php
// HTML全体からtitleを取得
function html2title($html){
// まずは UTF-8 で決め打ち
$htmlEncoded = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
$doc = new DOMDocument();
@$doc->loadHTML($htmlEncoded);
// metaからcharset検出
$charset = '';
$elements = $doc->getElementsByTagName("meta");
for($i = 0; $i < $elements->length; $i++){
$e = $elements->item($i);
// charset属性をチェック
// <meta charset="utf-8"/>
$node = $e->attributes->getNamedItem("charset");
if($node){
$charset = $node->nodeValue;
break;
}
// http-equiv属性をチェック
// <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
$node = $e->attributes->getNamedItem("http-equiv");
if($node && strcasecmp($node->nodeValue, 'content-type') == 0){
$node = $e->attributes->getNamedItem("content");
if($node && preg_match('/[\; ]charset ?\= ?([A-Za-z0-9\-\_]+)/', $node->nodeValue, $m)){
$charset = $m[1];
break;
}
continue;
}
}
// 検出されたcharsetがUTF-8じゃなかったら
if($charset !== '' && !preg_match('/^utf\-?8$/i', $charset)){
// 文字コード変換し直して
$htmlEncoded = mb_convert_encoding($html, 'HTML-ENTITIES', $charset);
// DOMも構築し直す
$doc = new DOMDocument();
@$doc->loadHTML($htmlEncoded);
}
// title取得
$elements = $doc->getElementsByTagName("title");
for($i = 0; $i < $elements->length; $i++){
$e = $elements->item($i);
return $e->textContent;
}
// titleが見つからなかった場合
return false;
}
// -- -- 実験コード -- -- //
// x-sjis の例
$body = file_get_contents("http://abehiroshi.la.coocan.jp/");
$title = html2title($body);
echo "title = $title\n";
// euc-jp の例
$body = file_get_contents("http://d.hatena.ne.jp/");
$title = html2title($body);
echo "title = $title\n";
// Shift_JIS の例
$body = file_get_contents("http://www.tohoho-web.com/www.htm");
$title = html2title($body);
echo "title = $title\n";
// UTF-8 の例
$body = file_get_contents("http://qiita.com/");
$title = html2title($body);
echo "title = $title\n";
実行結果
title = 阿部寛のホームページ
title = はてなダイアリー - 写真・画像・動画付き日記を無料で
title = とほほのWWW入門
title = Qiita - プログラマの技術情報共有サービス
<?php
// HTML全体からtitleを取得
function html2title($html){
// まずは UTF-8 で決め打ち
$htmlEncoded = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
$doc = new DOMDocument();
@$doc->loadHTML($htmlEncoded);
// metaからcharset検出
$charset = '';
$elements = $doc->getElementsByTagName("meta");
for($i = 0; $i < $elements->length; $i++){
$e = $elements->item($i);
// charset属性をチェック
// <meta charset="utf-8"/>
$node = $e->attributes->getNamedItem("charset");
if($node){
$charset = $node->nodeValue;
break;
}
// http-equiv属性をチェック
// <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
$node = $e->attributes->getNamedItem("http-equiv");
if($node && strcasecmp($node->nodeValue, 'content-type') == 0){
$node = $e->attributes->getNamedItem("content");
if($node && preg_match('/[\; ]charset ?\= ?([A-Za-z0-9\-\_]+)/', $node->nodeValue, $m)){
$charset = $m[1];
break;
}
continue;
}
}
// 検出されたcharsetがUTF-8じゃなかったら
if($charset !== '' && !preg_match('/^utf\-?8$/i', $charset)){
// 文字コード変換し直して
$htmlEncoded = mb_convert_encoding($html, 'HTML-ENTITIES', $charset);
// DOMも構築し直す
$doc = new DOMDocument();
@$doc->loadHTML($htmlEncoded);
}
// title取得
$elements = $doc->getElementsByTagName("title");
for($i = 0; $i < $elements->length; $i++){
$e = $elements->item($i);
return $e->textContent;
}
// titleが見つからなかった場合
return false;
}
// -- -- 実験コード -- -- //
// x-sjis の例
$body = file_get_contents("http://abehiroshi.la.coocan.jp/");
$title = html2title($body);
echo "title = $title\n";
// euc-jp の例
$body = file_get_contents("http://d.hatena.ne.jp/");
$title = html2title($body);
echo "title = $title\n";
// Shift_JIS の例
$body = file_get_contents("http://www.tohoho-web.com/www.htm");
$title = html2title($body);
echo "title = $title\n";
// UTF-8 の例
$body = file_get_contents("http://qiita.com/");
$title = html2title($body);
echo "title = $title\n";
title = 阿部寛のホームページ
title = はてなダイアリー - 写真・画像・動画付き日記を無料で
title = とほほのWWW入門
title = Qiita - プログラマの技術情報共有サービス
はてなダイアリーがいまだに euc-jp だったというのが意外。
関連
おわり
おそらくこれまでに何千人もが同じようなコード書いてるような気がするわけで、
DRY原則に真っ向から立ち向かってしまっている感なんだけど、
良いサンプルが見つからなかったので自分で作ってしまった。
もっとスマートな(というかデファクトでかつ安心できる)方法があれば知りたいです。。。
Author And Source
この問題について(阿部寛のホームページをPHPでDOMる), 我々は、より多くの情報をここで見つけました https://qiita.com/kobake@github/items/d66b5b858fbc38487e89著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .