tidyでHTMLのパースを実現したい - PHPプロ!Q&A掲示板

303

  • 100P

tidyでHTMLのパースを実現したい

質問日時 / 2007年1月4日 18:22    回答数 / 4件

Questioner:  jpnetratings  このエントリーをはてなブックマークに追加 

キーワード / tidy   

Googleなどで検索すると、HTMLのパースにtidy関数というものが使えると知りました。
http://www.php.net/manual/ja/ref.tidy.php

これを利用してHTMLのパース(例:HTMLの<title>タグ内の文字列を抜き出す、など)を実現したいのですが、そのやり方がPHPドキュメントに記載されておらず、困っております。もしご存知の方がいらっしゃったら、アドバイスお願いします。

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┗A01kazu_kunhttp://www.php.net/manual/ja/ref.tidy.php のペー
 ┗A01-1jpnetratingsご返信ありがとうございます。説明が不十分で申し訳ご
  ┗A01-1-1kazu_kun> tidyで整形してからsimple_xmlやDOMといったxml関数
   ┗A01-1-1-1jpnetratings> xpathのように各要素に直接アクセスはおそらくない

回答一覧

並び替え:

A01
answererkazu_kun [1月5日 17:52]

http://www.php.net/manual/ja/ref.tidy.php
のページのuser cntributed notesの上から4番目(patatraboum at nospam dot fr)がパースしている例と思われ。
とりあえず、コピペしてきて、いろいろいじってみてはいかが?

この意見に回答する

ツリーへ TOPへ

A01-1
replyerjpnetratings [1月6日 03:16]

ご返信ありがとうございます。説明が不十分で申し訳ございません。


WebサイトのSEO対策を調べるため、各HTMLをパースして<title>タグや<h1>タグの内容を自動的に取得して出力するツールを構築しております。そこで、tidyで整形してからsimple_xmlやDOMといったxml関数を使ってtitleタグやh1タグの内容を取得しております。

kazu_kunさんにいただいた情報を拝見しました。HTMLタグを再帰的に調べて出力するようです。次のサイトでも同様の方法を採用していました。
http://www.coggeshall.org/oss/tidy/

再帰処理をスクリプトに実装するとコードが複雑になるため、tidyでxpathのように各要素に直接アクセスして情報を取得できるかを調べているところです。もしご存知でしたら、教えていただけますと幸いです。

この意見に回答する

ツリーへ TOPへ

A01-1-1
replyerkazu_kun [1月9日 11:20]

> tidyで整形してからsimple_xmlやDOMといったxml関数を使ってtitleタグやh1タグの内容を取得しております。
私には、これ以上の方法を提示することはできません。

http://www.php.net/manual/ja/ref.tidy.php
は既に何度も見ていて、気づいていると思いますが、xpathのように各要素に直接アクセスはおそらくないです(私には見つけられませんでした)。
自前で、HTMLツリーを再帰的にたどって取得するしかないでしょう。きっと。

幸い、SimpleXMLはXPATHが使用できるようなので、
1.tidyでXHTMLに整形。
2.SimpleXMLで直接ノードを取得。

の方法(すなわち、現在の方法)がベストだとおもいます。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1
replyerjpnetratings [1月9日 12:56]

> 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)文字列に&nbspがあるとsimplexmlが読み込めないため、ereg_replace等で
  削除しておく(tidyのquote-nbspをfalseにしても動作しない場合がある)


少し長いですが、以下に私が作成したスクリプトを記載します。もし改善点などがあれば、ご指摘いただけると幸いです。

  1. <?php
  2. ###=============================================================
  3. ### config
  4. ###=============================================================
  5.  
  6. ### parseすべきタグのxpath(prefixは「x」で指定する)
  7. $tagXpath = array(
  8.   'title'            => "/x:html/x:head/x:title/text()",
  9.   'h1'               => "/x:html/x:body/x:h1/text()",
  10.   'meta-keywords'    => "/x:html/x:head/x:meta[@name='keywords']/attribute::content",
  11.   'meta-description' => "/x:html/x:head/x:meta[@name='description']/attribute::content"
  12. );
  13.  
  14. ### Tidyの設定
  15. $config = array(
  16.   'indent'         => false,
  17.   'output-xhtml'   => true,
  18.   'clean'          => true,
  19.   'quote-nbsp'     => false,
  20. );
  21.  
  22. ### xhtmlの名前空間
  23. $nsXhtml = 'http://www.w3.org/1999/xhtml';
  24.  
  25. ###=============================================================
  26. ### 処理開始
  27. ###=============================================================
  28.  
  29. ### 処理対象のURL
  30. $url = "http://www.yahoo.co.jp/";
  31.  
  32. ### HTML情報の取得&UTF-8に変換
  33. $html = file_get_contents($url);
  34. $codeList = array("Shift_JIS","EUC-JP","SJIS","UTF-8","JIS");
  35. $html = mb_convert_encoding($html,"UTF-8",mb_detect_encoding($html,$codeList));
  36.  
  37. ### Tidyオブジェクトの生成
  38. $tidy = new tidy;
  39. $tidy->parseString($html,$config,'utf8');
  40. $tidy->cleanRepair();
  41. $tidy = ereg_replace("&nbsp;"," ",$tidy);
  42.  
  43. ### simple_xmlのオブジェクトを生成
  44. $xmlObj = new SimpleXMLElement($tidy);
  45. $xmlObj->registerXPathNamespace('x',$nsXhtml);
  46.  
  47. ### 指定されたタグの情報を取得
  48. foreach($tagXpath as $xpathKey => $xpathDetail){
  49.   $resultArray = array();
  50.   print "$xpathKey:\t";
  51.   $nodeArray = $xmlObj->xpath($xpathDetail);
  52.   if(!empty($nodeArray[0])){
  53.     foreach($nodeArray as $oneNodeVal){
  54.       $resultArray[] = chop(ereg_replace("\n"," ",$oneNodeVal));
  55.     }
  56.     print join("<BR>",$resultArray);
  57.   }else{
  58.     print "empty";
  59.   }
  60.   print "\n";
  61. }
  62.  
  63. ### 終了
  64. exit;
  65. ?>

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
動的なURLを静的に見せる方法
 このエントリーをはてなブックマークに追加 
A
普通に考えて、mod_rewrite でしょうね。 http://www.nishishi.com/blog/2006/01/mod_rewrite_url.html...

>>続きを読む

GETのままでは検索エンジンのロボットが拾ってくれなかったためにSEO対策として有効だと言われていますね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)