cURLを使ってサイトへアクセスしてみた

PHP
この記事は約9分で読めます。

サイトのテキストを読み込んで、タイトル、本文、サムネイル画像とかを取得してみようと思います。

リンクをカード形式プラグイン

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('/.*&lt;meta\s+.*property\s*=\s*"og:(.*)"\s*content\s*=\s*"(.*)".*&gt;/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('/.*&lt;meta\s+(.*property\s*=\s*"og:title"\s*.*?)&gt;/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('/.*&lt;title&gt;\s*(.*)\s*&lt;\/title&gt;.*/i', $html, $m)) {
            $title = $m[1];
        }
    }

 

本文は、OGPがあれば「og:description」のcontentを、なければ「最初の<p>~</p>タグの中身」をもってくるようにしてみます。

    if (preg_match('/.*&lt;meta\s+(.*property\s*=\s*"og:description"\s*.*?)&gt;/i', $html, $m)) {
        $param = $m[1];
        if (preg_match('/.*content\s*=\s*"(.*?)".*/i', $param, $m)) {
            $excerpt = $m[1];
        }
    } else {
        if (preg_match('/&lt;p&gt;\s*(.*)&lt;\/p&gt;/i', $html, $m)) {
            $excerpt = $m[1];
        }
    }

 

同じように「og:image」で画像のURL、「og:site_name」でサイト名が取得できます。

画像はそのまま使う?

OGPで使われる画像は大きいものが多いため、スマートフォンなどで見ているときには通信量が増えてしまいます。

また、画像URLをそのまま直リンクすると、リンク先サイトへの無駄なアクセスも増えてしまうので、そのままは使わないようにしたいです。

この辺はまた次回にでも。

コメント

タイトルとURLをコピーしました