注意! 記事にはコードの一部があり、最も重要なアクションを説明していますが、プロジェクトのコードベースが複数変更されることに注意してください。 興味がある人はGitHubでソースを見つけることができます。
タスクを要素に分割します。
- アプリケーションの作成と承認。
- データを受信します。
- グラフの視覚化。
これに必要なもの:
- Python 3.4
- リクエスト
- d3
- Mozilla FireFox、ChromeではXMLHttpRequestを使用してローカルファイルをロードできないため( python -m http.server 8000を実行するユーザーはいません)
アプリケーションの作成と承認
VKontakte APIにアクセスするには、 スタンドアロンアプリケーションを作成する必要があります 。その後、必要なAPIメソッドを使用できます。これについては後で説明します。 ここでアプリケーションが作成されます - スタンドアロンアプリケーションを選択します 。 モバイルに送信された確認コードを入力するよう求められます。その後、アプリケーション管理ページに移動します。 [設定 ]タブで、 access_tokenのアプリケーションIDが役立ちます。
次に、アプリケーションを認証する必要があります。 このプロセスは3つのステージで構成されます。
VKでのユーザー認証
これを行うには、以下に示すようにURLを構成します。
https://oauth.vk.com/authorize?client_id=ID&scope=friends,offline&redirect_uri=https://oauth.vk.com/blank.html&display=page&v=5.21&response_type=token
vk.com/dev/auth_mobileを引用:
APP_ID-アプリケーションの識別子。
許可-要求されたアプリケーションの許可。
DISPLAY-サポートされている承認ウィンドウの外観:ページ、ポップアップ、モバイル。
REDIRECT_URI-access_tokenの送信先アドレス。
API_VERSIONは、使用しているAPIのバージョンです。
私たちの場合、PERMISSIONSは、サードパーティのサーバーからいつでも友人やAPIにアクセスできます(永久トークン)。 アドレスが正しく形成されている場合、ユーザー名とパスワードの入力を求められます。
データへのアクセス許可
次に、アプリケーションが必要な情報にアクセスできるようにします。
access_tokenの取得
アプリケーションの承認後、クライアントはREDIRECT_URIにリダイレクトされます。 必要な情報はリンクで囲まれます。
https://oauth.vk.com/blank.html#access_token=ACCESS_TOKEN&expires_in=0&user_id=USER_ID
settings.pyファイルを編集し、受け取ったaccess_tokenとuser_idをそこに挿入します 。 これで、VK APIにリクエストを送信できます。
データ検索
まず、この目的のために使用する方法を分析します。
グラフを作成するユーザーのIDに関する情報が少なくとも必要なので、 users.getは便利です。 これは、1つのIDと複数のフィールド、フィールドのリスト、必要な情報、および姓と名が傾く場合の両方を受け入れます。 base_info()メソッドはIDリストを取得し、写真を持つユーザーに関する情報を返します。
def base_info(self, ids): """read https://vk.com/dev/users.get""" r = requests.get(self.request_url('users.get', 'user_ids=%s&fields=photo' % (','.join(map(str, ids))))).json() if 'error' in r.keys(): raise VkException('Error message: %s. Error code: %s' % (r['error']['error_msg'], r['error']['error_code'])) r = r['response'] # , id settings.py if 'deactivated' in r[0].keys(): raise VkException("User deactivated") return r
これはfriends.getMutualからidを送信したい人にとって重要であり、膨大な数のリクエストを発生させます。 それについては後で詳しく説明します。
ここで、ユーザーの友達に関する情報を取得する必要があります。これはfriends.getメソッドで役立ちます。 ドキュメントにリストされているすべてのパラメーターのうち、 setting.pyとfieldsにあるuser_idを使用します 。 追加のフィールドは、友人のID、名前、姓、写真になります。 結局、ノードに写真のサムネイルを持たせたいのです。
def friends(self, id): """ read https://vk.com/dev/friends.get """ r = requests.get(self.request_url('friends.get', 'user_id=%s&fields=uid,first_name,last_name,photo' % id)).json()['response'] #self.count_friends = r['count'] return {item['id']: item for item in r['items']}
次に楽しい部分があります。
2人のユーザー間の共通の友人のIDリストはfriends.getMutualメソッドを返します。 friends.getのおかげで、idを取得するだけで、より高度な情報を既に取得しているため、これは良いことです。 しかし、 users.getを使用してさらに100から2つのリクエストを行うことを禁止する人はいません。 スキームは少し下にあります。
ここでfriends.getMutualの使用方法を決定しましょう。 ユーザーにN人の友人がいる場合は、N人のリクエストを作成して、友人ごとに共通の友人のリストを取得する必要があります。 さらに、1秒あたりの有効なリクエスト数を確保するために、遅延を作成する必要があります。
スキャンするIDに25人の友人がいるとします。
リクエストが多すぎるのは52件だけなので、 users.getはidリストを受け入れることができることに注意してください 。
25人の友人-28のリクエスト。ただし、上記のようにfriends.getのおかげですでに情報があります。
そして、ここでexecuteは便利であり、メソッドのシーケンスを実行できます。 単一のコードパラメーターがあり、APIメソッドへの最大25の呼び出しを含めることができます。
つまり、最終的に、 VKScriptのコードは次のようになります。
return { “id": API.friends.getMutual({"source_uid":source, "target_uid":target}), // * 25 ... };
API.friends.getMutualを常に使用せずにこのコードを短縮する方法を書く人がいます。
ここで、それぞれ25の友人IDのバッチで送信する必要があります。 この例では、回路は次のようになります。
しかし、forを使用して各友人をfriends.getMutualに送信し、users.getを介してより詳細な情報を見つけることができます。
次に、人間が読み取れる構造を作成します。ここでは、友人のIDと共通の友人のIDリストの代わりにfriends.getからの情報があります。 その結果、次のような結果が得られます。
[({ }, [{ }, { }]),({ }, None)]
辞書には、id、名、姓、写真がリストにあります-共通の友人の辞書、共通の友人がいない場合はなし。 タプルはすべて分割されています。
def common_friends(self): """ read https://vk.com/dev/friends.getMutual and read https://vk.com/dev/execute """ def parts(lst, n=25): """ - 25 """ return [lst[i:i + n] for i in iter(range(0, len(lst), n))] result = [] for i in parts(list(self.all_friends.keys())): # code ( execute) code = 'return {' for id in i: code = '%s%s' % (code, '"%s": API.friends.getMutual({"source_uid":%s, "target_uid":%s}),' % (id, self.my_id, id)) code = '%s%s' % (code, '};') for key, val in requests.get(self.request_url('execute', 'code=%s' % code)).json()['response'].items(): if int(key) in list(self.all_friends.keys()): # result.append((self.all_friends[int(key)], [self.all_friends[int(i)] for i in val] if val else None)) return result
そのため、友達のリストとその友達との共通の友達を表示するには、次を実行します。
python main.py
グラフの視覚化
選択肢はd3 、つまりCurved Linksにありました 。 これを行うには、次のようなjsonを生成します。
{ "nodes": [ {"name":"Myriel","group":1, "photo": "path"}, {"name":"Napoleon","group":1, "photo": "path"}, {"name":"Mlle.Baptistine","group":1, "photo": "path"} ], "links":[ {"source":1,"target":0,"value":1}, {"source":2,"target":0,"value":8} ] }
index.htmlを少し変更すると 、友人の写真がノードになります。
すぐにグラフを視覚化する場合:
python 2d3.py
miserables.jsonファイルがWebフォルダーに表示されます。 Mozilla FireFoxでindex.htmlを開くか、 python -m http.server 8000を使用してChromeで開くことを忘れないでください。
多数の友人がいると視覚化が遅くなるため、将来的にはWebGLの使用を検討しています。
これは私の友人の一人の友情グラフがどのように見えるかです。 コミュニケーションがすべてです。
もちろん、私は誰がより速く働くのだろうと思っていました。
私にインスピレーションを与えた記事はこう言います
私の333人の友人では、119秒かかりました。
この記事の執筆時点で、HimuraにはVKontakteに321人の友人がいました。 9秒かかりました( friends.getMutualだけでなく、プログラム全体)。
結論として
使用されるメソッドに関するすべての必要な情報は、VKontakteの寛大に書かれたドキュメントで見つけることができますが、いくつかのエラーが見つかりました:エラーコード15が記述されていません( 「error_msg」:「Access denied:user deactivated」、「error_code」:15 )、推測できます、その意味、およびfriends.getメソッドのドキュメントのuser_idではなくuid 。 2日後:
冒頭で述べたように、プロジェクトはGitHubで見つけることができます。他の誰かがそれを気に入ってくれてうれしいです。そして、たくさんのおいしいプルリクエストを受け取ります...
UPD(2014年5月27日):
WTFRU7 が 私を 促し たので、ストアドプロシージャを使用する機能を追加しました。 これを行うには、 リンクをたどってください 。
getMutualストアドプロシージャを作成します。 execute_getMutual.jsの内容をフォームにコピーして保存します。 新しいバージョンをダウンロードすることを忘れないでください。 スキームの最終形式は次のとおりです。
UPD(2014年6月16日):
無制限のトークンを取得します。
UPD(2014年7月11日):
説明スキームが追加されました。
UPD(2014年11月14日):
継続