はじめに
本稿は、はてなブックマークの人気エントリーを Azure Functions で取得する方法の紹介です。
言語は C# です。
はてなブックマークのRSS
はてなブックマークの人気エントリーと新着エントリーを取得する方法としてRSSがあります。
今回は、ITエンジニア向けの情報を取得したいので「テクノロジー」というカテゴリを対象にします。
人気エントリーは以下です。
http://b.hatena.ne.jp/hotentry/it.rss
新着エントリーは以下です。
http://b.hatena.ne.jp/entrylist/it.rss
その他のカテゴリのRSSについては以下の記事を参照ください。
はてなブックマークのRSSは、RSS 1.0 です。
中身を見ていくと、item という要素ごとに、ブックマークされたページの詳細なデータが入っています。
今回、利用するデータは、下図の赤枠部分とします。
それぞれの値は、おそらく以下の意味であると解釈しました(公式な説明が見つからず)。
title:対象ページのタイトル
link:対象ページのURL
description:対象ページの本文の冒頭の150~200文字くらい
dete:ブックマークが登録された日時(たぶん)
bookmarkcount:ブックマーク数
C# での RSS 1.0 の取得方法
.NET では Atom 1.0 と RSS 2.0 なら SyndicationFeed クラスで簡単に取得できます。
しかし、RSS 1.0 を取得するには、少し手間がかかります。
C# で RSS 1.0 を取得したいというニーズが少ないせいか、日本語で解説してくれる記事は少ないですが、以下の2つの記事で詳しく解説してくれていました(感謝)。
今回は、上記の実装方法を用いて、はてなブックマークのテクノロジーの人気エントリーを取得するソースコードを書きます。
まず、事前準備として RSS の中の Item 要素ごとのデータを格納するためのクラスとして、FeedItemクラスを定義します。
internal class FeedItem
{
public string Title { get; set; }
public string Link { get; set; }
public string Description { get; set; }
public DateTime Date { get; set; }
public int BookmarkCount { get; set; }
}
そして RSS から取得したデータを、FeedItemクラスに格納して返すメソッドを、以下のように書きます。
// 引数のurlに、RSSのURLが入ってくる想定
private static IEnumerable<FeedItem> ReadRSS(string url)
{
// RSSのデータをXmlDocumentクラスを用いて読み込む
var xml = new XmlDocument();
xml.Load(url);
// RSS 1.0 の要素を取得するための事前準備
var nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
nsmgr.AddNamespace("rss", "http://purl.org/rss/1.0/");
nsmgr.AddNamespace("dc", "http://purl.org/dc/elements/1.1/");
nsmgr.AddNamespace("hatena", "http://www.hatena.ne.jp/info/xmlns#");
// item要素を格納するためにFeedItemクラスのリストを作成
var items = new List<FeedItem>();
// すべてのitem要素を取得する
foreach (XmlElement node in xml.SelectNodes("/rdf:RDF/rss:item", nsmgr))
{
// titleやlinkなどの値を取得する
var title = node.SelectNodes("rss:title", nsmgr)[0].InnerText;
var link = node.SelectNodes("rss:link", nsmgr)[0].InnerText;
var description = node.SelectNodes("rss:description", nsmgr)[0].InnerText;
var date = DateTime.Parse(node.SelectNodes("dc:date", nsmgr)[0].InnerText);
var bookmarkCount = int.Parse(node.SelectNodes("hatena:bookmarkcount", nsmgr)[0].InnerText);
// 取得した値をもとにFeedItemを作成してリストに追加
items.Add(new FeedItem()
{
Title = title,
Link = link,
Description = description,
Date = date,
BookmarkCount = bookmarkCount
});
}
// FeedItemのリストを返す
return items;
}
上記のコードを実行すれば、はてなブックマークの人気エントリーをFeedItemクラスのリストに格納することができます。
Azure Functions で Web API として返す
Azure Functions の Web API の作成方法は、Visial Studio で新しいプロジェクトを作成する下図の画面で、Azure Functions を選択してプロジェクトを作成するだけです。
トリガーの種類は「httpトリガー」を選びます。
詳細は、以下の公式ページを参照ください。
プロジェクトを作成した時点で、Web API として機能するための雛形のメソッドは作成されています。
あとは、そのメソッドの中身を、書き換えるだけです。
さきほど紹介した ReadRSS メソッドを呼び出した後に、json形式に変換して返すメソッドを以下に書きます。
[FunctionName("hatenarss")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
// はてなブックマークのテクノロジーの人気エントリーのRSSのURL
string url = @"https://b.hatena.ne.jp/hotentry/it.rss";
// RSSから、IEnumerable<FeedItem> 型のリストを取得する
var feedItems = ReadRSS(url);
// IEnumerable<FeedItem> を json形式に変換して返す
string jsonResult = JsonConvert.SerializeObject(feedItems);
return new OkObjectResult(jsonResult);
}
上記の Azure Functions の Web API を実行すると、以下のようなJSON形式でデータが取得できます。
まとめ
はてなブックマークの人気エントリーを C# を用いた Azure Functions の Web API で JSON 形式で取得する方法の紹介しました。
ちなみに私は、エンジニアリングマネージャーとして「ハピネスチームビルディング」と名付けたチームの皆で主体的に楽しく成長する活動を実施しています。
ITエンジニア向け情報誌「Software Design」で連載している内容を以下で公開していますので、よろしければ、そちらも参照ください。
Twitterでも開発に役立つ情報を発信しています → @kojimadev