DOMDocument::loadHTML が meta の charset を解釈してくれない問題と対策
概要
HTMLソースに「<meta charset="…" />」が指定してあっても DOMDocument::loadHTML は文字コード解釈に失敗することがあるよ、というお話。
実験対象
Qiita のトップページ。「<meta charset="UTF-8">」という記述があり、DOMDocument はこれを解釈できそうに見えます。
<!DOCTYPE html>
<html xmlns:og="http://ogp.me/ns#">
<head><script type="text/javascript">var NREUMQ=NREUMQ||[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);</script>
<meta charset="UTF-8">
<title>Qiita [キータ] - プログラマの技術情報共有サービス</title>
…
サンプルコード
dom_charset.php
<?php
$url = "http://qiita.com/";
$body = file_get_contents($url);
$dom = new DOMDocument();
@$dom->loadHTML($body);
$title = $dom->getElementsByTagName('title')->item(0)->textContent;
print "$title\n";
サンプル実行結果
$ php dom_charset.php
Qiita [ãã¼ã¿] - ããã°ã©ãã®æè¡æå ±å±æãµã¼ãã¹
<?php
$url = "http://qiita.com/";
$body = file_get_contents($url);
$dom = new DOMDocument();
@$dom->loadHTML($body);
$title = $dom->getElementsByTagName('title')->item(0)->textContent;
print "$title\n";
$ php dom_charset.php
Qiita [ãã¼ã¿] - ããã°ã©ãã®æè¡æå ±å±æãµã¼ãã¹
文字化けだ!/(^o^)\
原因・対策
原因
環境によるかもしれないが、少なくとも自分の環境 (PHP 5.3.3) では、
どうやら DOMDocument::loadHTML は「<meta charset=…」ではなく「<meta http-equiv=…」のタグ情報を元に文字コードを判定しているらしい。
<!-- これがあっても意味がない -->
<meta charset="UTF-8" />
<!-- こっちを解釈する -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
コード修正
全サイトの管理者に「<meta http-equiv=…」のタグを埋め込んでもらうことを期待するのは現実的ではないので、
取得したHTMLソースを置換してやると良い。(今回はあくまでも対症療法として単純な置換で済ませます)
<?php
$url = "http://qiita.com/";
$body = file_get_contents($url);
$body = str_replace('<meta charset="UTF-8">', '<meta charset="UTF-8"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">', $body);
$dom = new DOMDocument();
@$dom->loadHTML($body);
$title = $dom->getElementsByTagName('title')->item(0)->textContent;
print "$title\n";
実行結果
$ php dom_charset2.php
Qiita [キータ] - プログラマの技術情報共有サービス
直った!\(^o^)/
Author And Source
この問題について(DOMDocument::loadHTML が meta の charset を解釈してくれない問題と対策), 我々は、より多くの情報をここで見つけました https://qiita.com/kobake@github/items/3c5d09f9584a8786339d著者帰属:元の著者の情報は、元の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 .