X
pm studio world wide news pj club
pm studio world wide news pj club
news, tech, music, film, sports, cg, translation, photo uploader
  • 2015-12-24
  • PJ Club
  • CreatIng Original RSS News Feed with “simple_html_dom.php” / PHP simple_html_domで、HTMLからオリジナルRSS Newsfeed作成
  • 前回、XMLを使ってニュースフィードを作成する方法をご紹介しましたが、すべてのWebサイトがRSSを用意しているわけではありません。そこで、XMLデータがない場合、HTMLから作成します。
    しかし、情報を知りたいサイトのHTML内容は千差万別です。HTMLデータをオリジナルでパース (Parse)するのは大変です。
    PHPにはHTML内の要素、例えば、div、img、href等を抽出する便利なライブラリー「simple_html_dom」があります。
    「simple_html_dom」は、JavaScriptのjQueryによく似た記述で、HTMLをパース出来るツールです。
    ダウンロードはSourceforgeから出来ます。

    ダウンロードはここをクリック。

    マニュアルは、http://simplehtmldom.sourceforge.net/manual.htmにあります。

    では、さっそく使ってみましょう。
    まず、ダウンロードしたファイルの中に「simple_html_dom.php」がありますので、そのファイルをサーバーにアップし呼び出します。
    アップするディレクトリーはどこでもOKですが、今回はニュースフィードと同じディレクトリーに置いてあるとします。
    呼び出すには、下記のように記述します。

    <?php
         require_once("simple_html_dom.php");
    ?>

    対象となるHTMLデータを見てみます。デモでは、音楽サイトのi-Dから必要な要素を抽出してみます。
    URLは「http://i-d.vice.com/en_us/topic/music」です。
    ニュースフィードで必要なのは、記事の日付、タイトル、リンク先、記事の詳細、記事に関連する画像です。
    このサイトでは、下記の要素article tag<article class="item">がメニューとしてブロックになっており、繰り返されています。

    <body>
         <article class="item">
                  <div class="image-container">
                      <a href="リンクURL">
                                <div class="vmp-srcN-container parsed fade-in hires-loaded loaded">
                                        <img class="srcN fade-in parsed hires" src="画像URL">
                                </div>
                                <noscript><img class="srcN fade-in parsed hires" src="画像URL"></noscript>
                      </a>
                  </div>
                  <div class="article-information">
                      <div class="item-meta-information">
                                <div class="item-topic">
                                        <a href="カテゴリートップURL">カテゴリー</a>
                                </div>
                                <span class="author">筆者</span>
                                <span class="publish-time">日付</span>
                      </div>
                      <div class="article-content">
                                <p class="item-title"><a href="リンクURL">タイトル</a></p>
                                <p class="item-description">記事詳細</p>
                                <p class="item-cta"><a href="リンクURL">Read More</a></p>
                      </div>
                  </div>
         </article>
    </body>

    では、まずこのHTMLデータを読み込みます。HTMLデータを読み込むには、file_get_html("HTMLのURL")関数を使います。

    <?php
         require_once("simple_html_dom.php");
         $htmlURL="http://i-d.vice.com/en_us/topic/music";
         $html = file_get_html($htmlURL);
    ?>
  • これで全部のHTMLデータを読み込めました。対象の要素を探し出しましょう。探し出すにはfind(要素名)関数を使用します。対象要素は<article class="item">ですから、article tagとclass設定のitemです。
    find()関数の対象要素の書き方は、jQueryと同じで「article.item」とすることが出来ます。もしclass設定ではなくid設定であれば「article#item」とします。idはお馴染の「#」ですね。
    スクリプトは下記のように記述し、要素を取得します。取得したデータは配列になっています。

    $html->find('article.item');

    続いて、すべての<article class="item">を取得したいので、繰り返しの関数foreach()を使います。

    foreach($html->find(’article.item') as $article) {
         抽出する要素のスクリプト
    }

    日付を取得します。日付はspan tagでclass設定がpublish-timeとなっていますから、下記のように記述します。plaintextとしているのは、タグ等を含まないテキストをそのまま抽出するためです。

    $date=$articleTop->find('span.publish-time',0)->plaintext;

    次にタイトルを取得します。タイトルはp tag、class設定がitem-titleとなっていますので、下記のように記述します。

    $title=$article->find('p.item-title',0)->plaintext;

    リンク先を取得します。リンクは<p class="item-cta">にあり、p tagとclass設定がされています。その中のa tagを抽出しますから、下記のように記述します。ただし、今回はリンク先ですので、plaintextではなくhrefとします。ここの「p.item-cta a」はjQueryと似た書き方です。

    $link=$article->find('p.item-cta a',0)->href;

    続いて、記事の詳細を取得します。詳細は<p class="item-description">となっています。p tagとclass設定がされていますので、下記のように記述します。

    $description=$article->find('p.item-description',0)->plaintext;

    最後に、画像データを抽出します。画像はimg tagですから、下記のように記述します。ここは、画像表示のためのURLが必要となりますので、srcとします。

    $article->find('div.image-container',0)->src;

    まとめると、

    <?php
         require_once("simple_html_dom.php");
         $htmlURL="http://i-d.vice.com/en_us/topic/music";
         $html = file_get_html($htmlURL);

         foreach($html->find('article.item') as $article) {
                  $date=$articleTop->find('span.publish-time',0)->plaintext;
                  $title=$article->find('p.item-title',0)->plaintext;
                  $link=$article->find('p.item-cta a',0)->href;
                  $description=$article->find('p.item-description',0)->plaintext;
                  $imgURL=$article->find('div.image-container',0)->src;
         }
    ?>

    となります。これでは、まだHTMLで出力されませんので、下記のHTML tagを追加します。

    $htmlDATA .="
                      <div>$date</div>
                      <div><a href='$link'>$title</a></div>
                      <div>$title</div>
                      <div>$description</div>
                      <div><<img src='$imgURL'><div>
                      ";

    .=は、「=」以降を追加していきます。つまり取得した<article class="item">数だけ、HTML tagを生成しています。

    まとめると、

    <?php
         require_once("simple_html_dom.php");
         $htmlURL="http://i-d.vice.com/en_us/topic/music";
         $html = file_get_html($htmlURL);

         foreach($html->find('article.item') as $article) {
                  $date=$articleTop->find('span.publish-time',0)->plaintext;
                  $title=$article->find('p.item-title',0)->plaintext;
                  $link=$article->find('p.item-cta a',0)->href;
                  $description=$article->find('p.item-description',0)->plaintext;
                  $imgURL=$article->find('div.image-container',0)->src;
                  $htmlDATA .="
                                      <div>$date</div>
                                      <div><a href='$link'>$title</a></div>
                                      <div>$title</div>
                                      <div>$description</div>
                                      <div><img src='$imgURL'></div>
                                      ";
         }
         echo $htmlDATA;
    ?>

    simple_html_domのマニュアルによると、メモリーヒープについて触れられています。頻繁にHTMLデータを読み込むとPHPのメモリーが消費され、エラーになるようです。
    そこで、読み終わったら、メモリーを解放する必要があります。解放するには下記の記述をします。

    $html->clear();
    unset($html);

    まとめると、

    <?php
         require_once("simple_html_dom.php");
         $htmlURL="http://i-d.vice.com/en_us/topic/music";
         $html = file_get_html($htmlURL);

         foreach($html->find('article.item’) as $article) {
                  $date=$articleTop->find('span.publish-time',0)->plaintext;
                  $title=$article->find('p.item-title',0)->plaintext;
                  $link=$article->find('p.item-cta a',0)->href;
                  $description=$article->find('p.item-description',0)->plaintext;
                  $imgURL=$article->find('div.image-container',0)->src;
                  $htmlDATA .="
                                      <div>$date</div>
                                      <div><a href='$link'>$title</a></div>
                                      <div>$title</div>
                                      <div>$description</div>
                                      <div><img src='$imgURL'></div>
                                      ";
         }
         $html->clear();
         unset($html);
         echo $htmlDATA;
    ?>
  • このスクリプトに、ファイル名 (例. html_data.php)を付け、サーバーにアップすると、HTMLとして出力されます。
    さて、これでうまくいったと思ったのですが、このサンプルでは画像データがうまく抽出されていません。ブランク用のpngファイルが抽出されてしまっています。どうもimg tag内にデバイス毎に大きさの違う画像データを記述し、スクリプトで表示処理しているためのようです。そこで、img tagが同様に書かれたnoscript tagから取得します。ただし、こちらは、予めプレインテキストになっていますので、srcを記述する必要はありません。

    $imgURL=$article->find('noscript img',0);

    まとめると、

    <?php
         require_once("simple_html_dom.php");
         $htmlURL="http://i-d.vice.com/en_us/topic/music";
         $html = file_get_html($htmlURL);

         foreach($html->find('article.item') as $article) {
                  $date=$articleTop->find('span.publish-time',0)->plaintext;
                  $title=$article->find('p.item-title',0)->plaintext;
                  $link=$article->find('p.item-cta a',0)->href;
                  $description=$article->find('p.item-description',0)->plaintext;
                  $imgURL=$article->find('noscript img',0);
                  $htmlDATA .="
                                      <div>$date</div>
                                      <div><a href='$link'>$title</a></div>
                                      <div>$title</div>
                                      <div>$description</div>
                                      <div><img src='$imgURL'></div>
                                      ";
         }
         $html->clear();
         unset($html);
         echo $htmlDATA;
    ?>

    これで、HTMLからニュースフィードを作成できました。

    サンプルはここをクリック

    simple_html_domは、HTMLをパースするのにとても便利です。公式サイトで詳細が説明されていますので、ご覧になると分かりやすいと思います。
  • source : pm studio world wide news
Recent Post
Latest News
Billboard Hot 100
Top 10
  • No.4
    "Psycho"
  • No.5
    "Meant To Be"
  • No.6
    "The Middle"
  • No.7
    "Look Alive"
BBC Radio 1 Singles 40
Top 10
  • Editor: Toshio Maeoka / pm studio
    pm studio world wide news © 2014-2018 . All Rights Reserved
^
to TOP