ディレクトリ型検索エンジンdtnのトップページでは、YahooやMSNやライブドアといった大手のポータルサイトと同じようにニュース記事をトップに表示させております。
ポータルサイトっぽさを出すにはニュース表示が必要だろうということで、dtn.jpを作った当初からニュースをトップページに表示してありましたが、私もサイトのチェックをするついでにニュースを眺めることが習慣になっておりましたので、サイトに欠かせないコンテンツの一つにはなっておりました。
かつては、Yahooが提供していたニューストピックスAPIというAPIを使い、Yahooニュースに表示されているものと同じデータをAPIで取得して表示することができましたが、APIサービスが終了して以降は、RSSで提供されるニュースデータを使ってなんとか実現していたものの、RSSデータのWEB利用はNGというパターンが多かったので、以前のYahooニューストピックスAPIのように、ニュースデータを提供するAPIがないかをずっと探してはおりました。
そんな中、Bingが提供するAPIの中に、News Search APIというニュース提供用のAPIがあることを見つけましたので、早速サイトに実装をさせてみました。
この記事では、Bing APIを利用するために必要なAzureアカウントの取得方法ご紹介や、Bing Search API v7によるニュース記事取得サンプルPHPコードのご紹介をしてみたいと思います。
dtn.jpトップページのニュース表示
ディレクトリ型検索エンジンdtnのトップページでは、YahooやMSNやライブドアといった大手ポータルサイトと同じように新着ニュースをトップに表示させています。ポータルサイトっぽさを出すにはニュース表示が必要だろうということで、dtn.jpを作った当初からニュースをトップページに表示してありました。
かつてはYahooトピックスAPIで表示
2007年頃はYahooのAPIでニューストピックスAPIといったものが提供されており、Yahoo Japanのトップページに表示されているニューストピックスデータと同じデータをAPI経由で取得することができました。今考えるとかなりの大盤振る舞いサービスだったようです。
APIサービス終了後はRSSデータで表示
APIブームの終了に伴い、YahooトピックスAPIもサービス終了となってしまいましたので、とりあえずは某ニュースRSSのデータを使ってトピックスを表示させておりましたが、RSSの二次利用はかなりグレーな問題もありますので、他に使えそうなAPIをずっと探してはおりました。
・提供するRSSは個人利用にのみ使用することができます。
YahooのRSSの利用マニュアル
・RSSから取得した情報を用いたウェブサイトやアプリケーションなどのプログラムを作成して公開することは許可しておりません。また、RSSの再配信や再提供も許可しておりません。
ニュース記事配信APIを探してはいたものの、このご時世ではなかなか無料で使える良さげなサービスが見つからず、時間もないのでそのままにしてしまっておりましたが、ふとしたタイミングで最適なニュースAPIを見つけることができました。
Bing APIにニュース取得用のAPIを発見
それが「Bing News Search API」でした。
これまでYahoo、Google、TwitterとAPIは色々使ってきたものの、MicrosoftのAPIを使ったという話も聞いたことがなかったため意外な盲点でしたが、Bing Search API では検索エンジンbingで提供している検索データや、画像検索、ニュース検索など、様々なサービスをAPIで提供しているようです。
Bing News Search API lets your users find headline news, news by category, and trending articles. If you’re looking to build an experience similar to bing.com/news, this is the API to use.
What is the Bing News Search API?の説明
ただし、私の世間知らずが原因か、はたまたマイクロソフトのAPI知名度があまり高くないことが原因かはよくわかりませんが、ドキュメントは英語のものしか見当たらず、Bing APIに関するネットの記事もあまり見当たらないので少々微妙でしたが、使ってみるとMicrosoftが提供するサービスなのでレスポンスは非常によく、しかも無料で利用することもできましたので、かなり使えるサービスということが今更ながらよく分かりました。
なお、完全無料で使えるというわけではなく、有料サービスが基本なものの、TPSとトランザクション数を抑えれば無料で利用が可能といった意味ですので、このあたりはご注意下さい。
インスタンス | 1 秒あたりのトランザクション数 (TPS) | 機能 | 料金 |
---|---|---|---|
無料 | 3 TPS | Bing Image Search Bing News Search Bing Video Search Bing Visual Search Bing Web Search | 1,000 無料トランザクション / 月 |
Microsoft Azureアカウントが必要
Bing APIを利用するためには「Microsoft Azure」のアカウントを取得する必要があります。
Microsoft Azureは2010年頃にサービスを開始したクラウドサービスの総称のことで、Amazon AWSと同じようなクラウドプラットフォームの従量課金型サービスといったものになりますが、Bing Search API利用にあたり、このAzureアカウント登録が必須のようですので早速登録をしてみました。
Azureアカウントの取得
こちらの「Microsoft Azure」の申込画面から「無料で始める」ボタンに進みます。
個人情報の登録
国/地域、氏名とメールアドレス、電話番号を登録します。電話番号は後々SMS認証に利用するので携帯番号が良さそうです。
SMSによる個人認証
先ほど登録した携帯番号にSMS認証の確認コードを送信させます。
クレジットカードによる本人確認
クレジットカードを登録して本人確認をさせます。アップグレードや制限以上の利用がなければ課金されるはないとのことですが、何かやらかした場合にはこのカードから請求されることになるようです。
最終同意
電話による本人認証、クレジットカードによる本人確認が終了すれば、最終同意画面が表示されます。
Azureアカウント作成完了
これでAzureアカウントの取得が完了したのでポータルに移動します。
Bing Search API v7
Azureのポータル画面にログインすると、さまざまなAzureサービスが一覧で確認することができます。Azure SQLや仮想マシンなど、IaaS/PaaSのクラウドサービスが100以上ずらっと並んでいます。全部使ったらかなり面白いことができそうですが、貧乏人には課金が恐ろしいので特に触らず目的のブツを探します。
今回やりたいことはニュースAPIでニュースを取るだけですので、「Bing News Search API」が含まれた「Bing Search API v7 」という名のAPIを探します。検索窓で「bing」と検索して探してしまいましょう。
F1サブスクリプション
みつけた「Bing Search API v7 」に進むと「Bing リソース」の作成に進みます。適当にリソースの名前を付けて、価格レベルをF1サブスクリプションにしておけば課金はひとまず避けられるようです。
APIキーとエンドポイント
ポータルに「Bingリソース」が無事追加ができたらやっと準備完了です。ここまできたら「キーとエンドポイント」を画面で確認することができますので、あとはプログラムを書けばOKです。
豊富なドキュメントとサンプルコード
マイクロソフトのサービスということもありドキュメントはかなり充実していました。英語マニュアルしか見当たりませんでしたが、QuickStartにC#、Java、Node.js、PHPといった各言語のサンプルまでご用意してくれてあるので、それを元にすれば問題なさそうです。
PHPのサンプルコードはこんな感じでした。
<?php
// NOTE: Be sure to uncomment the following line in your php.ini file.
// ;extension=php_openssl.dll
// **********************************************
// *** Update or verify the following values. ***
// **********************************************
// Replace the accessKey string value with your valid access key.
$accessKey = 'ここにAPIキーを設定';
$endpoint = 'ここにエンドポイントを設定';
$term = 'Microsoft';
function BingNewsSearch ($url, $key, $query) {
// Prepare HTTP request
// NOTE: Use the key 'http' even if you are making an HTTPS request. See:
// https://php.net/manual/en/function.stream-context-create.php
$headers = "Ocp-Apim-Subscription-Key: $key\r\n";
$options = array ('http' => array (
'header' => $headers,
'method' => 'GET' ));
// Perform the Web request and get the JSON response
$context = stream_context_create($options);
$result = file_get_contents($url . "?q=" . urlencode($query), false, $context);
// Extract Bing HTTP headers
$headers = array();
foreach ($http_response_header as $k => $v) {
$h = explode(":", $v, 2);
if (isset($h[1]))
if (preg_match("/^BingAPIs-/", $h[0]) || preg_match("/^X-MSEdge-/", $h[0]))
$headers[trim($h[0])] = trim($h[1]);
}
return array($headers, $result);
}
print "Searching news for: " . $term . "\n";
list($headers, $json) = BingNewsSearch($endpoint, $accessKey, $term);
print "\nRelevant Headers:\n\n";
foreach ($headers as $k => $v) {
print $k . ": " . $v . "\n";
}
print "\nJSON Response:\n\n";
echo json_encode(json_decode($json), JSON_PRETTY_PRINT);
?>
カテゴリ別のニュース取得
マニュアルをみていくと、クエリストリングにパラメータmktとcategory情報を付与して投げれば、カテゴリ別にニュース情報を取得できるようでした。
https://api.bing.microsoft.com/v7.0/news?mkt=en-us&category=sports
カテゴリはマーケット別に異なるようで、マーケット別カテゴリ一覧を見ると日本地域ではこのような分類がされておりました。
Japan (ja-P)
マーケット別のニュースカテゴリ一覧
・Business
・Entertainment
・Japan
・LifeStyle
・Politics
・ScienceAndTechnology
・Sports
・World
もともとdtn.jpのトップページで表示していたニュースは、国内・海外・経済・エンタメ…といった形でタブ分けをしてニュースを表示していたので、カテゴリ別にニュースが取得できればそっくり今の形にはめ込みができそうです。早速試してみました。
連続したAPIクエリ送信にはご注意を
先ほど見つけたマーケット:Japan (ja-P)のカテゴリを配列に設定し、接続先エンドポイントにカテゴリを順々に付けて取得してみたところ、全く問題なくニュースをカテゴリ別に取得することができました。
APIの連続送信で課金が発生!?
テスト送信を何度かやってデータ取得が問題なくできることを確認したところまではよかったのですが、Azureのポータルを見ていると無料枠にもかかわらず請求が発生してしまっておりました。
月間1000トランザクションまでは無料のはずで、さすがにこの短時間に1000回も回しているわけはありませんので、どうやら1秒当たりのトランザクション3TPS以内というところを超えたということのようです。
先程ご紹介したマーケット:Japan (ja-P)のカテゴリは8カテゴリですので、これを配列でぶん回して何も考えずに取りに行っていたので、3TPSは確実に超えてしまっていたようです。
やってしまったものはどうしようもなさそうですので、カテゴリの問い合わせをするごとにsleep()で1秒止めてデータ順次取得するようしておきました。sleep()でお眠りさせてからは課金されずに済みましたが、152.55円取られたのがなんだか悲しかったです。
sleep(1);
サイトに無事ニュースが表示
無料枠に収めるためには、月間1000トランザクション以内にする必要があるので、API接続は1時間に1トラン程度で済むようにバッチ処理化をしました。
cronで取得したニュースデータは一旦DBにためておき、トップページではDBデータを表示するようしてあります。ニュース情報がリアルタイム更新されたものとはできませんでしたが、これでサイトトップにニュースが表示できるようになりました。
取得したJSONのレスポンスにはニュース記事毎に画像も設定されておりましたので、画像を記事横に表示させることができればよりポータルサイトっぽくできそうです。時間があったら差し込んでみたいと思います。
ニュース情報が取得できていない
無事サイトに表示されたので安心しきっておりましたが、大晦日にサイトトップをみていたところ、ニュース情報が数日前と変わっていないことに気が付きました。
急いでDBのテーブルを確認してみたところ、12月22日頃のニュース取得が最終となっており、どうやらそれ以降はニュース情報を取得することができていなかったようです。
直接APIにリクエストを投げてみると「403 Quota Exceeded api error」が返ってきておりまして、なにやら回数制限を受けているような印象です。
ヘルプを見ても原因がよく分からず、仕方ないのでリソースを一度消して再度同じ名前で作り直し、新しいAPIキーで接続をしてみたところすんなり接続ができてしまいました。
APIキーの有効期限
「F1 Free」の無料利用だからかもしれないですが、APIキーを一定期間経過後に更新をかけないと動かなくなる仕様ということのようです。要はAPIキーの使用期間に有効期限があるということのようです。
DBに残っていたログをみていると12月22日の0時00分までは取得ができていたようです。API側のログでは、12月14日からこのキーを使い始めていたようなので、ちょうど7日間でAPIキーの有効期限が切れるということのようです。
APIキーの再生成ボタンがある
Azureポータルの「Bing Search」リソースを見ると、「Key1の再生成」「Key2の再生成」というボタンが置いてあるので、こいつで一週間に一回は更新しろということかもしれません。
「Bing リソース」の再作成が必要
キーの再生成でAPIが利用可能になるかと思ったものの、やはりリソースを一旦削除して、再度「Bingリソース」作成からやり直しをしないとうまく動きませんでした。やはり無料利用にはそこまで優しくなかったようです。
削除→リソース再生成で5分程度の作業で終わりますので、これさえ我慢すればMicrosoftの提供するAPIが利用可能と考えると、不満のないレベルかとは思います。
おわりに
APIキーの有効期限は7日間といった厄介な仕様ということが分かりましたが、そこさえ我慢すればマイクロソフトが提供する、レスポンスに機能も最高のAPIを無料で利用ができるので、今のご時世ではかなりの大盤振る舞いAPIといっても良いとは思います。よければお試ししてみて下さい。