nukorouのゆるガバ帳

ゆるくガバく適当に

法人インフォメーションAPIをRubyで取得する

はじめに

久しぶりの更新になってしまいました。

昨日(2017年1月19日)、法人インフォメーション(略称:法人インフォ)が公開されたので、Rubyで取得するところまでやってみたいと思います。

準備

このAPISPARQL(スパークル)というRDFのクエリ言語でクエリを書くみたいです。ちなみにRDFもSPARQLも初めて扱います。(SQLはSELECTとFROMぐらしかわかってません。)

gem install linkeddata

RDFを扱うためのモジュールをまとめてインストールしてくれるそうです。

コード

ざっくり説明しますと、get_all_hojin_id関数で法人番号(ID)を取得して、get_hojin_base_info関数にIDを渡しています。

SPARQLでは、?変数名が変数になるようです。

情報てんこもりのget_hojin_base_info関数は最初は理解しにくいかと思ったので、最小構成のSPARQLの例示として、get_name関数も用意しました。

あと、get_all_hojin_id関数では実は全部のIDは取得できません。SQLが分かる人には当たり前なのかもしれませんが、OFFSETが必要です。あえて、把握しにくくになるからOFFSETは書かなかったのですが、別に問題ないですよね。

あと、地味にOPTIONALってのは重要です!これがないと、全部の情報が必須の条件になってしまうため、ヒットしません。これは、必須ではないよって明示しているのが、OPTIONALみたいです。ここでつまりました。

require 'sparql/client'

def get_all_hojin_id(client=nil, limit)
  if client.nil?
    client = SPARQL::Client.new('http://api.hojin-info.go.jp/sparql')
  end
  query_string = "
    PREFIX hj: <http://hojin-info.go.jp/ns/domain/biz/1#>
    PREFIX ic: <http://imi.go.jp/ns/core/rdf#>

    SELECT ?id FROM <http://hojin-info.go.jp/graph/hojin>
    WHERE {
      ?s hj:法人基本情報 ?key .
      ?key ic:ID/ic:識別値 ?id .
    }
    limit #{limit}
  "
  results = client.query(query_string)
end


def get_name(client=nil, id)
  if client.nil?
    client = SPARQL::Client.new('http://api.hojin-info.go.jp/sparql')
  end

  q1 = "
    PREFIX hj: <http://hojin-info.go.jp/ns/domain/biz/1#>
    PREFIX ic: <http://imi.go.jp/ns/core/rdf#>

    SELECT ?name FROM <http://hojin-info.go.jp/graph/hojin>
    WHERE {
      ?s hj:法人基本情報 ?key .
      ?key ic:ID/ic:識別値 '#{id}' .
      ?key ic:名称/ic:表記 ?name
    }
  "
  results = client.query(q1)

end

#個人的に必要そうな情報しか取得してません
def get_hojin_base_info(client=nil, id)
  if client.nil?
    client = SPARQL::Client.new('http://api.hojin-info.go.jp/sparql')
  end

  query_string = "
    PREFIX hj: <http://hojin-info.go.jp/ns/domain/biz/1#>
    PREFIX ic: <http://imi.go.jp/ns/core/rdf#>

    SELECT DISTINCT * FROM <http://hojin-info.go.jp/graph/hojin>
    WHERE {
      ?s hj:法人基本情報 ?key .
      ?key ic:ID/ic:識別値 '#{id}' .
      ?key ic:ID/ic:識別値 ?id .
      OPTIONAL{?key ic:名称/ic:表記 ?name .}
      OPTIONAL{?key ic:住所/ic:表記 ?address .}
      OPTIONAL{?key ic:住所/ic:郵便番号 ?zip_code .}
      OPTIONAL{?key ic:住所/ic:都道府県 ?prefecture .}
      OPTIONAL{?key ic:住所/ic:市区町村 ?city .}
      OPTIONAL{?key ic:住所/hj:丁目番地等 ?chome .}
      OPTIONAL{?key ic:活動状況/ic:発生日 ?start_day .}
      OPTIONAL{?key hj:更新日時/ic:標準型日時 ?updated_at .}
    }
  "
  results = client.query(query_string)
end

if __FILE__ == $0
  client = SPARQL::Client.new('http://api.hojin-info.go.jp/sparql')
  ids = get_all_hojin_id(client, limit=10)

  ids.each do |i|
    name = get_name(client, i.id.to_s)[0].to_h[:name].to_s
    puts name

    base_info = get_hojin_base_info(client, i.id.to_s)[0].to_h
    puts "id:#{base_info[:id]} name:#{base_info[:name]} address:#{base_info[:address]}\n\n"
  end
end

改良するなら

公式PDFの、追加したいデータ名のプロパティパスっていうカラムをコピペして、変数名を自分でつけたらいいと思います。って誰でもわかるかw

参考

hanzomemo: DBpedia日本語版:SPARQLをRubyから実行

RDF.rbを用いたRDFデータの読み込み - Qiita