【问题标题】:API call limited to 500 results - how to iterate through to get all results?API 调用限制为 500 个结果 - 如何迭代以获得所有结果?
【发布时间】:2019-01-30 20:21:46
【问题描述】:

我正在开发一个 Web 应用程序,它遍历 API 结果以插入 MySQL 数据库。

我使用的 API 限制每次调用最多返回 500 条记录。

他们有一个参数,您可以在其中选择从哪个“页面”返回结果,因此对于 1504(当前记录数)记录,我可以调用第 2 页并返回 500-999 的结果。

我充其量只是半新手,这是我第一次尝试使用 API...我正在努力弄清楚如何收集所有 1504 个结果。

API 文档是:https://developer.trademe.co.nz/api-reference/search-methods/rental-search/

我可以使用“page”参数来选择我想要的结果页面。

$url = "https://api.tmsandbox.co.nz/v1/Search/Property/Rental.json";

$headr = array();
$headr[] = 'Content-length: 0';
$headr[] = 'Authorization: OAuth oauth_consumer_key="xxx", oauth_signature_method="PLAINTEXT", oauth_signature="xxx"';

$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER,$headr);
$pageSize = 10;
$data = array(
    "rows" => $pageSize,
    "sort_order" => "ExpiryDesc",
    "page" => 1
);
$totalPages = PHP_INT_MAX;
$result = [];
do {
    curl_setopt($curl, CURLOPT_URL, $url."?".http_build_query ($data));
    $resulta = curl_exec($curl);

    $array = json_decode($resulta, true);
    array_merge($result, $array);
    $data['page']++;
    if ( $totalPages == PHP_INT_MAX )   {
        $totalPages = floor($array['TotalCount']/$pageSize);
    }

}
while ( $totalPages < $data['page']);

$properties = $array['List'];
$prop_count = $array['TotalCount'];
curl_close($curl);

这是我用来返回 500 个结果的代码。 $prop_count 保存总行数(1504),$pages 保存页数(在本例中为 3.08)。

谁能让我先了解一下逻辑顺序以实现某种循环以返回所有结果?我坐在这里绞尽脑汁想要开始。

【问题讨论】:

  • 您获取的号码是$currentPage * $countPerPage。如果小于$totalCount,请继续。

标签: php json api


【解决方案1】:

虽然无法对此进行测试,但这里的原则是不断发出请求,直到没有更多页面为止。第一次循环它会计算出页数(使用返回内容中的 TotalCount / pageSize - 使用 floor() 使 3.1 变为 3)。然后在循环结束时检查当前页面是否 > 总页数。

$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER,$headr);
$pageSize = 500;
$data = array(
    "rows" => $pageSize,
    "sort_order" => "ExpiryDesc",
    "page" => 1
);
$totalPages = PHP_INT_MAX;
$result = [];
do {
    curl_setopt($curl, CURLOPT_URL, $url."?".http_build_query ($data));
    $resulta = curl_exec($curl);

    $array = json_decode($resulta, true);
    $result[] = $array['List'];
    $data['page']++;
    if ( $totalPages == PHP_INT_MAX )   {
        $totalPages = floor($array['TotalCount']/$pageSize);
    }

}
while ( $totalPages > $data['page']);
curl_close($curl);

// Loop through the pages of results and in each page each listing
foreach ( $result as $page )    {
    foreach ( $page as $item ){
        // Process each item
        echo $item['ListingId'].PHP_EOL;
    }
}

【讨论】:

  • 我喜欢这个 Nigel 的外观,但是当我运行测试时,它会将我的错误日志填充到 1.2GB 大小。通常这就是我通过修复事情“捏造”的方式。我知道您无法测试代码一定很难,但是您能看到任何可能导致这种情况的原因吗?
  • curl_exec() expects parameter 1 to be resource, string given 是它给我的错误。我重新添加了 $url 变量,因为其中包含 API url,但不太确定如何以这种新格式构造 $query_url 变量?我尝试只使用我的旧格式,但仍然会引发同样的错误。
  • 我刚刚更正了curl_setopt($curl, CURLOPT_URL...$resulta = curl_exec($curl);这两行
  • 不再有 1.2GB 错误文件!虽然我得到了超时(目前设置为 300 秒),但我认为这不应该发生在 1500 条记录上? 500 使用我的旧方法大约需要 8 秒?感谢您的帮助!
  • 您可以尝试将array_merge($result, $array); 替换为$result[] = $array;,您可能会发现它们的字符串键会相互覆盖。您将需要遍历不同的数组,因为它将是一个数组数组(在循环后使用print_r($result); 进行检查。
【解决方案2】:

使用循环并再次发送请求。

    for($i=1;$i<4;$i++)
        request(rows=$i*500);

行会是这样的

i=1, rows=500
i=2, rows=1000
i=3, rows=1500
i=4, rows=2000

【讨论】:

    猜你喜欢
    • 2014-07-28
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2020-01-01
    相关资源
    最近更新 更多