PHP の Dom操作で、特定のタグの中のHTMLを抜き出す
ある案件で、リモートのHTMLをインクルードして出力するという要件があった。
まあなにも考えないで書くと
$file = file_get_contents($url);
こんな感じでリモートのHTMLは取得できる。
だがしかし、これだとメタタグなども取得してしまうし、HTMLやHEAD、BODYタグもでてしまう、いささか不味い。
ということで、BODYの中のHTMLだけを抜き出す必要がある。
それはこんな感じでできる
$file = file_get_contents($url); preg_match( "/<body>(.*?)<\/body>/i", $file, $tmp) file = $tmp[0];
…こんなダメなコードは書いたらダメですね。
うごくかわかったもんじゃないです。
正規表現で切り貼りするのが許されるのは(略
ってことでDOMでやります。
$opts = array( 'http'=>array( 'method'=>"GET", 'header'=>"Accept-language: ja\r\n" ) ); $context = stream_context_create($opts); $file = file_get_contents($url, false, $context); $file = mb_convert_encoding($file, 'UTF-8', mb_detect_encoding($file)); libxml_use_internal_errors(TRUE); $document = new DOMDocument(); $document->recover = 1; $document->loadHTML($file); $body = $document->getElementsByTagName('body'); $childelms = $body->item(0)->childNodes; for($i=0; $childelms->length > $i; $i++) { $rtn .= $document->saveXML($childelms->item($i)); } $rtn = mb_convert_encoding($rtn, $charset,'UTF-8'); libxml_use_internal_errors(FALSE); return $rtn;
ばっちりですね。
コードは長いですけど、正規表現のマッチミスに不安になったり、文字コードのことを心配する必要がほぼ有りません。
しっかし、
for($i=0; $childelms->length > $i; $i++) { $rtn .= $document->saveXML($childelms->item($i)); }
ってまったく直感的じゃないですよね…。
for($childelms as $elm) { $rtn .= $elm->saveXML(); }
ってやりたいですよね…。