« フックでプル&バックアップを自動化 | メイン | VirtualBox5.2 + Extension Pack + CentOS 7 »

php

PHP で HTML をスクレイピング

●PHP SimpleXMLElement:読み出しやすい、追加のみ
●PHP DOMDocument:追加・削除できる
●PHP DOMXPath:domを柔軟にアクセス

というわけで 最終的に任意のノードを変更する為、PHP DOMDocument で HTML を DOM としてパース(スクレイピング)。
<?php
$html=<<<EOT
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="chapter" name="1章 ようこそ">
      <h1>1-1節 remix.asia</h1>
      <div class="paragraph">
        文章
      </div><!-- paragraph -->
    </div><!-- chapter -->
    <div class="chapter" name="2章 言語"><!-- 章の数だけ繰り返し -->
      <h1>2-1節 HTML</h1>
      <div class="paragraph">
        HyperText Markup Language...
      </div><!-- paragraph -->
      <h1>2-2節 PHP</h1>
      <div class="paragraph"><!-- 節の数だけ繰り返し -->
        Hypertext Preprocessor
      </div><!-- paragraph -->
    </div><!-- chapter -->
  </body>
</html>
EOT;
$dom = new DOMDocument( '1.0', 'UTF-8' );
if( false == $dom->loadHTML( $html ) ){
  return;//error
}
の前提で...▼
XPathを使わないと タグの種類に制限を受ける。
$domNodeList = $dom->getElementsByTagName( 'div' );
echo '<hr />' . $domNodeList->length . '個';
foreach( $domNodeList as $v ){
  echo '<br />' . $v->nodeValue;
}
   ▼
5個
1-1節 remix.asia 文章 
文章 
2-1節 HTML HyperText Markup Language... 2-2節 PHP Hypertext Preprocessor 
HyperText Markup Language... 
Hypertext Preprocessor
$domNodeList = $dom->getElementsByTagName( 'h1' );
echo '<hr />' . $domNodeList->length . '個';
foreach( $domNodeList as $v ){
  echo '<br />' . $v->nodeValue;
}
   ▼
3個
1-1節 remix.asia
2-1節 HTML
2-2節 PHP
XPathを使ってclassで絞り込む。
$domxpath = new DOMXPath( $dom );
$domNodeList = $domxpath->query( '//div[@class="chapter"]' );

echo '<hr />' . $domNodeList->length . '個';
foreach( $domNodeList as $v ){
  echo '<br />' . $v->getAttribute('name');
}
   ▼
2個
1章 ようこそ
2章 言語
echo '<hr />';
foreach( $domNodeList as $v ){
  echo '<br />' . $v->nodeValue;
}
   ▼
1-1節 remix.asia 文章 
2-1節 HTML HyperText Markup Language... 2-2節 PHP Hypertext Preprocessor
上記を踏まえ、入れ子構造のタグとしてループさせる。
echo '<hr />';
foreach( $domNodeList as $v ){
  echo '<br />*' . $v->getAttribute('name');
  $domNodeListChild = $domxpath->query( './/h1', $v );//★
  foreach( $domNodeListChild as $vc ){
    echo '<br />**' . $vc->nodeValue;
  }
}
   ▼
*1章 ようこそ
**1-1節 remix.asia
*2章 言語
**2-1節 HTML
**2-2節 PHP
次回は、編集。

トラックバック

このエントリーのトラックバックURL:
http://www.remix.asia/cgi/mt/mt-tb.cgi/7687

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)