1

facebook-graph-api から json データを取得しています。

  1. 私の友達との関係
  2. 私の友達同士の関係。

現在、私のプログラムは次のようになっています (Python 疑似コードでは、プライバシーのためにいくつかの変数が変更されていることに注意してください)。

import json
import requests

# protected
_accessCode = "someAccessToken"
_accessStr = "?access_token=" + _accessCode
_myID = "myIDNumber"

r = requests.get("https://graph.facebook.com/" + _myID + "/friends/" + _accessStr)
raw = json.loads(r.text)

terminate = len(raw["data"])

# list used to store the friend/friend relationships
a = list()

for j in range(0, terminate + 1):
    # calculate terminating displacement:
    term_displacement = terminate - (j + 1) 
    print("Currently processing: " + str(j) + " of " + str(terminate))
    for dj in range(1, term_displacement + 1):
        # construct urls based on the raw data:
        url = "https://graph.facebook.com/" + raw["data"][j]["id"] + "/friends/" + raw["data"][j + dj]["id"] + "/" + _accessStr
        # visit site *THIS IS THE BOTTLENECK*:
        reqTemp = requests.get(url)
        rawTemp = json.loads(reqTemp.text)
        if len(rawTemp["data"]) != 0:
            # data dumps to list which dumps to file
            a.append(str(raw["data"][j]["id"]) + "," + str(rawTemp["data"][0]["id"]))

outputFile = "C:/Users/franklin/Documents/gen/friendsRaw.csv"
output = open(outputFile, "w")

# write all me/friend relationship to file
for k in range(0, terminate):
    output.write(_myID + "," + raw["data"][k]["id"] + "\n")

# write all friend/friend relationships to file
for i in range(0, len(a)):
    output.write(a[i])

output.close()

つまり、最初に私のページを呼び出して、友達リストを取得します (これは、access_token を使用して Facebook API を介して許可されます)。友達の友達リストを呼び出すことは許可されていませんが、上の友達との関係を要求することで回避できます。私のリストと私のリストの別の友人。そのため、パート 2 (二重の for ループで示されます) では、友人 a が b の友人でもあるかどうかを確認するために別の要求を行っています (どちらも私のリストに含まれています)。その場合、友人 a の名前を持つ長さ 1 の json オブジェクトが存在します。

しかし、約 357 人の友人の場合、文字通り何千ものページ リクエストを行う必要があります。つまり、プログラムは json リクエストを待つだけで多くの時間を費やしています。

私の質問は、これをより効率的に書き直すことができるかということです。現在、セキュリティ上の制限により、フレンドのフレンド リスト属性の呼び出しは許可されていません。APIがこれを許可するようには見えません。これをより速く実行できるPythonのトリックはありますか? 多分平行?

修正されたコードを更新して、回答セクションの下に貼り付けます。

4

2 に答える 2

1

更新これが私が思いついた解決策です。FQLの提案について@DMCSに感謝しますが、私は自分が持っていたものを使用することにしました。実装を検討する機会があれば、FQL ソリューションを投稿します。ご覧のとおり、このメソッドはより凝縮された API 呼び出しを利用しているだけです。

ちなみに、今後の参考のために、API 呼び出しの制限は、トークンごとおよび IP ごとに 600 秒あたり 600 回の呼び出しであるため、一意の IP アドレスごとに、一意のアクセス トークンを使用して、呼び出しの数は 1 秒あたり 1 回の呼び出しに制限されます。@Gerrat の非同期呼び出しでそれが何を意味するのかはわかりませんが、それはあります。

import json
import requests

# protected
_accessCode = "someaccesscode"
_accessStr = "?access_token=" + _accessCode
_myID = "someidnumber"

r = requests.get("https://graph.facebook.com/" 
    + _myID + "/friends/" + _accessStr)
raw = json.loads(r.text)

terminate = len(raw["data"])

a = list()
for k in range(0, terminate - 1):
    friendID = raw["data"][k]["id"]
    friendName = raw["data"][k]["name"]
    url = ("https://graph.facebook.com/me/mutualfriends/" 
        + friendID + _accessStr)
    req = requests.get(url)
    temp = json.loads(req.text)
    print("Processing: " + str(k + 1) + " of " + str(terminate))
    for j in range(0, len(temp["data"])):
        a.append(friendID + "," + temp["data"][j]["id"] + "," 
            + friendName + "," + temp["data"][j]["name"])

# dump contents to file:
outputFile = "C:/Users/franklin/Documents/gen/friendsRaw.csv"
output = open(outputFile, "w")
print("Dumping to file...")
# write all me/friend relationships to file
for k in range(0, terminate):
    output.write(_myID + "," + raw["data"][k]["id"] 
        + ",me," + str(raw["data"][k]["name"].encode("utf-8", "ignore")) + "\n")

# write all friend/friend relationships to file
for i in range(0, len(a)):
    output.write(str(a[i].encode("utf-8", "ignore")) + "\n")

output.close()  
于 2013-01-03T21:31:38.370 に答える
0

これはおそらく最適ではありませんが、リクエストの非同期メソッドを使用するようにコードを少し調整しました (未テスト):

import json
import requests
from requests import async

# protected
_accessCode = "someAccessToken"
_accessStr = "?access_token=" + _accessCode
_myID = "myIDNumber"

r = requests.get("https://graph.facebook.com/" + _myID + "/friends/" + _accessStr)
raw = json.loads(r.text)

terminate = len(raw["data"])

# list used to store the friend/friend relationships
a = list()

def add_to_list(reqTemp):
    rawTemp = json.loads(reqTemp.text)
    if len(rawTemp["data"]) != 0:
        # data dumps to list which dumps to file
        a.append(str(raw["data"][j]["id"]) + "," + str(rawTemp["data"][0]["id"]))

async_list = []
for j in range(0, terminate + 1):
    # calculate terminating displacement:
    term_displacement = terminate - (j + 1) 
    print("Currently processing: " + str(j) + " of " + str(terminate))
    for dj in range(1, term_displacement + 1):
        # construct urls based on the raw data:
        url = "https://graph.facebook.com/" + raw["data"][j]["id"] + "/friends/" + raw["data"][j + dj]["id"] + "/" + _accessStr

        req = async.get(url, hooks = {'response': add_to_list})
        async_list.append(req)

# gather up all the results
async.map(async_list)

outputFile = "C:/Users/franklin/Documents/gen/friendsRaw.csv"
output = open(outputFile, "w")
于 2012-12-31T22:00:23.603 に答える