我正在嘗試從 API 獲取大量資料(超過 30 萬條記錄)。它有分頁(每頁 25 條記錄),請求限制為每 3 分鐘 50 個請求。我正在使用 PHP curl 來獲取資料。API 需要 JWT 令牌授權。我可以得到一個頁面并將其記錄放入一個陣列中。
...
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
問題是我需要從所有頁面獲取所有記錄并將其保存到陣列或檔案中。怎么做?也許我應該使用 JS 做得更好?
最好的問候,謝謝。
uj5u.com熱心網友回復:
理想情況下使用 cron 和某種形式的存盤、資料庫或檔案。
重要的是要確保除非前一個腳本完成,否則不會開始對腳本的新呼叫,否則它們會開始堆積,并且在幾次之后,您將開始出現服務器過載、腳本失敗并且變得混亂的情況。
存盤一個值來表示腳本正在啟動。
運行 CURL 請求。
一旦回傳 curl 并處理和存盤資料,更改您在開始時存盤的值以表示腳本已完成。
在您認為必要的時間間隔內將此腳本作為 cron 運行。
一個簡化的例子:
<?php
if ($script_is_busy == 1) exit();
$script_is_busy = 1;
// YOUR CURL REQUEST AND PROCESSING HERE
$script_is_busy = 0;
?>
uj5u.com熱心網友回復:
我會使用一系列請求。一個典型的請求最多需要 2 秒才能完成,因此每 3oo 秒 50 個請求不需要并行請求。如果您不想被 DoS 禁止,您仍然需要測量時間并等待。請注意,據我所知,即使使用并行性,curl 也支持它。當您達到請求限制時,您必須使用睡眠功能等待,直到您可以發送新請求。對于 PHP,真正的問題是它是一個長時間運行的作業,所以你需要更改設定,否則它會超時。您可以這樣做:管理長時間運行的 php 腳本的最佳方法?就 nodejs 而言,我認為對于這種異步任務來說它是一個更好的解決方案,因為 nodejs 所需要的特性自然而然地出現了,沒有擴展之類的東西,盡管我對它有偏見。
uj5u.com熱心網友回復:
好的。我誤解了你需要什么。我還有更多問題。
你能做一個請求并立即獲得你的 50 條記錄嗎?這是假設當您說每 3 分鐘 50 個請求時,您的意思是 50 條記錄。
為什么你認為有這個 50/3 的限制?
你能提供這個服務的鏈接嗎?
每個 IP 地址有 50 條記錄嗎?
租用 5 個或 6 個 IP 地址是一種選擇嗎?
您是否為每條記錄付費?
該服務總共有多少條記錄?
記錄的可行性是否有時間限制。
我在想如果你可以使用 6 個 IP 地址(或 6 個行程),你可以同時使用stream_socket_client().
stream_socket_client 允許您同時發出請求。
然后,您創建一個回圈來監視每個套接字的回應。
大約 10 年前,我制作了一個評估網頁質量的應用程式。我跑了
- W3C 標記驗證
- W3C CSS 驗證
- W3C 移動 OK
- 網頁測驗
- 我自己的性能測驗。
我將所有 URL 放在一個陣列中,如下所示:
$urls = array();
$path = $url;
$url = urlencode("$url");
$urls[] = array('host' => "jigsaw.w3.org",'path' => "/css-validator/validator?uri=$url&profile=css3&usermedium=all&warning=no&lang=en&output=text");
$urls[] = array('host' => "validator.w3.org",'path' => "/check?uri=$url&charset=(detect automatically)&doctype=Inline&group=0&output=json");
$urls[] = array('host' => "validator.w3.org",'path' => "/check?uri=$url&charset=(detect automatically)&doctype=XHTML Basic 1.1&group=0&output=json");
然后我會做插座。
foreach($urls as $path){
$host = $path['host'];
$path = $path['path'];
$http = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
$stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
if ($stream) {
$sockets[] = $stream; // supports multiple sockets
$start[] = microtime(true);
fwrite($stream, $http);
}
else {
$err .= "$id Failed<br>\n";
}
}
然后我監視套接字并從每個套接字檢索回應。
while (count($sockets)) {
$read = $sockets;
stream_select($read, $write = NULL, $except = NULL, $timeout);
if (count($read)) {
foreach ($read as $r) {
$id = array_search($r, $sockets);
$data = fread($r, $buffer_size);
if (strlen($data) == 0) {
// echo "$id Closed: " . date('h:i:s') . "\n\n\n";
$closed[$id] = microtime(true);
fclose($r);
unset($sockets[$id]);
}
else {
$result[$id] .= $data;
}
}
}
else {
// echo 'Timeout: ' . date('h:i:s') . "\n\n\n";
break;
}
}
我用了很多年,從來沒有失敗過。
收集記錄并對其進行分頁將很容易。
關閉所有套接字后,您可以收集頁面并將它們發送給您的用戶。
你覺得上面說的可行嗎?
JS不是更好。
還是您的意思是每 3 分鐘 50 條記錄?
這就是我將如何進行分頁。
我會將回應組織成每頁 25 條記錄的頁面。
在查詢結果 while 回圈中,我會這樣做:
$cnt = 0;
$page = 0;
while(...){
$cnt
$response[$page][] = $record;
if($cnt > 24){$page , $cnt = 0;}
}
header('Content-Type: application/json');
echo json_encode($response);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/507058.html
標籤:javascript php api 休息 卷曲
