如何在 C# HttpClient 中循环调用分页 URL 以从 JSON 结果下载所有页面

2024-04-03

我的第一个问题,所以请友善......:)

我正在使用C# HttpClient调用作业 API 端点。

这是端点:Jobs API Endpoint(不需要密钥,点击即可) http://service.dice.com/api/rest/jobsearch/v1/simple.json?skill=ruby

这给了我这样的 JSON。

{
  "count": 1117,
  "firstDocument": 1,
  "lastDocument": 50,
  "nextUrl": "\/api\/rest\/jobsearch\/v1\/simple.json?areacode=&country=&state=&skill=ruby&city=&text=&ip=&diceid=&page=2",
  "resultItemList": [
    {
      "detailUrl": "http:\/\/www.dice.com\/job\/result\/90887031\/918715?src=19",
      "jobTitle": "Sr Security Engineer",
      "company": "Accelon Inc",
      "location": "San Francisco, CA",
      "date": "2017-03-30"
    },
    {
      "detailUrl": "http:\/\/www.dice.com\/job\/result\/cybercod\/BB7-13647094?src=19",
      "jobTitle": "Platform Engineer - Ruby on Rails, AWS",
      "company": "CyberCoders",
      "location": "New York, NY",
      "date": "2017-04-16"
    }
 ]
}

我已经粘贴了完整的 JSON 片段,以便您可以在答案中使用它。完整的结果真的很期待这里。

这是 C# 类。

using Newtonsoft.Json;
using System.Collections.Generic;

namespace MyNameSpace
{
    public class DiceApiJobWrapper
    {
        public int count { get; set; }
        public int firstDocument { get; set; }
        public int lastDocument { get; set; }
        public string nextUrl { get; set; }

        [JsonProperty("resultItemList")]
        public List<DiceApiJob> DiceApiJobs { get; set; }
    }

    public class DiceApiJob
    {
        public string detailUrl { get; set; }
        public string jobTitle { get; set; }
        public string company { get; set; }
        public string location { get; set; }
        public string date { get; set; }
    }
}

当我使用 HttpClient 调用 URL 并使用 JSON.NET 反序列化时,我确实正确地取回了数据。

这是我从控制台应用程序调用的代码Main方法(因此static列表,我认为这可以更好地重构?)

   private static List<DiceApiJob> GetDiceJobs()
    {
        HttpClient httpClient = new HttpClient();
        var jobs = new List<DiceApiJob>();

        var task = httpClient.GetAsync("http://service.dice.com/api/rest/jobsearch/v1/simple.json?skill=ruby")
          .ContinueWith((taskwithresponse) =>
          {
              var response = taskwithresponse.Result;
              var jsonString = response.Content.ReadAsStringAsync();
              jsonString.Wait();

              var result =  JsonConvert.DeserializeObject<DiceApiJobWrapper>(jsonString.Result);
              if (result != null)
              {
                  if (result.DiceApiJobs.Any())
                      jobs = result.DiceApiJobs.ToList();

                  if (result.nextUrl != null)
                  {
                      //
                      // do this GetDiceJobs again in a loop? How?? Any other efficient elegant way??
                  }
              }
          });
        task.Wait();

        return jobs;
    }

但现在,我如何检查是否有更多工作使用nextUrl场地?我知道我可以检查它是否不为空,如果不为空,则意味着还有更多工作需要取消。

我的调试和单步执行的结果 https://i.stack.imgur.com/N3sn7.png

如何以递归方式执行此操作,并且不会挂起且有一些延迟,这样我就不会超出 API 限制?我想我必须使用 TPL(任务并行库),但我很困惑。

谢谢你! 〜肖恩


如果您担心应用程序的响应时间,并且希望在实际从 API 获取所有页面/数据之前返回一些结果,您可以循环运行您的进程,并为其提供一个回调方法,以便在它获取每个页面/数据时执行来自 API 的数据页。

这是一个示例:

public class Program
{
    public static void Main(string[] args)
    {
        var jobs = GetDiceJobsAsync(Program.ResultCallBack).Result;
        Console.WriteLine($"\nAll {jobs.Count} jobs displayed");
        Console.ReadLine();
    }

