読者です 読者をやめる 読者になる 読者になる

PHP+JavaScriptでWebスクレイピング

ちょっとホームページのスクレイピングが必要だったので、使い回しできるような物として作ってみた。

スクレイピング」とは、とあるサイトの必要なデータを抽出する行為とのこと。
はてなキーワードより。

目指したのは、Facebookの記事投稿でURLを貼り付けると、リンク先のページの説明が表示されるけど、あんな感じで、

  • タイトル
  • 概要
  • イメージのリスト

を表示してくれるようなもの。

初期バージョンのものが出来上がったので、Githubに上げました。
PHP+JavaScriptでWebスクレイピング

デモはこちら


JQueryプラグインのように、HTMLに簡単に組み込めるようにしました。
組み込み方は、

サーバに get_url_info.php を置く。

外部に公開されているWebサーバに

  • get_url_info.php
  • simple_html_dom.php

を置いてください。

CSSを読み込む
<link href="css/jquery.scraping.0.1.css" rel="stylesheet">`
JQueryスクレイピング用のプラグインを読み込む
<script src="src/jquery.js"></script>`
<script src="js/jquery.scraping.0.1.js"></script>`
URL入力用のinputを配置する
<input id="url_input" type="text" style="width:200px">
JavaScriptで初期化する
	$(function() {
		$('#url_input').Scraping({
			phpUrl : './get_url_info.php'
		});
	});

これで、textの値が入力され、フォーカスが離れると入力されたサイトの情報を取得しにいきます。

本当はJavaScriptだけで完結させたかったけど、クロスドメインの制約の回避がちょっと厄介だったので、サーバで対象のサイトのHTMLを解析させて、その結果をJSONで受け取って表示する方法にした。


スクレイピングする際にややこしくなるのが、どこの情報を取得して表示するか。

このあたりを調査していたら、metaタグにこんな定義があるのを見つけた

<meta property="og:title" content="sparkgeneのブログ">

これは、Open Graph protocolで定義されているmetaタグの書き方。
簡単に言うと、サイトのことについての説明を分かりやすいように共通の名称で定義しているもの。

はてなダイアリーでもソースを覗くと、定義されています。
このブログの場合は、こんな感じでブログの説明が書かれています。

<meta property="og:type" content="blog">
<meta property="og:title" content="sparkgeneのブログ">
<meta property="og:image" content="http://www.st-hatena.com/users/sp/sparkgene/profile.gif">
<meta property="og:url" content="http://d.hatena.ne.jp/sparkgene/">
<meta property="og:description" content="ブログを始めるのはこれで3度目だけど、ぼちぼち頑張ってみます">
<meta property="og:site_name" content="はてなダイアリー">

なので、Facebookでこのサイトを貼り付けると、以下のようにちゃんとサイトの説明が表示される。

便利!
今後ホームページを作成する時は、必ず入れておくと他のサービスとの連携が良くなりますね。

けど、このタグが設定されていない場合は、どうするかも考えなければならない。

例えば「タイトル」の場合は、metaタグに書かれている場合や、titleタグに書かれている場合がある。
どちらも書かれていなかった場合はどうするか?
など。

そこで、今回の場合の優先順位は以下のようにしてみた。

  1. metaのog:title
  2. titleタグ
  3. metaのog:site_name
  4. どれも無ければurlを表示

ただ、この場合どれも指定されていなかった場合、常にurlが表示されてしまい、なんだかイマイチですね。。。
今後は、h1,h2タグを探す機能も入れてみようかな。