Facebook Graph API Pagination如何工作以及如何使用它迭代facebook用户提要?

问题描述 投票:8回答:2

我有一个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也是。

c# facebook facebook-graph-api pagination facebook-c#-sdk
2个回答
9
投票

首先是一些术语:

节点 - 基本上是“事物”,例如用户,照片,页面,评论 边缘 - “事物”之间的联系,例如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/


1
投票

最后,在做了一些研究和阅读一些博客之后,我发现没有直接来自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分钟,这对我来说并不理想。

© www.soinside.com 2019 - 2024. All rights reserved.