1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  5. <meta name="keywords" content="php,tidy,スクレイピング,API,Webサービス" />
  6. <meta name="description" content="phpによるスクレイピング処理入門" />
  7. <title>phpによるスクレイピング処理入門:はてなブックマークの情報を取得</title>
  8. <link href="style.css" rel="stylesheet" type="text/css">
  9. </head>
  10. <?php
  11. define(INIT_URL "http://b.hatena.ne.jp/");
  12. // proxyを利用する場合は 1 / 利用しない場合は0
  13. $use_proxy 0;
  14. $proxy_host 'proxy.example.com';
  15. $proxy_port 8080;
  16. $no_proxy = array(
  17.     'localhost',        // localhost 
  18.     '127.0.0.0/8',      // loopback
  19. );
  20. include('proxy.php');
  21. function get_html($url){
  22.     $rdata http_request($url);
  23.     $data mb_convert_encoding($rdata['data'],"utf-8","auto");
  24.     return ($data);
  25. }
  26. function dump_nodes_title(tidyNode $node, &$urls NULL) {
  27.     $urls = (is_array($urls)) ? $urls : array();
  28.     if(isset($node->id)) {
  29.     // ここからが実際のスクレイピング処理と思ってよいでしょう。
  30.         // $node->id が Aタグだったら
  31.         if($node->id == TIDY_TAG_A) {
  32.             // $node->id に class属性がセットされていれば
  33.             if (isset($node->attribute['class'])){
  34.                 // $node->id の class属性値がbookmarkだったら
  35.                 if (stristr ($node->attribute['class'] ,"bookmark") !==FALSE){
  36.                     // <a href="http://ryouchi.seesaa.net/">りょーち</a>
  37.                     // の場合、「りょーち」の文字を取得するには、
  38.                     // $node->child[0]->value
  39.                     // http://ryouchi.seesaa.net/ の文字を取得するには、
  40.                     // $node->attribute['href']
  41.                     // $urls にtitle,linkの連想配列として、タイトルとリンクを格納
  42.                     $urls[] = array("title" => $node->child[0]->value ,"link" =>$node->attribute['href']);
  43.                 }
  44.             }
  45.         }
  46.     // ここまでが実際のスクレイピング処理と思ってよいでしょう。
  47.     }
  48.     // 更に子供のノードが存在すれば、再帰的にdump_nodes_title()を繰り返す
  49.     if($node->hasChildren()) {
  50.         foreach($node->child as $c) {
  51.             dump_nodes_title($c$urls);
  52.         }
  53.     }
  54.     // 連想配列をリターン
  55.     return $urls;
  56. }
  57. echo '<a href="'.INIT_URL.'">'.INIT_URL.'</a><br />';
  58. // INIT_URLで指定されたHTMLファイルを取得して$dataに格納
  59. $data get_html(INIT_URL);
  60. // Tidy関数で整形する際のおまじない。
  61. $config = array('indent' => TRUE,
  62.                 'output-xhtml' => TRUE,
  63.                 'wrap' => 200);
  64. // 取得したHTMLファイルの内容をUTF-8の文字コードで$configで
  65. // 指定した設定で、tidyオブジェクトを作成
  66. $tidy tidy_parse_string($data$config'UTF8');
  67. // cleanRepairで整形
  68. $tidy->cleanRepair();
  69. // 作成したtidyオブジェクトのbody要素の内容をdump_nodes_title()に渡す
  70. // $urlsにはtitle,linkのペアの配列が格納されている。
  71. $urls dump_nodes_title($tidy->body());
  72. echo '<div align="left"><ul>';
  73. // 取得されたurlsをforeachで回す
  74. foreach ($urls as $item){
  75.     // $item['link'] / $item['title'] を出力
  76.     echo '<li><a href="'.$item['link'].'" target="_blank">'.$item['title'].'</a>';
  77. }
  78. echo '</ul></div>';
  79. ?>
  80. </body>
  81. </html>