Re:Re:Re:tidyでHTMLのパースを実現したい
> xpathのように各要素に直接アクセスはおそらくないです(私には見つけられませんでした)。
ご説明ありがとうございます。やはり、直接アクセスは無理ですか・・・。
ご指摘の通り、simpleXMLを利用して取得します。なお、参考までにxpathを利用する際の注意点(私が苦労した点)は次の通りです。
1)DOMだとなぜか文字化けするので、simpleXMLを利用した
2)xpathの指定方法(次はmetaのキーワードの場合)
/x:html/x:head/x:meta[@name='keywords']/attribute::content
3)xhtmlでは名前空間が指定されているので、registerXPathNamespaceを実行し、
プレフィックス(上記では「x」)を指定する必要がある
4)例えばtitleタグが複数ある場合もあるので、nodeをforeachで出力する
5)文字列に があるとsimplexmlが読み込めないため、
ereg_replace等で
削除しておく(tidyのquote-nbspをfalseにしても動作しない場合がある)
少し長いですが、以下に私が作成したスクリプトを記載します。もし改善点などがあれば、ご指摘いただけると幸いです。
- <?php
-
- $tagXpath = array(
- 'title' => "/x:html/x:head/x:title/text()",
- 'h1' => "/x:html/x:body/x:h1/text()",
- 'meta-keywords' => "/x:html/x:head/x:meta[@name='keywords']/attribute::content",
- 'meta-description' => "/x:html/x:head/x:meta[@name='description']/attribute::content"
- );
-
- $config = array(
- 'indent' => false,
- 'output-xhtml' => true,
- 'clean' => true,
- 'quote-nbsp' => false,
- );
-
- $nsXhtml = 'http://www.w3.org/1999/xhtml';
-
-
- $url = "http://www.yahoo.co.jp/";
-
- $html = file_get_contents($url);
- $codeList = array("Shift_JIS","EUC-JP","SJIS","UTF-8","JIS");
- $html = mb_convert_encoding($html,"UTF-8",mb_detect_encoding($html,$codeList));
-
- $tidy = new tidy;
- $tidy->parseString($html,$config,'utf8');
- $tidy->cleanRepair();
- $tidy = ereg_replace(" "," ",$tidy);
-
- $xmlObj = new SimpleXMLElement($tidy);
- $xmlObj->registerXPathNamespace('x',$nsXhtml);
-
- foreach($tagXpath as $xpathKey => $xpathDetail){
- $resultArray = array();
- print "$xpathKey:\t";
- $nodeArray = $xmlObj->xpath($xpathDetail);
- if(!empty($nodeArray[0])){
- foreach($nodeArray as $oneNodeVal){
- $resultArray[] = chop(ereg_replace("\n"," ",$oneNodeVal));
- }
- print join("<BR>",$resultArray);
- }else{
- print "empty";
- }
- print "\n";
- }
-
- exit;
- ?>