石巻のニュースを紹介をフィードして表示しているのが
http://hebita.jp/news/
になります。
技術的には簡単なことしかしていなくて、
をクロールして記事を集めているだけです。
記事を集めたいページを解析してスクレイピングしています。
具体例を少しだけ。
石巻かほくのメインフレーム を正規表現で切り刻む方法
とりあえず、このファイルの取得の仕方ですが、PHPであれば簡単にできます。
<php?
// 目的URL
$URL = 'http://www.sanriku-kahoku.com/main.html';
// file_get_contents関数の仕様
$HTML = file_get_contents($url);
?>
これだけ。
詳しくはWebスクレイピング を参照してください。
これでソースが取得できます。
まず、記事のリンク先のURLを取得するために見出し部分を切り刻みます。
ターゲットとするHTMLは
<TABLE border="0" cellspacing="5" cellpadding="0">
<TR>
<TD width="286" height="681">
・
(見出しが入っています)
・
</TD>
</TR>
</TABLE>
といった感じにします。
tableで組んだ中にtableを入れ子でいれているようです。
どうやら石巻かほくさんはheight=”681″の記述部分を手動で変更しているらしく、自動でクロールしているクローラーがときどきパースでエラーを起こしていました。
まず、このTDタグの中身を取得します。
PHPだとpreg_match関数を使用し以下のように書けば取得できます。
preg_match("/(.+?)<\/TD>/s", $HTML, $Kiji);
$HTML ソース
$Kiji[0] TD入りの切り刻んだ記事が入ります
$Kiji[1] TDを除いた切り刻んだ記事が入ります
この場合にはTDが必要ないので$Kiji[1]を使用します。
データをキレイにします。
$main_kiji = str_replace(" ","",$Kiji[1]);
$Kiji = str_replace("\n","",$Kiji);
これで、BRタグと改行を取り除きます。
キレイになったところで、preg_match_all関数を使用して、変数中に存在するaタグを全て取り出し、配列に格納します。
preg_match_all("/<A href\=\"news(.+?)\">(.+?)<\/A>/s", $Kiji, $Midashi);
これで$Midashi配列に全ての記事のリンクが入ることになります。
それで、これをHTMLとしてジェネレートして好きな形で吐き出すことでデータの生成は終了です。
また当サイトではニュースの更新データをRSSとして吐き出しています。
これらのデータを生成する際にはリンクを更に細かく切り刻みURLとテキストに分けます。
そこからUTF-8にエンコードをして、XMLの形にして、ジェネレートして吐き出してあげます。
ジェネレートのタイミングは3時間おきで、指定のプログラムをcronでキックし定期的に生成しています。
記事の見出しを勝手に拝借している形なので、注意があった際には公開を停止しようと考えています。
2009 年 3 月 1 日
ソースコードを表示する際に、見た目をキレイに表示してくれるJavascriptライブラリが「dp.SyntaxHighlighter」です。
SyntaxHighlighter のすすめ を参考にして実装してみました。
実装の仕方を以下に記述します。
1.ソースの入手
ソースのダウンロードを行います。
以下のGoogleCodeで入手できます。
http://code.google.com/p/syntaxhighlighter/
また、ツールバーの表示が日本語化される改造版のパッチを当てます。
パッチはこちら からダウンロードします。
パッチファイルを解凍後にSyntaxHighlighter.css と shCore.jsを上書きします。
2.アップロード
ファイルをアップロードします。
当サイトでは。以下のように配置しました。
/home/hebita/www/css/sh/SyntaxHighlighter.css
/home/hebita/www/css/sh/clipboard.swf
/home/hebita/www/js/sh/shBrush****.js
これでファイルの準備は完了。
3.テンプレートの修正
ブログで表示するためには、テンプレートの修正作業が必要となります。
3-1.HeadタグにJSとCSSの埋め込み
サーバへアップロードしたJavascriptとCSSを読み込むように設定します。
<head>
</head>
3-2.エントリー部分の後ろにJSタグ挿入
<script type="text/javascript">
dp.SyntaxHighlighter.ClipboardSwf = "http://hebita.jp/css/sh/clipboard.swf";
dp.SyntaxHighlighter.HighlightAll("code");
</script>
このタグを入れることで該当する<pre>タグに変換をかけます。
これで準備は完了です。
4.記述の仕方
実際の書き方です。
ブログには以下のように記述します。
PHPのソースコードの場合。
<pre name="code" class="php:firstline[1]">
ここに記述
</pre>
これでブログにソースコードを記述することができます。
2009 年 1 月 27 日
当サイトはPHPで作成しています。
多少、フレームワークっぽくしてサイトの構成を実現しています。
ホームページ作成において、最も重要となるのが
「HTML ファイルをどのように扱うか」
ということになります。
PHP でページを表示することになるので、出来る限り、「ロジック」と「テンプレート」は分けたいものです。
そうすることによって、PHPのソースコードがとても見やすくなり、メンテナンスしやすくなります。
ですが、フレームワークチックにするとやはり、デメリットもあります。
それは、フレームワークを理解するためのコストが掛かるということです。
一般的なフレームワークを使うのであれば、上記のようなデメリットも発生しますが、一からフレームワークを作成すれば、そんな苦労はなくなりますし、なにより、手が入れやすいです。
まず、ロジックとテンプレートの切り分け方法を考えます。
プログラムロジックは各ページのindex.phpに任せます。
サーバーのrewriteruleを調整して一箇所のindex.phpにアクセスを集めて、パラメータで処理ワケをするという手もありますが、それ程大規模なサイトでなければガチガチに、アクセスを集めるよりも柔軟な対応ができる方がいいと思います。
rewriteruleはこまかくいじれない場合が多いですからね。
ですので。
Document Root
/home/hebita/www/
/home/hebita/www/index.php
/home/hebita/www/news/index.php
/home/hebita/www/weather/index.php
/home/hebita/www/tv/index.php
これらのindex.phpにロジックを持たせています。
それから、対となるテンプレートは
/home/hebita/www/template
以下に分かりやすく配置してあげます。
当サイトでは共通するテンプレートをcommonとして扱い、各ページで使用するテンプレートをpartsとして扱っています。
ですので、以下のようなテンプレート配置としています。
/home/hebita/www/template/common
/home/hebita/www/template/parts
/home/hebita/www/template/AD
/home/hebita/www/template/gen
/home/hebita/www/template/Base.html
こんな感じで配置しています。
ADディレクトリ
広告パーツを配置しています。
GoogleAdsenseやYahoo!IMやAmazonの広告配信用のJavascriptとなっているHTMLを置いておくことで、どの場所からも呼び出せるようにしています。
genディレクトリ
HTMLをジェネレートする際に読み込むエレメントパーツを配置しておきます。
HTMLパーツのジェネレートプログラムからエレメントを呼び出して静的HTMLを作成するパーツとなります。
Base.html
全てのページを表示する際に読み込まれる大元のHTMLとなります。
実際にアクセスすると分かるのですが。
http://hebita.jp/template/Base.html
中身は
<!-- HEADER -->
<!-- CONTENTS -->
<!-- FOOTER -->
こんな内容になっています。
大元のファイルはこれだけで、一つの画面を構成させることができます。
2009 年 1 月 20 日
Webスクレイピングとは
はてな では
英語で”scrape”とは「削ること」。
特に、ウェブサイトのデータを必要な部分だけ抽出して利用すること。
なんて紹介されています。
個人でホームページを作る場合に欲しくてたまらなくなるものが、「データ」ですね。
つまり、Webスクレイピングとは
欲しいデータを掲載しているサイトそのものをプログラムでダウンロードし、欲しいデータだけを取得し加工しましょうというものです。
それ程難しいものではなく、PHPであれば簡単に実行できてしまいます。
プログラムの大まかな流れは
HTTP通信でデータ(HTMLページ)を取得(ダウンロード)
取得したHTMLを変数として扱い「正規表現」で欲しいデータだけを取得
データを加工し、(可能であれば)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を用いてページをジェネレートしています。
例えば、トップページ で言えば
ニュース記事の見出し
仙台放送女子アナブログ
イオン ショップ情報
ワーナー・マイカル・シネマズ 新石巻
等の情報を定期的にクロールをして取得しています。
やり方はいろいろあると思うのですが、機会があったらチャレンジしてみてください!
2009 年 1 月 1 日
プロフィールを書いて個人ブログをスタートしようと思います。
管理人名
164(ひろし)
性別
男
年齢
23
出身
宮城県石巻市
住んでいるとこ
東京都練馬区
職業
Webエンジニア PHP、Perl、Ruby (HTML、CSS、Javascript)
好きなテレビ
大河ドラマ
趣味
サッカー ホームページ作成
当ブログは管理人のメモとして使おうと思っています。
お問い合わせがございましたら書きURLの入力フォームよりよろしくお願いいたします。
お問い合わせ
古い投稿 »