①などの文字が含まれるHTMLページをDOMDocumentのloadHTML()でDOMにしようとしたところ、以下のようなエラーが発生してしまいました。
DOMDocument::loadHTML(): input conversion failed due to input error, bytes 0x81 0xAE 0xE3 0x81
やりたいことは、ShiftJISのページをUTF-8にして、SimpleXMLElementに変換することです。
[PHP] DOMDocument#loadHTML()で、特定の文字が含まれていると正しいDOMを作ってくれない を拝読することで解決しました。
原因1
根本的な原因は、機種依存文字を利用したことです。しかし、①などはUTF-8にも定義されているのでエンコードの指定が合っていれば変換できます。
①などのWindowsの機種依存文字まで含めたエンコードは、 CP932 や sjis_win などと呼び、ShiftJISとは別に指定することができます。
解決策
$urlに読み込みたいWebページのURLが入っているとして、以下のようにして変換します。
<?php // URLからHTMLの取得 $html = file_get_contents($url); // windows用のSJISからUTF8に変換 $html = mb_convert_encoding($html, "UTF-8", "SJIS-win"); // HTMLのcharsetを変換に合わせて修正する $html = str_replace("charset=shift_jis", "charset=utf-8", $html); // HTMLをDOMに変換 $domDocument = new domDocument(); $domDocument->loadHTML($html); // XMLに変換 $xmlstr = $domDocument->saveXML(); // SimpleXMLElementに読み込み $xml = simplexml_load_string($xmlstr);
原因2
&記号が本文中などにあるとエラーになります。 & でエスケープが必要です。