Boostnoteのスターを調べる

今月部屋から一歩も出ずにらき☆すたを4周見たasmsuechanです。今5周目の10話です。ここではスターの話をします。

プログラマー向けノートアプリであるBoostnoteはOSSとして https://github.com/BoostIO/Boostnote に公開されています。今日はこのリポジトリにスターをつけた人の居住国をグラフにしてみます。

スターしたユーザーの居住地をグラフにする

早速ですがスターしたユーザーのlocationを集めて世界地図にプロットするとこのようになります(公開 - 現在まで)



ちょっと見にくいので棒グラフにします。



中国が一番多くてその次にアメリカ、次が日本、といった感じで50%程を占めています。にしても米中が思ったより多いです。

スターしたユーザーの取得、解析

スターしたユーザーの取得は以下のようなスクリプトからGitHubのAPIを叩いています。

Pythonである理由は全然ありません。その時の気分です。雑ですがコードはここにあります。

from github import Github
from dotenv import load_dotenv, find_dotenv
import os
import csv

load_dotenv(find_dotenv())
GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN")

g = Github(login_or_token=GITHUB_ACCESS_TOKEN, per_page=100)

# Get stargazers of the repository
repository = g.get_repo('BoostIO/Boostnote')
stargazers = repository.get_stargazers()
for page_number in 50:
  for stargazer in stargazers.get_page(page_number):
    f = open('stargazers.csv', 'a')
    writer = csv.writer(f, lineterminator='\n')
    csvlist = []
    csvlist.append(stargazer.login)
    csvlist.append(stargazer.location)
    writer.writerow(csvlist)
    f.close()
    print(stargazer.location)


これでユーザーのidとそのlocationが取得できました。(csvに吐き出しました)

ですがここで問題点が。ユーザーのlocationは必ずしも自分にとって都合のいい 'Japan' や 'China' や 'America' などの形式ではないということです。人によってはもっと細かい都市(例えば'Tokyo'や'Nakano'など)を設定しています。というかむしろこっちが大多数です。

そこでこのlocationを適切に国名へと変換するためにGoogle Maps Geocoding APIを使用します。

GeocodingAPIはhttps://maps.googleapis.com/maps/api/geocode/json?address=Washinomiya+Kuki-shi&key=YOUR_API_KEYの形式でリクエストを送ることにより情報を得ることができます。

例えばパラメーターのaddressaddress=Washinomiya+Kuki-shiとしてcurlを投げると以下のようなjsonを返してくれます。

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Washinomiya",
               "short_name" : "Washinomiya",
               "types" : [ "political", "sublocality", "sublocality_level_1" ]
            },
            {
               "long_name" : "Kuki",
               "short_name" : "Kuki",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Saitama Prefecture",
               "short_name" : "Saitama Prefecture",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Japan",
               "short_name" : "JP",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "340-0217",
               "short_name" : "340-0217",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "Washinomiya, Kuki, Saitama Prefecture 340-0217, Japan",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 36.107551,
                  "lng" : 139.6791901
               },
               "southwest" : {
                  "lat" : 36.0785273,
                  "lng" : 139.6443736
               }
            },
            "location" : {
               "lat" : 36.1003427,
               "lng" : 139.6614365
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 36.107551,
                  "lng" : 139.6791901
               },
               "southwest" : {
                  "lat" : 36.0785273,
                  "lng" : 139.6443736
               }
            }
         },
         "place_id" : "ChIJfcsG4zjKGGARBnLnJiLVPM0",
         "types" : [ "political", "sublocality", "sublocality_level_1" ]
      }
   ],
   "status" : "OK"
}

ここで真ん中あたりにある formatted_arress を見てみると "formatted_address" : "Washinomiya, Kuki, Saitama Prefecture 340-0217, Japan" となっています。国名まで補完できていますね。これから不完全なlocationを国名に変換しました。この辺のコードはここに置いてあります。これもまた雑ですが。

最終的には以下のような配列になりました。これをGoogleのGeochartにプロットしたのが上のグラフです。array[0]が国名でarray[1]が総数です。(多いので一部です)

[["China", 366], ["USA", 365], ["Japan", 199], ["Germany", 103], ["France", 74], ["Brazil", 69], ["India", 67], ["UK", 59], ["South Korea", 58], ["Canada", 56], ["Russia", 45], ["Australia", 32], ["Turkey", 32], ["Spain", 32], ["Taiwan", 28], ["United States", 24], ["504-42 Yunam-dong", 22], ["Mexico", 21], ["Netherlands", 20], ["Poland", 20], ["Portugal", 18], ["Italy", 18], ["Switzerland", 17], ["Indonesia", 17], ["United Kingdom", 15], ["Vietnam", 15], ["Thailand", 14], ["Ukraine", 14], ["Austria", 11], ["Hong Kong", 11], ["Singapore", 10], ["Sweden", 10], ["Belgium", 10], ["Argentina", 10], ["Denmark", 10], ["Colombia", 9], ["Greece", 9]]

"USA"と"United Stats"があったりそういう被りは暖かみのある手作業でくっつけていきました。

ちなみにこのarrayの下の方には謎にJA甲府市やら赤坂の美容室やらの住所が出てました。謎です。

中国勢力

最近(ここ3か月程度)中国からのスターが明らかに増えています。体感半分くらいは中国の方からのスターだと思っています。これも検証してみます。

まず、3か月のうちにスターをしたユーザーを取得する必要があります。

ですが、GitHubはスターをした時間までは返してくれません。ですので少し工夫をします。

まず、 http://www.timqian.com/star-history/#BoostIO/Boostnote この便利なサービスを見て、3か月前のスター数を調べます。次にこれを現在のスター数から引きます。こうして出た値がこの3か月でついたスターの数です。

あとは簡単で、先ほど出した全体のスターしたユーザーの下からその人数を引っ張ってくれば完成です。合計1600くらいでした。

f:id:hyottokoaloha:20170719141633p:plain

これもまたグラフにしてみます。




これも一部ですが、合計1012の中で中国が27%を占めています。大きいですね。

実は中国からのスターが増えた理由には心当たりがあって、中国版Twitterのweiboのある投稿が拡散されていたからでした。

f:id:hyottokoaloha:20170719142130p:plain

これからもっと伸びてたみたいです。このおかげでGitHubのトレンドにも乗って本当に驚きました。

感想

locationを設定していない人も結構いるのでそういう人はリポジトリのdescriptionを拾って一番多い言語または英語の次に多い言語からある程度絞れそうな気もしています。

中国勢力すごいですね。個人的にはこれから中国進出したいです。

この記事を書いている間に15話まで見終わりました。