MA10に向けて何か作ろうかなと思って各社提供のWebAPIを色々と触っています。本記事では、KPI社のC#を使って政治データAPIの政治家データを取得します。
事前準備
政治データAPIはレスポンスにxmlとjsonを選択することが可能です。どちらのフォーマットでも対応しても良かったのですが、PCLでどのプラットフォームでも使いやすいJSON.NETが存在していることを考えて、jsonでレスポンスを取得することに決めました。
- Visual Studioでプロジェクトを作成する
- NuGetでJSON.NETをインストールする
政治家情報の取得処理を実装する
特に認証処理は必要ないようですので、以下のURLみたいにパラメータをつなげていくだけでデータの取得は可能です。
どのようなjsonが取得できるかというと、下記のようなレスポンスです(見やすいように改行させています)。
[ { "area": "北海道 1区", "pubDate": "Mon, 08 Sep 2014 04:39:01 GMT", "category": "衆議院議員", "linkname": "ホームページ", "link": "http://funahashi-toshimitsu.jp/", "seitou": "自民党", "hatsu_tousen": "2012年", "tousen_kaisu": "衆議院1回 / 参議院0回", "name": "船橋 利実", "id": 1, "yomi": "ふなはし としみつ", "birth": "1960年11月20日" }, { "area": "北海道 2区", "pubDate": "Mon, 08 Sep 2014 04:39:01 GMT", "category": "衆議院議員", "linkname": "ホームページ", "link": "http://tyoshikawa.com/", "seitou": "自民党", "hatsu_tousen": "1996年", "tousen_kaisu": "衆議院4回 / 参議院0回", "name": "吉川 貴盛", "id": 2, "yomi": "よしかわ たかもり", "birth": "1950年10月20日" } ]
素直なjsonですのでJSON.NETでデシリアライズさせましょう。政治家情報を扱うためのクラスクラスを定義します。クラス名をPolitician
としました。
using Newtonsoft.Json; using System; namespace SeijiParser { public class Politician { [JsonProperty("id")] public int Id { get; set; } [JsonProperty("area")] public string Area { get; set; } [JsonProperty("pubDate")] public string PubDate { get; set; } [JsonProperty("category")] public string Category { get; set; } [JsonProperty("linkname")] public string Linkname { get; set; } [JsonProperty("link")] public string Link { get; set; } [JsonProperty("seitou")] public string Seitou { get; set; } [JsonProperty("hatsu_tousen")] public string HatsuTousen { get; set; } [JsonProperty("tousen_kaisu")] public string TousenLaisu { get; set; } [JsonProperty("name")] public string Name { get; set; } [JsonProperty("Yomi")] public string NameYomi { get; set; } [JsonProperty("birth")] public string Birth { get; set; } }
次に政治データAPIを叩きます。
var parm = new Dictionary<string, object>(); parm["type"] = 1; parm["count"] = "50000"; parm["format"] = "json"; var urlParam = string.Join("&", parm.Select(item => string.Format("{0}={1}", item.Key, item.Value))); var url = string.Format("http://seiji.kpi-net.com/api/?{0}", urlParam); var client = new WebClient(); client.Encoding = System.Text.UTF8Encoding.UTF8; var text = client.DownloadString(url); var result = JsonConvert.DeserializeObject<List<Politician>>(text);
これだけで政治家情報の取得ができます。
政治データAPIの残念なところ
TwitterでAPIがダメダメだぁ……と呟いていたところ、なかじ先生が「どこが悪いのか教えてよ!」って食いついてきた!「おぉ、なかじさんも政治データAPIに興味があるのか……」と思い、一通り使ってみて気になったところ残念なところを挙げていきます。
政治データAPIのリクエストとレスポンスのパラメータは以下のページをご参照ください。
地域で絞り込んでの検索ができないところ
地域だけではないのですが、データのフィルタパラメータが衆議院議員や区長などの区分type
しかありません。
リクエストパラメータのcount
を使うとデータ取得件数を指定することができるのですが、衆議院議員を先頭から3人分という取得する方法にしか使えず、実質件数の絞り込みを使う理由がありません。よって前述した通り、毎回Maxであろう件数を指定してリクエストすることになります。
僕はこの情報のために一旦自分のDBに情報を格納した上で、ページ分割することを想定せざるを得ませんでした。
せめてskipなどで取得するレコードを飛ばせられるなら意味があると思う。あ、ひょっとして更新順にソートされていれば現状の仕様でも良いのかもしれない(未確認)。
取得できるデータの不備、不整合
データの精査ができていない(or スクレイピングミスな)のか、所々改行コードなどの変なデータが混じっていたりします。
もうひとつ、データの整合性が取れていないところが気になりました。これはデータ提供元であるKPI社のルールが提示されてないのでどう判断して良いのか悩みました。
例えば、関ケ原町の「ケ」や茅ヶ崎市の「ヶ」の部分です。総務省の「全国地方公共団体コード」では、関ケ原町・茅ヶ崎市なのですが、政治データAPIから返ってくる値は関ヶ原町・茅ヶ崎市となっており、自治体の正式名称と異なった表記になっています。
- Areaに改行コードが混じっている
- Areaに整合性がない
- 市長と区長には都道府県名が入っていないが、町長と村長には都道府県名が入っている*1
- Areaで返される自治体の名称は正式名称なのかどうか分からない
- リンク情報が単一の物しか提供されない
- いまどき政治家と言ってもウェブサイト、ブログ、FacebookとTwitterなど、複数の情報発信媒体を持っている
2014/9/14追記
市レベルだと名前はユニークだと、重複が無いのではないだろうかと書いていたのですが、府中市と伊達市が重複しているのが分かりました……どこの市の市長かわかるように判別してほしかったです。
*1:これは市の名前はユニークだから問題なしという判断なのか?