我有一个facebook Graph API调用来获取Facebook用户提要:
dynamic myFeed = await fb.GetTaskAsync(
("me/feed?fields=id,from {{id, name, picture{{url}} }},story,picture,link,name,description," +
"message,type,created_time,likes,comments")
.GraphAPICall(appsecret_proof));
以上返回了一些最新的用户帖子,其中包括21个或22个帖子,但不是完整的用户帖子列表。我搜索了一种使用facebook分页迭代用户提要的方法,我最终找到了适用于facebook Offset分页的解决方案。
dynamic myFeed = await fb.GetTaskAsync(
("me/feed?fields=id,from {{id, name, picture{{url}} }},story,picture,link,name,description," +
"message,type,created_time,likes,comments")
.GraphAPICall(appsecret_proof), new {limit = "1000", offset = "21" });
这让我更接近我想要实现的目标,但我认为这不是理想的做法,也不会返回所有用户帖子。有没有解决方法?请帮忙。
P.S:我正在使用Facebook C#SDK。
更新1:根据杰里米的回答。似乎facebook光标分页是我的要求唯一正确的选项。我想知道C#facebook sdk是否提供任何功能来迭代下一个边缘,这样我就可以在一个电话中获得所有的帖子,这有什么可能的解决方案吗? PS:我已经多次通过facebook API文档,我知道Nodes,Edges和Fields到底是什么,唯一不幸的是facebook还不支持C#SDK,我无法找到适当的文档Facebook C#SDK也是。
首先是一些术语:
节点 - 基本上是“事物”,例如用户,照片,页面,评论 边缘 - “事物”之间的联系,例如Page's Photos或Photo's Comments 字段 - 有关这些“事物”的信息,例如某人的生日或页面的名称
当您向节点或边缘发出API请求时,通常不会在单个响应中收到该请求的所有结果。这是因为某些响应可能包含数千个对象,因此默认情况下大多数响应都是分页的。
要获得用户的所有帖子,您有3个选项:
基于游标的分页
基于游标的分页是最有效的分页方法,应尽可能使用。游标是指随机字符串,用于标记数据列表中的特定项目。除非删除此项,否则光标将始终指向列表的同一部分,但如果删除项,则无效。因此,您的应用不应存储任何旧游标或假设它们仍然有效。
在读取支持光标分页的边时,您将看到以下JSON响应:
{
"data": [
... Endpoint data is here
],
"paging": {
"cursors": {
"after": "MTAxNTExOTQ1MjAwNzI5NDE=",
"before": "NDMyNzQyODI3OTQw"
},
"previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
"next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
}
}
要获得用户的所有帖子,您可以继续浏览“下一个”边缘(插入新项目)。当我将整个组转储到RDBMS进行统计分析时,我就是这样做的。通常你会看到你已经遇到的节点的边缘,这就是我提到UPSERT的原因(如果存在则更新,否则插入)。
基于时间的分页
时间分页用于使用指向数据列表中特定时间的Unix时间戳来浏览结果数据。
使用使用基于时间的分页的端点时,您将看到以下JSON响应:
{
"data": [
... Endpoint data is here
],
"paging": {
"previous": "https://graph.facebook.com/me/feed?limit=25&since=1364849754",
"next": "https://graph.facebook.com/me/feed?limit=25&until=1364587774"
}
}
要获得所有用户帖子,请不断回顾。此方法将按顺序为您提供帖子,但可能希望它们通过FaceBooks边缘算法按顺序返回。
基于偏移量的分页
当您不关心年表并且只想要返回特定数量的对象时,可以使用偏移分页。仅当边缘不支持光标或基于时间的分页时才应使用此选项。
所以你在Offset中发现的是你最接近你想要的股票标准分页。然而:
所有API调用都不支持基于偏移的分页。为了获得一致的结果,我们建议您使用我们在响应中返回的上一个/下一个链接进行分页。
您可以在FB API文档中阅读所有这些内容。
https://developers.facebook.com/docs/graph-api/overview/ https://developers.facebook.com/docs/graph-api/using-graph-api/
最后,在做了一些研究和阅读一些博客之后,我发现没有直接来自facebook的API CAlls
一次获取所有用户馈送帖子。要实现该功能,要么必须按照Jeremy Thomson的建议进行无限滚动,要么迭代不同的facebook数据页,无论facebook pagination
支持哪种edge
类型。至于我想要一个没有用户干扰/动作的过程,我肯定会选择使用while
循环遍历facebook数据页面的第二个选项。要做到这一点,我们首先需要我们的两个最重要的参数(facebook access_token
+(facebook appsecret_proof
),如下所述:
var appsecret_proof = access_token.GenerateAppSecretProof();
var fb = new FacebookClient(access_token);
值得记住的点:facebook
access_token
是由HttpContext
类生成的。
facebook API
电话将获得用户的第一个25个馈线帖子,如下所示:
dynamic myFeed = await fb.GetTaskAsync(
("me/feed?fields=id,from {{id, name, picture{{url}} }},story,picture,link,name,description," +
"message,type,created_time,likes,comments")
.GraphAPICall(appsecret_proof));
上面的API
调用返回得到一个Json
数组,应该通过Model View
属性进行水合,如下所示:
var postList = new List<FacebookPostViewModel>();
foreach (dynamic post in myFeed.data)
{
postList.Add(DynamicExtension.ToStatic<FacebookPostViewModel>(post));
}
直到这里一切都很清楚,最重要的部分肯定是取得所有Facebook用户的帖子现在正在行动。为此,我们需要将string
NextPageUri
设置为空,如下所示:
string NextPageURI = string.Empty;
最后一部分是检查是否有另一个数据页面,如果是,则应迭代并将数据添加到View Model
,直到没有页面提升,如下所示:
while (myFeed.paging != null && myFeed.paging.next != null)
{
NextPageURI = myFeed.paging.next;
var nextURL = GetNextPageQuery(NextPageURI, access_token);
dynamic nextPagedResult = await fb.GetTaskAsync(nextURL.GraphAPICall(appsecret_proof));
foreach (dynamic post in nextPagedResult.data)
{
postList.Add(DynamicExtension.ToStatic<FacebookPostViewModel>(post));
}
}
这有助于我摆脱面临的问题。但是我还有另一个任务可以继续。这是获取帖子的速度,如果帖子超过30k需要10分钟,这对我来说并不理想。