【问题标题】:Detect the final page of a paginated cURL response in a Bash loop在 Bash 循环中检测分页 cURL 响应的最后一页
【发布时间】:2018-08-30 00:22:27
【问题描述】:

目标

使用 cURL 和 Bash 在单个 JSON 文件中包含来自分页 REST API 调用的所有对象。此组合列表将输入到 Power BI 报告中。

详情

一个请求最多返回 100 个对象。总共有 400 多个对象。总量随时间增长。我不想维护包含 for set in 0 100 200 300 400 ; do 之类的脚本,因为它需要我手动将集合与当前对象数量进行匹配。为了节省劳动力,我想要一个脚本来自动检测最后一页何时被处理然后中断。

为了实现我的目标,目前我提出的计划是将每个增量集(包含 100 个项目)提取到其自己的 JSON 文件中,然后将它们与cat 组装在一起,并使用 JQ 提取相关的 JSON 键/值。 Bash 的原因是它是我所知道的唯一编程。

尝试

(基于this question and answer

for ((i=0; ; i+=100)); do
    contents=$(curl -u "username:password" -H "Content-Type: application/json" "https://<url>/api/core/v3/places?count=100&startIndex=$i")
    echo "$contents" > $i.json
    if [[ $contents =~ 'list" : [ ]' ]]
    then break
    fi
done

结果

除第一页和最后一页外,所有页面都按预期导出:

  • 第一个startIndex 应该是0 但代码使startIndex 100。我尝试了i 的多种变体,但仍然失败。
  • [编辑:已解决,谢谢@weirdan]list":nullnext":null 都不会结束循环。该脚本会无限期地导出递增的 JSON 文件。~

参考

返回的分页 JSON 的第一页

{
  "itemsPerPage" : 100,
  "links" : {
    "next" : "https://<url>/api/core/v3/places?sort=titleAsc&count=100&startIndex=0" <--- with my script, startIndex is erroneously 100
  },
  "list" : [ {
...

中间页面

{
  "itemsPerPage" : 100,
  "links" : {
    "previous" : "https://<url>/api/core/v3/places?sort=titleAsc&count=100",
    "next" : "https://<url>/api/core/v3/places?sort=titleAsc&count=100&startIndex=200"
  },
  "list" : [ {
...

最后一页

{
  "itemsPerPage" : 100,
  "links" : {
    "previous" : "https://<url>/api/core/v3/places?sort=titleAsc&count=100&startIndex=400"
  },
  "list" : [ {
...

空白页

{
  "itemsPerPage" : 100,
  "list" : [ ],
  "startIndex" : 500
}

感谢您的任何建议或想法。

【问题讨论】:

  • 好吧,看看页面示例list 键从不包含null,所以这就是正则表达式永远不会匹配的原因之一。您可能还需要考虑冒号周围的空格 (:)。
  • 你完全正确@weirdan,谢谢你,只要我把它改成'list" : [ ]'就可以了。我不明白那里发生了什么,所以谢谢你的解释!
  • 顺便说一句,我倾向于建议使用jq,而不是使用正则表达式进行测试。使用-e,您可以告诉它根据表达式是否为真设置退出状态,让您使用if jq ...,就像使用if grep ...一样。
  • jq 确实是很好的建议
  • 至于$startIndex 部分,我实际上认为第一页应该在它的next 元素中显示100。该元素指示您可以获取结果的 next 页的 url,第二页以第 100 号记录开始(给定 100 作为页面大小)

标签: json bash api curl jq


【解决方案1】:

假设我关于startIndex 的理论成立并实施@CharlesDuffy 关于jq 的建议,这就变成了

for ((i=0; ; i+=100)); do
    contents=$(curl -u "username:password" -H "Content-Type: application/json" "https://<url>/api/core/v3/places?count=100&startIndex=$i")
    echo "$contents" > $i.json
    if jq -e '.list | length == 0' >/dev/null; then 
       break
    fi <<< "$contents"
done

【讨论】:

  • 完美运行。谢谢怪人和@CharlesDuffy
猜你喜欢
  • 2019-11-29
  • 2021-06-02
  • 2016-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多