2017年11月19日更新

スクレイピングの方法(PHP)

スクレイピングは、他のサイトのコンテンツの一部分を抜き出して、自分のコンテンツとして再構築させる為の物です。

  • 追加

スクレイピングとは

ウェブスクレイピング(英: Web scraping)とは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。ウェブ・クローラー[1]あるいはウェブ・スパイダー[2]とも呼ばれる。 通常このようなソフトウェアプログラムは低レベルのHTTPを実装することで、もしくはウェブブラウザを埋め込むことによって、WWWのコンテンツを取得する。
ウェブスクレイピングは多くの検索エンジンによって採用されている、ボットを利用してウェブ上の情報にインデックス付けを行うウェブインデクシングと密接な関係がある。ウェブスクレイピングではウェブ上の非構造化データの変換、一般的にはHTMLフォーマットからデータベースやスプレッドシートに格納・分析可能な構造化データへの変換に、より焦点が当てられている。また、コンピュータソフトウェアを利用して人間のブラウジングをシミュレートするウェブオートメーションとも関係が深い。ウェブスクレイピングの用途は、オンラインでの価格比較、気象データ監視、ウェブサイトの変更検出、研究、ウェブマッシュアップやウェブデータの統合等である。

出典:ja.wikipedia.org

簡単に言うと、ウェブページに書いてある情報から必要な部分を抜き出す方法です。

必要なFunction

方法自体は色々とありますが、ひとまず、私がいつも使っているFunctionを二つ掲載します。

まずは、HTMLの文章をXML化する事が、スクレイピングの基本です。
XMLとは、一番良く見かける状態で言うと、Feedのような形式の事で、
<item url="http://xxx.xxx">abc</item>
<item url="http://yyy.yyy">efg</item>
のように、HTMLに似た形で形成されています。
XMLを、オブジェクト化することで、<item>の2番目の要素を取得する、と言ったことや、<item>のurlがxxx.xxxを含むものを取得する、ということが可能になります。
それが、xpathと言う技術です。

フィードからURL一覧を取得する等も基本的には同じような形で、URL一覧を取得しています。

//xmlからXpathを指定して返すFunction
private function xpath_and_preg($xpath, $xml) {
$rarray = array();
$s = $xml->xpath(html_entity_decode($xpath["path"], ENT_QUOTES));
if (!isset($s) or count($s) == 0) {
return array();
}
if ($xpath["preg"] == 0) {

foreach ((array) $s as $key => $value) {
try {
if (preg_match(html_entity_decode($xpath["match"], ENT_QUOTES), $value, $matches)) {
$rarray[] = $matches[$xpath["num"]];
}
} catch (\Exception $e) {
$this->errors($e->getMessage());
}
}
} else {
foreach ($s as $key => $value) {
if (preg_match_all(html_entity_decode($xpath["match"], ENT_QUOTES), $value, $matches)) {
foreach ($matches[$xpath["num"]] as $val) {
$rarray[] = $val;
}
}
}
}

return $rarray;
}

出典:code

URLで指定したページを、まずはXML化しなくてはなりません。
XML化する際に、BRが割と邪魔になります。
というのも、BRも一つのタグで要素になるからです。
<p>
あいうえお<br>
かきくけこ<br>
</p>
という部分があり、Pタグ内を抜き出そうとした時、
0=>あいうえおかきくけこ
1=><br>
2=><br>
のように、BRはPタグの下のさらに子要素になります。

なので、BRを\nに置き換え、コメント欄を取得できるように平文字化する等を行っています。

//htmlをXML化するFunction
private function html_to_xml($url_html, $charset = null, $replacearray = array()) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_html);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$html = curl_exec($ch);
curl_close($ch);

$html = str_replace(array("<br />", "<br>", "<br/>", "<br >", "<BR>", "<BR />", "<BR/>", "<BR >"), "\n", $html);
if (count($replacearray) > 0) {
foreach ($replacearray as $replace) {
$html = preg_replace($replace["from"], $replace["to"], $html);
}
}
$html = str_replace("&nbsp;", " ", $html);

$html = preg_replace("/<!--(.*?)-->/", "$1", $html);

if ($charset == null) {

$min_pos = 99999999999999; //十分に大きな数字
$from_encoding = 'UTF-8'; //デフォルト
foreach (array('UTF-8', 'SJIS', 'EUC-JP', 'ASCII', 'JIS', 'ISO-2022-JP') as $charcode) {
if ($min_pos > stripos($html, $charcode, 0) && stripos($html, $charcode, 0) > 0) {
$min_pos = stripos($html, $charcode, 0);
$from_encoding = $charcode;
}
}
} else {
$from_encoding = $charset;
}
$html = mb_convert_encoding($html, 'HTML-ENTITIES', $from_encoding);

$domDocument = new DOMDocument();
libxml_use_internal_errors(true);
$domDocument = new DOMDocument();
@$domDocument->loadHTML($html);
$xmlObject = @simplexml_import_dom($domDocument);
if (!$xmlObject) {
$this->errors("ページの書式が不正です。");
return false;
}
return $xmlObject;
}

出典:code

後はXPATHのポイントを指定するだけ

XPATHは、XML化した文章からどの場所を取得するか指定出来ます。
これが使えるようになると、アンテナサイトなども作成できるようになります。

$xml = $this->html_to_xml($url, "SJIS", array(array("to" => "", "from" => "/<a [^>]+>/"),
array("to" => "", "from" => "/<\/a\s*>/"),
array("to" => "", "from" => "/<\/?b>/"),
array("to" => "", "from" => "/<\/?font\s?[^>]+>/"),
));
if (!$xml) {
$this->errors("RSSの書式が不正です。");
return;
}

$x["path"] = "//div[@class='post']/@id";
$x["match"] = "/[0-9]+/su";
$x["num"] = "0";
$x["preg"] = "preg_match";
$resid = $this->xpath_and_preg($x, $xml);

出典:code

上の例は、URLに2chURLを指定することで、レス番号の一覧を取得するXPATHです。
同様に、本文なども取得することが可能です。

スクレイピングをしたデータを整形する

スクレイピングは、データそのままではあまり役に立たない文字の羅列です。
しかし、例えば株価をスクレイピングしたならば、
毎日継続的に自動的にスクレイピングすることで、自分だけの株価のデータベースを作ることも出来ます。
アンテナサイトから掲載されているブログ一覧を取得することなども出来ます。

ウェブサイトのこのデータの一覧があれば、
こういう面白いことが出来ると思うんだけど…
という時に、必要な技術がスクレイピングです。

なお、APIが発行されている場合は、そちらを使ったほうが良いです。

オススメの記事Gmatom注目まとめ

シェアする気になったらシェアする

ツイート

ユーザー情報ユーザーの紹介

Gmatom 浜田貴朗

2008年よりコミュニティサイトを運営しつつ、効果の高い広告はバナー広告では無く誘導的コンテンツ広告と気付き、コンテンツ作成を手掛ける。 ポイントサイト・キュレーションサイト・動画自動投稿サイトや自動記事作成ツール、自動フォローツール等ツールの開発等、主にウェブ系の業界にて開発・運営を行っています。 V系バーの立ち上げ・ウェブ戦略・立地戦略等飲食店の立ち上げ・運営も携わっていました。

関連するキーワードキーワードからまとめを探す