    private static async Task<List<DiceApiJob>> GetDiceJobsAsync(Action<DiceApiJobWrapper> callBack = null)
    {
        var jobs = new List<DiceApiJob>();
        HttpClient httpClient = new HttpClient();
        httpClient.BaseAddress = new Uri("http://service.dice.com");
        var nextUrl = "/api/rest/jobsearch/v1/simple.json?skill=ruby";

        do
        {
            await httpClient.GetAsync(nextUrl)
                .ContinueWith(async (jobSearchTask) =>
                {
                    var response = await jobSearchTask;
                    if (response.IsSuccessStatusCode)
                    {
                        string jsonString = await response.Content.ReadAsStringAsync();
                        var result = JsonConvert.DeserializeObject<DiceApiJobWrapper>(jsonString);
                        if (result != null)
                        {
                            // Build the full list to return later after the loop.
                            if (result.DiceApiJobs.Any())
                                jobs.AddRange(result.DiceApiJobs.ToList());

                            // Run the callback method, passing the current page of data from the API.
                            if (callBack != null)
                                callBack(result);

                            // Get the URL for the next page
                            nextUrl = (result.nextUrl != null) ? result.nextUrl : string.Empty;
                        }
                    }
                    else
                    {
                        // End loop if we get an error response.
                        nextUrl = string.Empty;
                    }
                });                

        } while (!string.IsNullOrEmpty(nextUrl));
        return jobs;
    }


    private static void ResultCallBack(DiceApiJobWrapper jobSearchResult)
    {
        if (jobSearchResult != null && jobSearchResult.count > 0)
        {
            Console.WriteLine($"\nDisplaying jobs {jobSearchResult.firstDocument} to {jobSearchResult.lastDocument}");
            foreach (var job in jobSearchResult.DiceApiJobs)
            {
                Console.WriteLine(job.jobTitle);
                Console.WriteLine(job.company);
            }
        }
    }
}

请注意,上面的示例允许回调方法在接收到数据后访问每一页数据。GetDiceJobsAsync方法。在这种情况下,控制台会在每个页面可用时显示该页面。如果你不想要回调选项,你可以简单地传递任何东西给GetDiceJobsAsync.

But the GetDiceJobsAsync完成后还会返回所有作业。所以你可以选择在最后对整个列表进行操作GetDiceJobsAsync.

