- はじめに -
Qiitaは、プログラミングに関する知識を記録・共有するためのサービスです。
Qiitaアカウントには企業情報が紐付いている場合があり、Qiitaの様々な記事から情報を取得し分析する事で「機械学習を記事を多くストックしている勉強熱心な会社はここだ!」等といった事が分かるのではないかという思いから、Qiitaのアカウント情報を取得するスクリプトを書きました。
その時のただのメモです。
- Qiita API -
QiitaにはAPIが存在します。
以下のQiita記事でAPIのPythonクライアントを書いている人が既に居たので、こちらを利用します。
Qiita API v2のPythonラッパー実装した - Qiita
pipで導入します。
pip install qiita_v2
以下から「個人用アクセストークン」にread権限を付けて発行します。
https://qiita.com/settings/applications
その際表示されるtokenをメモしておきます。
これで後はいいね数を取得するだけなのですが、実際にこのPythonクライアントの中を見てみると、APIに存在する「いいね数の取得」に対応していませんでした。
qiita_py/client.py at master · petitviolet/qiita_py · GitHub
仕方ないので以下のようにメソッドを追加しつつ、記事のID(stock_id)に対していいねしたユーザとストックしたユーザを取得するスクリプトを書きました。
from qiita_v2.client import QiitaClient def list_item_likes(self, item_id, params=None, headers=None): return self.get("/items/{}/likes".format(item_id), params, headers) QiitaClient.list_item_likes = list_item_likes stock_id = '' token = '' client = QiitaClient(access_token=token) # いいねしたユーザ res = client.list_item_likes(stock_id) like_users = [x["user"]['id'] for x in res.to_json()] for i in range(int(int(res.result_count)/20)): res = client.list_item_likes(stock_id, params={"page":i+2}) like_users += [x["user"]['id'] for x in res.to_json()] # ストックしたユーザ res = client.list_item_stockers(stock_id) stock_users = [x["id"] for x in res.to_json()] for i in range(int(int(res.result_count)/20)): res = client.list_item_stockers(stock_id, params={"page":i+2}) stock_users += [x['id'] for x in res.to_json()]
APIの制限は認証している状態で1000回/時、そうでなければIPアドレスごとに60回/時です。
数記事であれば大丈夫でしょう。
- ユーザ情報の取得 -
list_item_likes、list_item_stockersのresponseとなるjsonには""organization""なるキーが含まれています。
しかし、Qiitaプロフィールで表示されるものには「organization」と「Organizations」が存在しており、Qiita Organizationに登録されていない会社は前者、登録されている会社は後者に含まれ、APIでは前者しか取得できないのが現状です。
データ分析のため、後者のOrganizationsを取得したい事からユーザ情報取得のスクリプトを書きました。
import requests from bs4 import BeautifulSoup import time def get_accounts_org(accounts): data = {} for account in accounts: res = requests.get("https://qiita.com/{}".format(account)) bs = BeautifulSoup(res.text, "lxml") organization = [y.attrs["content"] for y in [x.find("meta") for x in bs.findAll("li", attrs={"itemprop":"memberOf"})]] host = [x.text.strip() for x in bs.findAll("div", attrs={"class": "newUserPageProfile_info_body"}) if x.find("i", attrs={"class": "fa-building-o"}) is not None] data.update({account: {"org":organization, "host":host}}) time.sleep(5) return data like_orgs = get_accounts_org(like_users)
like_usersリストに入っているユーザ情報から「organization(host)」「Organizations(org)」を取得する事ができました。
- 実際に見てみる -
実際に「記事にいいねしたユーザ」について見てみました。
テストとして以下の記事を選びました。
技術共有サービスQiitaで開催されていた2017年Advent Calenderにて、いいね獲得数ランクによってIBM、Greenという会社から表彰された記事ですので、いいね数もそれ相応かと思います。
qiita.com
集計は適当にCounterで
from collections import Counter d = Counter() for y in [(k,v) for k,v in like_orgs.items() if v["org"] or v["host"]]: for x in y[1]["org"]: d[x]+=1 for x in y[1]["host"]: if x not in y[1]["org"]: d[x]+=1 for x in d.most_common(10): print(x)
結果は以下のようになりました
('株式会社リブセンス', 21) ('株式会社ミクシィ', 5) ('フューチャーアーキテクト株式会社', 4) ('フリーランス', 4) ('スタディプラス株式会社', 4) ('株式会社オールアバウト', 3) ('株式会社モバイルファクトリー', 3) ('アイレット株式会社(cloudpack)', 3) ('IBM Japan', 3) ('株式会社ゆめみ', 3)
記事の著者もリブセンスという会社ですが、やはり同僚の記事はいいねしたくなる傾向にあるのでしょうか。
私も社内SNSに「アイツの記事バズってるよww」みたいに同僚の記事を貼る人間を見たことがあるので、そういう影響もあるでしょう。
いかんせん、データ数が少ないので何も言えませんが、取得して見るまではできました。
- Qiitaの特定タグのついた記事を集める -
Qiitaには、記事にタグを付ける機能があります。
特定のタグがついているAPIを叩くため、上記と同じくQiitaClientに新しくメソッドを追加して実行します。
from qiita_v2.client import QiitaClient def get_tag_items(self, item_id, params=None, headers=None): return self.get("/tags/{}/items".format(item_id), params, headers) QiitaClient.get_tag_items = get_tag_items tag_name = '機械学習' token = 'hoge' client = QiitaClient(access_token=token) res = client.get_tag_items(tag_name)
ひとまず機械学習タグのついた記事を100 * 20 件分取得してみます。
QiitaのAPI制限を考えると、一度取得した情報はcacheしておくのが正解だと思います(以下では一切やっていません)。
ids = [] users = [] for i in range(100): res = client.get_tag_items("機械学習", params={"page":i+1}) ids += [x["id"] for x in res.to_json()] users += [x["user"]["id"] for x in res.to_json()]
上記スクリプトにより、機械学習タグのついた記事を投稿しているユーザ、投稿された記事のidリストが取得できました。
- 機械学習記事を投稿、いいねしたユーザ情報を見てみる -
前述したget_accounts_org関数を利用して、機械学習タグ付き記事を投稿したユーザが属する企業、機械学習タグ付き記事をいいねしたユーザが属する企業について、Countをとってみます。
以下が直近2000記事で見た「機械学習タグのついた記事」を多く投稿する社員のいる企業です。
('TIS株式会社', 6) ('株式会社トップゲート', 5) ('株式会社ブレインパッド', 4) ('Team AI', 4) ('株式会社リブセンス', 4) ('株式会社 ドワンゴ', 4) ('Nuco Inc.', 4) ('株式会社Nextremer', 4) ('株式会社アカツキ', 3) ('株式会社クラウドワークス', 3)
Qiitaで機械学習記事といえば、あのアカウントとあのアカウントとあのアカウントかな…?という一覧になりました。
データが増加してもQiita活動家が社内に居るか居ないか、に寄ってしまいそうです。
これ以下はほぼ1~2だったので面白い結果を得るまで数を増やすのは少し大変そうです。
以下は直近2000記事で見た「機械学習タグのついた記事」にいいねを多くした社員のいる企業です。
('株式会社リブセンス', 31) ('Fringe81株式会社', 24) ('株式会社クラウドワークス', 22) ('TIS株式会社', 21) ('株式会社VASILY', 16) ('株式会社リクルートライフスタイル', 12) ('Retty株式会社', 12) ('フューチャーアーキテクト株式会社', 11) ('P&D – Planning and Development – ', 11) ('株式会社アカツキ', 11) ('Shinonome, inc.', 11) ('株式会社LIFULL', 10) ('株式会社トップゲート', 10) ('株式会社オールアバウト', 10) ('株式会社ゆめみ', 9) ('フリーランス', 8) ('株式会社 ドワンゴ', 8) ('株式会社Nextremer', 8) ('株式会社ACCESS', 8) ('株式会社エイチームライフスタイル', 8) ('株式会社エイチームブライズ', 8) ('株式会社BitStar', 8) ('The University of Tokyo', 7) ('株式会社div(ディブ).', 7) ('株式会社WACUL', 6) ('株式会社Fusic', 6) ('Kyoto University', 6) ('株式会社Rosso', 6) ('株式会社サイバーエージェント', 6) ('エムスリー株式会社', 6)
リブセンスという会社はQiitaに相当な時間を使っているという事がわかりました。
こちらも上位は「あのアカウントかな…」と個人が見え隠れする結果となりました。
こちらは、東大、京大やフリーランスがトップ30に入ってきた辺りを見るに、データが集まれば少し改善しそうです。