Facebook Graph API 分页如何工作以及如何使用它来迭代 facebook 用户提要?
Posted
技术标签:
【中文标题】Facebook Graph API 分页如何工作以及如何使用它来迭代 facebook 用户提要?【英文标题】:How does Facebook Graph API Pagination works and how to iterate facebook user feed with it? 【发布时间】:2017-05-16 01:53:50 【问题描述】:我有一个 facebook Graph API 调用来获取 facebook 用户供稿:
dynamic myFeed = await fb.GetTaskAsync(
("me/feed?fields=id,from id, name, pictureurl ,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, pictureurl ,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 是否提供任何功能来迭代 Next Edges,以便我可以在一次调用中获取所有提要帖子,是否有任何可能的解决方案? PS:我已经多次阅读 facebook API 文档,我知道节点、边缘和字段到底是什么,唯一不幸的是 facebook 还不支持 C# SDK,我无法找到合适的文档Facebook C# SDK 也是如此。
【问题讨论】:
除非 Graph API 在最近的几个版本中发生了变化,否则它实际上不会那样工作。 Facebook 帖子处于边缘,如果您想获得用户的所有帖子,您必须保持浏览边缘(更新新项目)。你用 Offset 找到的是最接近的。您可以在 FB API 文档中阅读此内容。 【参考方案1】:最后在做了一些研究并阅读了一些博客之后,我发现没有直接来自 facebook 的API CAlls
可以一次获取所有用户馈线帖子。
要实现该功能,要么按照 Jeremy Thomson 的建议进行无限滚动,要么遍历不同的 facebook 数据页面,无论 edge
支持哪种 facebook pagination
类型。至于我想要一个没有用户干预/操作的过程,我肯定会选择第二个选项,即使用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 个 feeder 帖子,如下所示:
dynamic myFeed = await fb.GetTaskAsync(
("me/feed?fields=id,from id, name, pictureurl ,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 分钟,这至少对我来说并不理想。
【讨论】:
什么是GetNextPageQuery
?
看来您使用的 API 与我不同 :)【参考方案2】:
首先介绍一些术语:
nodes - 基本上是“事物”,例如用户、照片、页面、评论edges - “事物”之间的连接,例如主页的照片或照片的评论字段 - 有关这些“事物”的信息,例如某人的生日或主页的名称
当您向节点或边缘发出 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 Graph API 不支持一次调用获取所有用户帖子,因此 C# SDK 无法提供该功能。我唯一能想到的是使用 WebClient 和/或 html Agility 包并滚动到用户页面的底部并将整个页面转储出去。不理想。 我做到了,看看我下面的答案以上是关于Facebook Graph API 分页如何工作以及如何使用它来迭代 facebook 用户提要?的主要内容,如果未能解决你的问题,请参考以下文章
Facebook Open Graph API:获取分页用户新闻提要时参数限制的奇怪行为
iOS Facebook Graph API 使用“下一个”或“上一个”Url 使用 SDK 进行分页