至于达到 API 限制,您可以在重复循环之前在循环内插入一个小的延迟。但当我尝试时,我没有遇到限制我的请求的 API,所以我没有将其包含在示例中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C# HttpClient 中循环调用分页 URL 以从 JSON 结果下载所有页面 的相关文章

  • 具有不同大小结构的结构数组的 malloc()

    如果每个结构都包含一个大小不同的字符串数组 那么如何正确地 malloc 一个结构数组 因此每个结构可能有不同的大小 并且不可能 realloc 结构体数量 sizeof 结构体名称 after malloc 初始大小 sizeof 结构名
  • 通过增加索引之和来生成排序组合的有效方法

    对于启发式算法 我需要一个接一个地评估特定集合的组合 直到达到停止标准 由于它们很多 目前我正在使用以下内存高效迭代器块生成它们 受到 python 的启发 itertools combinations http docs python o
  • 在 VS2017 下使用 Conan 和 CMake 项目进行依赖管理

    我正在尝试使用 CMake 与 VS2017 集成为 C 设置一个开发环境 以便在 Linux x64 下进行编译 为了更好地管理依赖关系 我选择使用 Conan 但我对这个软件还很陌生 我想知道让 VS2017 识别项目依赖关系的最佳方法
  • 内联函数/方法

    声明 内联函数必须在调用之前定义 这个说法正确吗 EDIT 该问题最初是德语 内联功能穆森 弗 伊赫雷姆 奥夫鲁夫定义 sein 也许它对任何人都有帮助 是的 它是正确的 但只是部分正确 它可能正确地重新构建如下 内联函数必须在每个翻译单位
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • C# 正则表达式用于查找 中具有特定结尾的链接

    我需要一个正则表达式模式来查找字符串 带有 HTML 代码 中的链接 以获取文件结尾如 gif 或 png 的链接 示例字符串 a href site com folder picture png target blank picture
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • 获取尚未实例化的类的函数句柄

    我对 C 相当陌生 我想做的事情可能看起来很复杂 首先 我想获取一些函数的句柄以便稍后执行它们 我知道我可以通过以下方式实现这一目标 List
  • Async.StartChild是否存在内存泄漏?

    当我运行以下测试 使用 F 2 0 构建 时 我得到 OutOfMemoryException 在我的系统上大约需要 5 分钟才能达到异常 如果它作为 x86 进程运行 则为 i7 920 6gb ram 但无论如何我们都可以在任务管理器中
  • 如何生成 appsettings..json 文件?

    我有一个 ASP NET Core 2 WebAPI 它将部署在以下环境中 INT QA STAGE 生产环境 基于上述 我需要有appsettings
  • C++ 错误 - “成员初始值设定项表达式列表被视为复合表达式”

    我收到一个我不熟悉的 C 编译器错误 可能是一个非常愚蠢的错误 但我不能完全指出它 Error test cpp 27 error member initializer expression list treated as compound
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和
  • asp.net网格分页的SQL查询

    我在用iBatis and SQLServer 使用偏移量和限制进行分页查询的最佳方法是什么 也许我添加该列ROW NUMBER OVER ORDER BY Id AS RowNum 但这只会阻止简单查询的数据访问 在某些情况下 我使用选择
  • WPF。如何从另一个窗口隐藏/显示主窗口

    我有两个窗口 MainWindow 和 Login 显示登录的按钮位于主窗口 this Hide Login li new Login li Show 登录窗口上有一个检查密码的按钮 如果密码正确 我如何显示主窗口 将参数传递给 MainW
  • 0-1背包算法

    以下 0 1 背包问题是否可解 浮动 正值和 浮动 权重 可以是正数或负数 背包的 浮动 容量 gt 0 我平均有 这是一个相对简单的二进制程序 我建议用蛮力进行修剪 如果任何时候你超过了允许的重量 你不需要尝试其他物品的组合 你可以丢弃整
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • OSError: [WinError 193] %1 不是有效的 Win32 应用程序,同时使用 CTypes 在 python 中读取自定义 DLL

    我正在尝试编写用 python 封装 C 库的代码 我计划使用 CTypes 来完成此操作 并使用 Visual Studio 来编译我的 DLL 我从一个简单的函数开始 在 Visual Studio 内的标头中添加了以下内容 然后将其构
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是

