誰でもスクレイピング!DOM要素を引っこ抜くSimple HTML Dom ITかあさん

ITかあさん

誰でもスクレイピング!DOM要素を引っこ抜くSimple HTML Dom


誰でもスクレイピング!DOM要素を引っこ抜くSimple HTML Dom

Linuxエンジニアの方と一緒に主催している勉強会で『スクレイピング』についてリクエストを頂いたことがきっかけで『WEBサイト上で表示されているテキストやリンクなどのDOM要素をスクレイピングで簡単に引っこ抜いてしまおう!』ということになりました。
人生初のスクレイピング体験となりましたが非常に簡単!ではいってみよ~

1分で分かるスクレイピング

そもそもスクレイピングとは

・ウェブサイトのデータを必要な部分だけ抽出して利用すること

DOM要素として必要な部分だけを抽出して、ほとんどの場合自分のデータベースに登録して実際には運用したりします。

スクレイピング注意点

・著作権問題

WEBサイトは著作権で守られています。許可無く勝手に人様のサイトから情報だけ抜き出して自分のサイト上に公開することは出来ません。この著作権の問題には十分注意してください。

スクレイピング便利クラス Simple HTML Dom

スクレイピングの方法はいくつか存在するのがですが、私はSimple HTML Domを好んで使っています。色々調べた結果、個人的にはこれが一番使い易いと思いました。
サイトからダウンロードし、simplehtmldom_1_5フォルダをスクレイピングを実行したいサーバーにアップして、simple_html_dom.phpを呼び出すだけで準備は完了します。

引っこ抜きの指定が実はCSSそっくり!だからWEBデザイナーにも!

簡単ですが、データの引っこ抜き方です。『ここを引っこ抜きたい!』という部分を指定します。

下記の赤字部分に注目。引っこ抜きたい(スクレイピングしたい)DOMの指定。

$html = file_get_html( ‘http://から始まるURLで指定’ );//何のURLからスクレイピングするか
foreach($html->find(‘a’) as $element)

id=”contents”の中のulを引っ張りたいなら

foreach( $html->find( ‘#content ul’ ) as $ul )

DOMの指定が#contentで、#を使えて入れ子にするあたりが全くCSSの指定と一緒なのでWEBデザイナーにも優しい設計です!

1分でスクレイピング実行!

ITかあさんのブログ内をスクレイピング実行して、どのように抜き出せるのか実際にやってみましょう。

例えば、ITかあさんのブログのトップページ中のリンク(hrefの中身)を引っ張るとしたらこうなります。

// simple_html_dom.phpファイルの読み込み
include_once('simplehtmldom_1_5/simple_html_dom.php');
//スクレイピングしたいURLを指定
$html = file_get_html( 'http://www.kaasan.info/' );
//リンク
foreach($html->find('a') as $element)
echo $element->href . '<br>';

これだけでは何のリンクなのか分かりません。引っ張るaタグの範囲を右カラムのリンクに絞ります。

// simple_html_dom.phpファイルの読み込み
include_once('simplehtmldom_1_5/simple_html_dom.php');
//スクレイピングしたいURLを指定
$html = file_get_html( 'http://www.kaasan.info/' );

//○○の中のある特定の要素もCSSと同じように指定できます。
foreach($html->find('#rightcol .category_list a') as $element)
echo $element->href . '<br>';
もちろん画像のみの抽出も可能でして
// simple_html_dom.phpファイルの読み込み
  include_once('simplehtmldom_1_5/simple_html_dom.php');
//スクレイピングしたいURLを指定
  $html = file_get_html( 'http://www.kaasan.info/' );
//画像URL保存用の空の配列を用意
  $src = array();
  //リンク
  foreach($html->find('img') as $key => $element){ 
  $src[$key] = $element->src;
  }

foreach($src as $img){
echo '<img src="'.$img.'">';
}

もっと細かく要素を指定したい場合はこちらが参考になります。

おまけ:Wordpress × Simple HTML Domでスクレイピング

スクレイピングしたDOMをforeachのループ中にINSERT文を実行すれば簡単に自分のwordpressに記事として登録することが出来ます。
以下はさくらvps設定マニュアルの投稿記事一覧を抽出してWordpressをインストールしたデータベースに、記事としてINSERTする方法です。

MDB2.phpは大手レンタルサーバーなら大抵インストールされているかと。(私mysql関数って使ったことないんですよ・・)

require_once 'MDB2.php';//ライブラリのロード
//DSN
  $db = "mysql://ユーザー名:パスワード@localhost/データベース名?charset=utf8";
//接続
  $mdb2 =& MDB2::factory($db);
//フェッチモード設定
  $mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC);
  
  // simple_html_dom.phpファイルの読み込み
  include_once('simple_html_dom.php');
  
  // UTF-8で処理 他の文字コード処理するかもしれないからdefineしておく。
  define("CHAR_SET","UTF-8");
  
  // 文字化け対策のおまじない的(?)なもの。
  mb_language("Japanese");
  
  $html = file_get_html( 'http://www.kaasan.info/archives/category/さくらvps設定マニュアル' );
//wordpress上の投稿日時
  $wordpress['date'] = '2012-02-12 10:00:00';
foreach( $html->find( '#content ul' ) as $ul )
  foreach( $ul->find( 'li' ) as $li )
  $mdb2->exec("INSERT INTO `wp_posts` (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) VALUES
  (1, '{$wordpress['date']}', '{$wordpress['date']}', '$li', 'test', '', 'publish', 'open', 'open', '', 'test', '', '', '{$wordpress['date']}', '{$wordpress['date']}', '', 0, 0, 'post', '', 0)");

サンプルは以上です。
どこをどのように引っ張るのか、アイディア次第でいろんなサイトやサービスがお手軽に作れそうですが、著作権などの問題には十分注意してください。