簡単なAPIをつくります。今回やるのはurlを入力するとページのタイトルを返すという超簡単なものです。他のサイトにリンクをはるときにできればタイトルを変えずにそのままにしたいのですが、こんなときに役に立つかなと考えて作成することにしました。
まずphpファイルを作成します。json形式の文字列をPOSTすればurlからHTMLを取得、それを解析してページのタイトルを返します。
01.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php header('Content-Type: application/json; charset=UTF-8'); $json = file_get_contents('php://input'); $data = json_decode($json, true); $url = htmlspecialchars($data["url"]); if($html = @file_get_contents($url)){ $html = mb_convert_encoding($html, "utf-8", "auto"); preg_match('/<title(.*?)>(.*?)<\/title>/', $html, $result); $index = array_key_last($result); $title = $result[$index]; // メイン処理 $arr["status"] = "ok"; $arr["title"] = $title; $arr["json"] = $json; } else { $arr["status"] = "error"; $arr["title"] = ""; $arr["json"] = $json; } print json_encode($arr, JSON_UNESCAPED_UNICODE); |
HTMLからタイトルタグを抜き出す方法ですが、よく以下のようなサンプルコードがあります。
1 2 |
preg_match( "/<title>(.*?)<\/title>/i", $html, $matches) ) $title = $matches[1]; |
たいていの場合はこれでうまくいきます。しかしタイトルタグが以下のようになっているとうまくいきません。
1 |
<title itemprop="name">たまにこういうものをみかけます</title> |
そこで上記のような方法で取得しています。
これに①のようなJsonTEXTを作成してPostすると②のような結果が返ってきます。
①
1 2 3 |
{ "url":"https://news.yahoo.co.jp/pickup/6413095" } |
②
1 2 3 4 5 |
{ "status": "ok", "title": "5G網は23年度に人口9割に 首相 - Yahoo!ニュース", "json": "{\"url\":\"https://news.yahoo.co.jp/pickup/6413095\"}" } |
実際に使うときはweb上やデスクトップアプリで使うことが多いので、以下のようなHTMLを作成します。URLを入力して送信ボタンを押せばタイトルが取得できます。またデバッグも兼ねてPOSTしたJSON形式の文字列も変えさせます。
もし存在しないURLやURL以外のものを入力したときは”status” : “error”が返ってくるのでエラーである旨を表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>urlからタイトルを抜く</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <form onsubmit="GetTitle(); return false;"> <p>URL: <input type="text" name="url" id = "url" value=""></p> <input type="submit" > </form> <p>取得されたページタイトル</p> <p id = "title"></p> <p>返されたjson形式の文字列</p> <p id = "result"></p> <script> let xhr = new XMLHttpRequest(); function GetTitle(){ xhr.open('POST', "https://miya10240.xsrv.jp/api-test/01.php", true); xhr.setRequestHeader('Content-Type', 'application/json'); let value = document.getElementById('url').value; let obj = { "url":value, } let json = JSON.stringify(obj); xhr.send(json); xhr.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200){ let result = document.getElementById('result'); let title = document.getElementById('title'); let json = xhr.response; const obj = JSON.parse(json); if(obj["status"] == "ok"){ result.innerHTML = json; title.innerHTML = obj["title"]; } else { result.innerHTML = json; title.innerHTML = "エラーです"; } } }; } </script> </body> </html> |
ローカルサーバーで実験してうまく動作することを確認したらサーバーにアップすればよいのですが、同じドメインでない場合は
クロスオリジン要求をブロックしました: 同一生成元ポリシーにより、https://XXXX/XXX/01.php にあるリモートリソースの読み込みは拒否されます (理由: CORS 要求が成功しなかった)。ステータスコード: (null)
と表示されてうまくいきません。その場合は01.phpをアップロードしたディレクトリに以下のように記述した.htaccessを設置します。
1 2 3 4 5 6 |
<IfModule mod_headers.c> Header add Access-Control-Allow-Origin "*" Header add Access-Control-Allow-Headers "*" Header add Access-Control-Allow-Methods "GET, POST" Header add Access-Control-Max-Age 86400 </IfModule> |
これでうまくいくはずです。