ショウジンブログ on Hatena

“お芝居をしないと、この社会では異邦人として扱われるほかない”

Webページを部分的に抽出して別の場所で表示(スクレイピング)@PHP

とあるWebページの内容を一部抽出して別の場所(同じサーバ上でも別サーバ上でも別ドメインでも)で表示するのに大変重宝しているのがPHPのライブラリ「Simple HTML DOM Parser」です。

他者が作っているコンテンツをさも自分のもののように見せるような使い方はもちろんご法度ですが(以前はiframeなんかでそういうことがよくされてましたが)外部のブログサービスなんかを利用していて、それを一部(直近数件とか)自サイトの「お知らせ」とか「ブログ」に表示したいといった依頼はけっこうあって、そういうときにこのParserを使ったスクレイピングに大変お世話になっています。

似たようなものではこれもPHPのParserであるMagpieRSSがあり、こちらも何度かお世話になりました。

http://blog.showzine.co/entry/magpierssblog.showzine.co

今回は「Simple HTML DOM Parser」です。

PHP Simple HTML DOM Parser

http://simplehtmldom.sourceforge.net/

上記URLにあるDownload & Documents部分の「Download latest version form Sourceforge.」のリンクテキストからダウンロードURLに行き、Download simplehtmldom_1_5.zip (343.8 kB)をクリック。ダウンロードが始まるのに5秒ほどかかるので、そのまま待ちます。

ダウンロード出来るようになるとどこに保存するかのダイアログウィンドウが出現するので、そこでダウンロードしたいディレクトリを指定して「simplehtmldom_1_5.zip」をダウンロード。

ダウンロードしたzipファイルを展開すると中身はこんな具合。

f:id:showjinx:20160517102319p:plain

この中身をスクレイピングを実行したいサーバにアップロードします。

この例ではテスト実行用にsimpleHtmlDomというディレクトリを用意して、その中にsrcという名前でディレクトリを作成。その中にsimplehtmldom_1_5内のsimple_html_dom.phpだけをアップロードしました。

f:id:showjinx:20160517102341p:plain

このphpソースファイルがスクレイピングを実行する本体で、他はマニュアルやサンプルなので、それらは必要に応じて使います。

スクレイピングを実行して、その内容を表示させるページとして同ディレクトリにindex.phpを作成します。

このindex.php内に以下を記述します。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>DEMO | Simple HTML DOM Parser</title>
</head>
<body>

<div id="container">
<?php
// simple_html_dom.phpファイルの読み込み
include_once('src/simple_html_dom.php');

//スクレイピングしたいURLを指定
$html = file_get_html( 'http://blog.showzine.co/' );

// findメソッドを使ってスクレイピングしたい(取り込みたい)場所を指定
// 該当箇所のclass名やid名なんかを使ってjQueryで要素を指定する要領で
foreach($html->find('#box2 .hatena-module-profile') as $list) {
     echo $list->outertext;
}
// クリアーして開放
$html->clear();
unset($html);
?>

<!-- // container --></div>
</body>
</html>

これで完了。

ブラウザでアクセスしてみると、指定した要素(#box2 > .hatena-module-profile)をまるっと取り込んで表示してくれてます。

デモ

このブログのサイドバー部分(右上のAuthorのブロック)をスクレイピングした例です。
DEMO | Simple HTML DOM Parser

html要素を抽出して出力しているだけなのでcssによるデザイン指定は効いていません。

日本語が文字化けする場合はPHPのmg_language関数で日本語を指定します。

<?php
// simple_html_dom.phpを読み込む
require_once('src/simple_html_dom.php');

// file_get_htmlを使って取り込みたいスクレイピング元URLを変数$htmlに代入
$html = file_get_html('http://blog.showzine.co');

// mg_language関数で日本語を指定
mb_language('Japanese');

// 取り込みたいスクレイピング元のURLを変数$urlに代入
$url = 'http://blog.showzine.co';

$contents = file_get_contents($url);
$content = mb_convert_encoding($contents, 'UTF-8', 'auto');
$html = str_get_html($content);
echo $html->find('.Guest dl.FstTitle', 0)->outertext;

// 取り込みたい部分の要素名をclass名やid名で指定
foreach($html->find('#box2 .hatena-module-profile') as $list) {
echo $list->outertext;
}
$html->clear();
unset($html);
?>

こんなふうに実に簡単、お手軽にスクレイピングを実現してくれる便利なライブラリですが、HTMLの解析に正規表現を使っていることからメモリ消費量が多いそうです。(処理時間は大差ないとあります)

localdisk.hatenablog.com

このGoutteも使ってみたいですね。