サイトのテキストを読み込んで、タイトル、本文、サムネイル画像とかを取得してみようと思います。
リンクをカード形式プラグイン
WordPressでリンク先を「はてなブログカード」で表示する「popo-HatenaBlogCard」を公開中。
「これを自前でやれないかなぁ?」という計画です。
今回は、リンク先からタイトルや本文(もしくは抜粋文、概要文)、サムネイル画像を取得してみようと思います。
file_get_contentsでHTML取得してみる
テキストファイルを読み込む file_get_contents()。
ファイル名の代わりにURLを指定することで、HTTPリクエストを送信することができるそうです。
とりあえず、HTML取得して、かかった時間を測ってみます。
$html = file_get_contents('https://popozure.info/20150723/7753');
1.5秒~2.6秒くらいで取得できました。
HTMLソースが取得できた状態なので、ここからタイトルの取得とかを別途考えます。
cURLでHTML取得してみる
cURLというのを使うと、USER_AGENTとかREFERERを指定したり、cookie使ったりできるほか、PUTとか色々とアクセスができるようです。
「cURL初期化→cURLオプション指定→cURL実行→cURL閉じる」という手順が必要のようです。
とりあえず、HTML取得してみます。
$ch = curl_init('https://popozure.info/20150723/7753'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $html = curl_exec($ch); curl_close($ch);
1.2秒~2.2秒くらいでした。
結果としては「file_get_contentsよりも速いのは確かだけど、誤差範囲」という感じでした。
手軽さでは file_get_contents、自由度では cURL という感じでしょうか。
HTMLソースが取得できただけなので、タイトルの取得などは別途考えます。
OpenGraph.phpを使ってみる
最近ではfacebookとかで使われている「OGP(;OpenGraph Protocol)」という仕様があって、タイトル、概要、画像、URL、サイト名なんかが記述されているブログが増えてきました。
OGPが設定されているサイトは、それを使うことでサイト側が意図した内容が表示される、ということになります。
HTMLのソースを取得して、そこからOGPの内容まで取得してくれる「OpenGraph.php」というのがあるようで、URLを指定するだけで、OGPの内容をオブジェクトとして返してくれます。
OpenGraph.phpは、「Apache License 2.0」ということなので、自分のプラグインに使って、一緒に頒布しても大丈夫そうです。
さっそく取得してみます。
require_once('OpenGraph.php'); $graph = OpenGraph::fetch($url);
取得にかかる時間は1.3秒~2.0秒。
内部ではcURLを使っているので、基本的には上のcURLを使っているのと同じ速度です。
あとは、
echo '<br />title='. $graph->title; // ページのタイトル echo '<br />description='. $graph->description; // ページの説明 echo '<br />image='. $graph->image; // 画像URL echo '<br />site_name='. $graph->site_name; // サイト名
こんな感じで使うだけです。
↓結果
[crayon]title=リンクをカード形式にするプラグインを修正中
description=リンクカード形式で表示するプラグイン「HatenaBlogCard」を公開していますが、設定画面とかを付けたバ…
image=http://mailbox.conohawing.com/popozure/blog/wp-content/uploads/2015/07/popo-linkcard-shadow-300×100.png
image_src=
site_name=ぽぽづれ。[/crayon]
タイトルについては、「<meta property=”og:title” content=”○○○○”>」が無い場合には、「<title>○○○○</title>」からセットしてくれるようです。
あれ?これ使うだけでいいじゃんか!Σ(゚ロ゚)o゙
タイトル、抜粋文、サムネイル画像を抜き出してみる
どうせなので自分で抜出をしてみたいので、HTMLソースから、自分でOGP情報とかを抜き出してみようと思います。
とりあえず、metaタグで、property=”og:○○○○”とcontent=”○○○○”があるのを抜き出してみます。
preg_match_all('/.*<meta\s+.*property\s*=\s*"og:(.*)"\s*content\s*=\s*"(.*)".*>/i', $html, $m)
$m | [0] | [1] | [2] |
[0] | type | article | |
[1] | title | リンクをカード形式にするプラグインを修正中 | |
[2] | url | https://popozure.info/20150723/7753 | |
[3] | description | リンクカード形式で表示するプラグイン「HatenaBlogCard」を公開していますが、設定画面とかを付けたバ… | |
[4] | site_name | ぽぽづれ。 | |
[5] | image | http://mailbox.conohawing.com/popozure/blog/wp-content/uploads/2015/07/popo-linkcard-shadow-300×100.png | |
[6] | locale | ja_JP | |
[7] |
しょっぱなからいい感じで取得できましたΣ(゚ロ゚)o゙
他のサイトさんでも試したところ、取得は出来たのですが、propertyとcontentの順番が逆のサイトさんがあり、上手く取れませんでした。
順不同でマッチさせると、結果もどっちに入っているのか分からなくなってしまうので、「property=”og:title”」が含まれるmetaタグを拾ってきてから、contentの中身を取得するようにしてみます。
if (preg_match('/.*<meta\s+(.*property\s*=\s*"og:title"\s*.*?)>/i', $html, $m)) { $param = $m[1]; if (preg_match('/.*content\s*=\s*"(.*?)".*/i', $param, $m)) { $title = $m[1]; } }
一行目のpreg_matchで、metaタグの内容を取得。
$m | [0] | [1] | [2] |
property=”og:title” content=”リンクをカード形式にするプラグインを修正中” / |
三行目のpreg_matchで、contentの中身を取得します。
$m | [0] | [1] | [2] |
property=”og:title” content=”リンクをカード形式にするプラグインを修正中” / | リンクをカード形式にするプラグインを修正中 |
これなら、contentがpropertyよりも前でも後でも取得できそうです。
さらにはOGPが無かったときは<title>~</title>タグの中身を持ってくれば良さそうです。
} else { if (preg_match('/.*<title>\s*(.*)\s*<\/title>.*/i', $html, $m)) { $title = $m[1]; } }
本文は、OGPがあれば「og:description」のcontentを、なければ「最初の<p>~</p>タグの中身」をもってくるようにしてみます。
if (preg_match('/.*<meta\s+(.*property\s*=\s*"og:description"\s*.*?)>/i', $html, $m)) { $param = $m[1]; if (preg_match('/.*content\s*=\s*"(.*?)".*/i', $param, $m)) { $excerpt = $m[1]; } } else { if (preg_match('/<p>\s*(.*)<\/p>/i', $html, $m)) { $excerpt = $m[1]; } }
同じように「og:image」で画像のURL、「og:site_name」でサイト名が取得できます。
画像はそのまま使う?
OGPで使われる画像は大きいものが多いため、スマートフォンなどで見ているときには通信量が増えてしまいます。
また、画像URLをそのまま直リンクすると、リンク先サイトへの無駄なアクセスも増えてしまうので、そのままは使わないようにしたいです。
この辺はまた次回にでも。
コメント