随机推荐

  • 在另一台 Windows 机器上运行 Rust 编译的程序有什么要求?

    我对 Rust 完全陌生 我在 Windows 10 机器上安装了 Rust 创建了一个简单的 helloworld 程序 如下所示 fn main print Hello world 并编译它rustc rust rs 之后会生成两个文件
  • 2 个 IndexedSlices 不支持高效 allreduce

    我正在尝试在多个 GPU 上运行子类 Keras 模型 代码按预期运行 但是在代码执行过程中出现以下 警告 2 个 IndexedSlices 不支持高效 allreduce 这是什么意思 我遵循 Tensorflow 2 0 Beta 指
  • 为什么 CSS 光标属性不适用于样式化滚动条?

    我设计了一个滚动条 but 光标指针不工作 即使我把 important webkit scrollbar width 0 3vw height 20px padding 2px cursor pointer important Handl
  • 两个 WPF 应用程序之间的通信

    我有两个 WPF 应用程序 我需要这两个应用程序能够相互通信 我只需要这些应用程序相互发送一些通知 仅此而已 我已经找到了两种技术 一种是使用WCF 另一种是使用DDE 但对我来说 这些对于我的要求来说似乎太复杂了 请建议最简单的方法是什么
  • Internet Explorer中跨域POST请求ajax

    我正在使用 jQuery 1 7 2 并且想向另一个域发出 POST 请求 它必须是 POST 请求 但这确实无法在 Internet Explorer 中工作 我在IE9上试过 它适用于所有其他浏览器 我有这个脚本
  • Java中将short转换为byte[]

    我怎样才能转换short 2 个字节 到 Java 中的字节数组 例如 short x 233 byte ret new byte 2 应该是这样的 但不确定 0xFF lt lt 8 x gt gt 0 EDIT 您还可以使用 java
  • 查找我的数据库的 DSN?

    我有一个 SQL 数据库 想要使用 VBA 连接到它以支持一些旧功能 我正在使用 ADODB 连接 需要知道我的数据库 DSN 是什么 我怎样才能找到这个 我正在使用 SQL Server 2008 谢谢 D A DSN 数据源名称 htt
  • Laravel 从嵌套关系中取出一个数组

    我只需要得到roomnumber从以下查询返回的数组 roomnumbers Room with floorroomcount gt function query query gt with roomnumber gt get gt whe
  • java队列中Queue.Poll()返回null但Queue.size()>0

    My code while Memo qRcv size gt 0 MessageReceived msg Memo qRcv poll 然后我得到了 2014 03 01 11 09 36 DEBUG Thread 16 threadQu
  • 如何将时间序列数据中的y%m%d%H格式转换为“%Y%m%d %H:%M:%S”

    我如何转换y m d H格式化为 Y m d H M S 我的日期从 1970 年到 2010 年 部分来自评论 如果您可以相应地修改问题 那就太好了 似乎这不是格式化的情况 y vs Y或空格 分隔符 但是strptime POSIX t
  • C谜题:用有偏差的硬币制造公平的硬币

    如何确定函数在以下情况下返回 0 或 1 的概率 Let the function A返回 0 与 概率 40 和 1 有概率 60 生成一个function B和 概率 50 50 仅使用function A only 我想到了以下几点
  • Java读取文件,如果不存在则创建它

    这是我的代码 public String path public String fileName public static void readData throws IOException try path myPath fileName
  • 具有固定大小的 Blackberry VerticalFieldManager:滚动问题

    我试图拥有一个带有修复标题 带有某些字段的管理器 和可滚动内容 自定义字段列表 的全屏用户界面 这个想法是模拟一种可滚动列表 为此 我制作了一个接受 maxHeight 屏幕高度 标题高度 的自定义 VerticalFieldManager
  • NSPopover 内的 NSTableview 看起来与独立的不同

    我创建了一个ListView类 这是一个非常简单的Tableview 如果我用 IB 实例化它 一切看起来都很好 如果我以编程方式实例化它也是一样 如果我在一个内部以编程方式实例化它NSPopover 我的桌子的每一行都有浅灰色背景 这是从
  • 为什么 form.submit() 不起作用?

    我在页面中有以下片段 我一生都无法弄清楚为什么单击button1元素时表单没有提交 我在 IE 中收到错误消息 指出该对象不支持此属性或方法 我将 document poform 放入警报中 它会警报表单对象 我感觉我可能错过了一些非常明显
  • 某些设备上的 Android 中出现“没有这样的表”问题

    我在 Android 应用程序中使用外部数据库 它在所有模拟器和三星真实设备上运行良好 但是当我检查宏碁智能手机时 我的应用程序崩溃并出现以下异常 android database sqlite SQLiteException no suc
  • 可变结构与类?

    我不确定是否使用可变结构或可变类 我的程序存储一个包含很多对象的数组 我注意到使用类会使所需的内存量增加一倍 但是 我希望对象是可变的 并且有人告诉我使用可变结构是邪恶的 这就是我的类型 struct or class Block publ
  • 将 Flash (AS3) 数据保存为 XML

    我在互联网上 包括 Stack Overflow 花了好几个小时 试图找到一个可靠的 可行的示例 将 Flash 中的信息保存到 XML 文件中 我想获取两种不同类型对象的位置并将每个对象的列表导出到 XML 我们将调用这些对象ball a
  • PHP 5.3.3 中的 ini_set("memory_limit") 根本不起作用

    我之前有过这样的工作 echo ini get memory limit n ini set memory limit 256M echo ini get memory limit n 这将输入 32M 256M 在通过命令行执行的 php
  • 如何在 C# HttpClient 中循环调用分页 URL 以从 JSON 结果下载所有页面

    我的第一个问题 所以请友善 我正在使用C HttpClient调用作业 API 端点 这是端点 Jobs API Endpoint 不需要密钥 点击即可 http service dice com api rest jobsearch v1