蛇田.jp ~開発ブログ~

2009 年 1 月 20 日

Webスクレイピング

カテゴリー: 未分類 — タグ: , , — admin @ 11:24 PM

Webスクレイピングとは
はてなでは

英語で”scrape”とは「削ること」。
特に、ウェブサイトのデータを必要な部分だけ抽出して利用すること。

なんて紹介されています。
個人でホームページを作る場合に欲しくてたまらなくなるものが、「データ」ですね。
つまり、Webスクレイピングとは
欲しいデータを掲載しているサイトそのものをプログラムでダウンロードし、欲しいデータだけを取得し加工しましょうというものです。
それ程難しいものではなく、PHPであれば簡単に実行できてしまいます。
プログラムの大まかな流れは

  1. HTTP通信でデータ(HTMLページ)を取得(ダウンロード)
  2. 取得したHTMLを変数として扱い「正規表現」で欲しいデータだけを取得
  3. データを加工し、(可能であれば)HTMLとしてジェネレートし出力する

といった流れになります。
可能であればHTMLとしてジェネレートするというのには理由があります。
自サイトにアクセスが発生する際にいちいち、PHPによって他のサイトまでHTTPの通信を行うと、非常にコストがかかりますし、他のサイトさんにも迷惑をかけます。
(Webスクレイピングをしている時点で迷惑をかけている感はありますが・・・)
ですので、可能であればcronでキックされるジェネレート方式にした方がいいかと思います。
今回は、Webスクレイピングで簡単にいろいろなデータを取得したいと思い、クラスを作成してみました。
スクレイピングするために以下のようなクラスを作ってみました。

<?php
// WebScrapingをするツール
Class WebScraping{
function __construct($sURL){
// ターゲットURL
$this->sURL = $sURL;
// Get
ini_set('user_agent', 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
$this->sSrc = @file_get_contents($sURL);
$this->aHtml = $this->sSrc;
}
////////////////////////////////////////////////
// 正規表現をセットし
// 切り取ったデータを返す
// 2: 正規表現分なし = 1
//		正規表現分あり = 0
////////////////////////////////////////////////
function RegexAllGet($regex,$sReturn){
preg_match_all("/$regex/s",$this->sSrc,$this->aHtml);
if($sReturn){
$this->aHtml = $this->aHtml[1];
}else{
$this->aHtml = $this->aHtml[0];
}
return $this->aHtml;
}
////////////////////////////////////////////////
// もらった配列をメンバ変数としてセットしなおす
////////////////////////////////////////////////
function SetHtml($aHtml){
$this->aHtml = $aHtml;
}
////////////////////////////////////////////////
// 1: 正規表現
// 2: 正規表現分なし = 1
//		正規表現分あり = 0
// 3: オプション
//		指定があった場合にはその配列を正規表現で切り刻む
////////////////////////////////////////////////
function RegexGet($regex,$sReturn,$aHtml = NULL){
if(!isset($aHtml)){
$aHtml = $this->aHtml;
}
if(is_array($aHtml)){
$nRow = count($aHtml);
$i = 0;
$aResult = array();
while($nRow > $i){
preg_match("/$regex/s",$aHtml[$i],$aResult);
$aResult_0[$i] = $aResult[0];
$aResult_1[$i] = $aResult[1];
$i++;
}
if($sReturn){
$this->aHtml = $aResult_1;
}else{
$this->aHtml = $aResult_0;
}
return $this->aHtml;
}else{
preg_match("/$regex/s",$aHtml,$aResult);
if(empty($aResult)){
return 1;
}
if($sReturn){
$this->aHtml = $aResult[1];
}else{
$this->aHtml = $aResult[0];
}
return $this->aHtml;
}
}
}
?>

使い方はこんな感じ

  <?php
require_once('WebScraping.php');
$sURL = 'http://dailynews.yahoo.co.jp/fc/';
$oWS = new WebScraping($sURL);
$regex = '
    (.*?)
'; $aHtml = $oWS->RegexAllGet($regex,1); // $aHtmlにヤフートピックスの見出しが配列として入ります。 ?>

ただ、ここで注意するのはHTTPでファイルを取得しに行く際にPHPの標準関数である

file_get_contents

を使用しています。
これはセキュリティ上サーバによっては許可されていない場合もあります。
php.iniファイルをいじることができるのであれば、

allow_url_fopen = On

とします。
当サイトにおいては、とあるサイトからデータを取得する際には上で紹介したようなclassを用いてページをジェネレートしています。
例えば、トップページで言えば

  • ニュース記事の見出し
  • 仙台放送女子アナブログ
  • イオン ショップ情報
  • ワーナー・マイカル・シネマズ 新石巻

等の情報を定期的にクロールをして取得しています。
やり方はいろいろあると思うのですが、機会があったらチャレンジしてみてください!

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

1件のコメント »

  1. [...] これだけ。 詳しくはWebスクレイピングを参照してください。 [...]

    ピンバック by 石巻ニュース « 164 Tech Blog — 2009 年 3 月 3 日 @ 12:57 AM

このコメント欄の RSS フィード トラックバック URL

コメントをどうぞ