スクレイピングするPHPプログラムの作り方【Simple html dom prser】
ウェブサイトから必要な情報を収集できるスクレイピングですが、最近はjavascriptやPythonでもとても簡単にできるようになってきました。
「PHP」というプログラミング言語はお仕事にしているプロ級の方から、ブロガーやアフィリエイターの方々まで幅広く学習・実践できるプログラムです。
そんな初心者でも比較的簡単に使うことができるPHPで「Simple HTML DOM Parser」を使ったウェブスクレイピングプログラムの作り方・使い方をご紹介します。
Webスクレイピングとは
あるウェブサイトに自分の欲しい情報があるとします。
そのサイトにはRSSやAPIなどが用意されておらず、その情報を得るためには毎日もしくは1ページずつアクセスする必要があります。
これはとても面倒な作業になりますよね。
そのような作業を機械(プログラム)が行うことをWebスクレイピングといいます。
「クローラー」や「クローリング」と読んだりもします。
取得した情報は自分の欲しい形で加工・整形して資料にまとめたり、自分のサイトで活用したりできます。
PHP Simple HTML DOM Parser
簡単に説明します。
・PHPのライブラリでrequireするだけで使える
・HTMLの文字、要素 (element)、属性 (attribute)を指定すると取得できる
・取得したいページのHTML解析スキルが必要となる
ウェブサイトの構成が複雑であれば、少し頭を使う必要があります。
個人の方がこだわって作られたサイトや、ひと昔前のサイト等はHTMLが複雑なこともあるので難しいかもしれません。
simple_html_domの使い方
良くわかる使い方のページはコチラです。
PHP Simple HTML DOM Parserの使用方法 - Webスクレイピング ライブラリ
まずは、ライブラリをrequireします。
<?php require_once('simple_html_dom.php');
<?php //Vendor/simple_html_dom.phpを読み込む(CakePHP2の場合) App::import('Vendor', 'simple_html_dom');
simple_html_domが使えるようになるので、対象(読み込みたい)ページのURLを指定してHTMLを読み込みます。
なお、下記file_get_htmlはURLを指定してウェブページ(自サーバー内のHTMLファイルもOK)を読み込みますが、他にstr_get_html(文字列から)を使うことも可能です。
<?php //対象ページのURL $url = "http://soudan.hatenablog.jp"; //文字化け対策 mb_language("Japanese"); //ウェブページのデータを読み込み $html = file_get_html($url);
$dataがnullでなければ、HTMLデータを取得できています。
あとはfindを使い、欲しいデータだけを取り出していきます。
スクレイピングプログラムの作り方
●記事一覧ページから詳細ページのURLを抜き出す方法
記事一覧の各記事のクラスがpostの場合、その領域内のリンク(各記事詳細ページURL)を取得する
【ネストのパターン】
<?php $list = array(); foreach( $html->find( 'div.post' ) as $element ) { $list[] = array( 'title' => $element->find( 'a',0 )->plaintext, 'url' => $element->find( 'a',0 )->href, ); } var_dump($list);
こうするとページ名とURLの一覧($list)を取得することが可能です。
ちなみに、次ページへ送りたいときはあらかじめページ指定のURLを解析する必要があります。
http;//---.com/page/2
http;//---.com/page/3
http;//---.com/page/4
や
http;//---.com/?page=2
http;//---.com/?page=3
http;//---.com/?page=4
といったパターンが多いです。
とりあえず20ページ分スクレイピングできるサンプルプログラムはこんな感じです。
<?php //ページングURL $base_url = "http://soudan.hatenablog.jp/pgae/%s"; for ($page=1; $page<=20; $page++) { //URLにページをセットする $url = sprintf($base_url, $page); …ウェブページを読み込み解析する…
whileを使ってページャーエリアにリンクがあるかどうかをfindで調べるのがベストな方法かもしれません。
→ 個別で解析をご希望の方はご相談ください
●記事詳細ページからデータを抜き出す方法
・固有のURLを取得:ヘッダーのmeta relのshortlink
<?php $shortlink_elem = $html->find('head link[rel=shortlink]',0); $shortlink = $shortlink_elem->href
・記事タイトルを取得:div#mainの中のdiv.entry-contentの中の最初のh1
<?php $title_elem = $html->find('div#main div.entry-content h1', 0); $title = $title_elem->plaintext;
・複数あるタグを取得:div.tag領域のリンクのテキストを1つずつ取得し配列にセット
<?php foreach( $html->find('div#main div.tag a') as $tag ) { $tags[] = $tag->plaintext; }
スクレイピングデータの加工の方法
取得したデータは必要な箇所だけ抜き出してデータベースへ保存したり、テキストファイルにまとめたりすることが多いと思います。
よくあるパターンとその時使いそうなPHP関数を上げておきます。
※下記サンプルは取得した文字列データに対して行う作業です。
・正規表現で記事から画像パスだけ抜き出す
<?php preg_match_all('/<img(?:.*?)src=[\"\'](.*?)[\"\'](?:.*?)>/e', $description, $img_path_list);
・URLの?以降を削除する
(対象の文字より後ろの文字を削除するときに使う)
<?php $url2= mb_substr($url,0,strpos($url, '?'));
様々なデータ取得と解析、加工のサンプルをあげていきました。
サイトによって作りは異なるため、一筋縄ではいかないこともあります。
「どうしてもスクレイピングが上手くいかない」、「自分では作れないので0から作って欲しい」等のリクエストはココナラからお問い合わせください。
WordPressと連携し記事に投稿することも可能です。