在V3中列出文件时ERR 403 - (超出用户速率限制)

时间:2016-04-08 06:59:56

标签: php google-api google-drive-api google-api-php-client

我想使用Google Drive v3 API和Google PHP客户端库,使用Files.List从一个文件夹中获取文件名。

我不想检查已移动的文件是否从该文件夹中删除,因此我使用了驱动器API函数getExplicitlyTrashed()来查找垃圾箱中的文件以过滤这些文件

最新版本的Google PHP客户端库:1.1.7

Google Drive V3文件:https://gist.github.com/bshaffer/9bb2cdccd315880ab52f

在驱动器v3中也使用了src / Google / Http / REST.php,仅在帖子回复后更新:Download CSV file using Google Drive V3(V2 works perfect) throws error 403

使用Drive V3方法的示例脚本文件:列表 - 列出不在垃圾箱中的文件夹中的文件

<?php
error_reporting(0);
set_include_path( get_include_path() . PATH_SEPARATOR . 'Google' );
require_once 'Google/autoload.php';
require_once 'Google/Client.php';
require_once 'Google/Service/Drive.php';
$service=get_service_document();
$folderid="FOLDER_ID";
$list_files=GetAllFilesName($service,$folderid);
for($i=0;$i<count($list_files);$i++){
    $id= $list_files[$i][0];
    $name=$list_files[$i][1];
    echo 'ID:'.$id.'<br>NAME:'.$name.'<br>';
}

function GetAllFilesName($service,$folderid){
// v3 To check explicitly trashed function we shld use optional parameter    
try{
            $optParams = array(
            'fields' =>'explicitlyTrashed'
        );
//Get list of files from folder
        $children1 = $service->files->listFiles(array(
            'q' => "'$folderid' in parents "));
        $filenamelist=array();
        foreach ($children1 as $child) {
                if ($service->files->get($child->getId(), $optParams)->getExplicitlyTrashed() == 1) continue;
                $fileid = $service->files->get($child->getId())->id;
                $filename = $service->files->get($child->getId())->name;
                $filenamelist[] = [$fileid,$filename];
              }
        return $filenamelist;
    }
    catch (Exception $ex) {
        echo $ex->getMessage();//$filenamelisterr;
    }
}
//function to get service
function get_service_document(){
    $userstamp='user@example.com';
     $driveService =buildServiceDrive($userstamp,"SERVICE-ACCOUNT","https://www.googleapis.com/auth/drive","key.p12");
    return $driveService;
}
//building service
function buildServiceDrive($userEmail,$service_id,$scope,$service_filename) {
    $key = file_get_contents($service_filename);
    $auth = new Google_Auth_AssertionCredentials(
        $service_id,
        array($scope),
        $key);
    $auth->sub = $userEmail;
    $client = new Google_Client();
    $client->setAssertionCredentials($auth);
    return new Google_Service_Drive($client);
}

我的脚本无法不断列出该文件夹中的所有文件。每次调用一段时间工作一段时间我都会遇到以下问题

响应: enter image description here

2.Sample Script使用Drive V2方法文件:列表 - 列出不在垃圾箱中的文件夹中的文件

使用Drive v2,我的脚本运行正常,我没有得到任何403问题。

<?php
set_include_path( get_include_path() . PATH_SEPARATOR . 'GoogleV2' );
require_once 'GoogleV2/autoload.php';
require_once 'GoogleV2/Client.php';
require_once 'GoogleV2/Service/Drive.php';


$service=get_service_document();
$folderid="FOLDER-ID";
$list_files=GetAllFilesName($service,$folderid);
for($i=0;$i<count($list_files);$i++){
    $id= $list_files[$i][0];
    $name=$list_files[$i][1];
    echo 'ID:'.$id.'<br>NAME:'.$name.'<br>';
}
//print_r($list_files);

function GetAllFilesName($service,$folderid){
    try{
        $children1 = $service->children->listChildren($folderid);
        $filenamelist=array();
        foreach ($children1->getItems() as $child) {
            if($service->files->get($child->getId())->getExplicitlyTrashed()==1)continue;
            $fileid=$service->files->get($child->getId())->id;
            $filename=$service->files->get($child->getId())->title;
            $filenamelist[]=[$fileid,$filename];
        }
        return $filenamelist;
    }
    catch(Exception $ex){
        Echo $ex->getMessage();
    }
}
//function to get service
function get_service_document(){
  $userstamp='user@example.com';
  $driveService =buildServiceDrive($userstamp,"SERVICE-ACCOUNT","https://www.googleapis.com/auth/drive","KEY.p12");
    return $driveService;
}
//building service
function buildServiceDrive($userEmail,$service_id,$scope,$service_filename) {
    $key = file_get_contents($service_filename);
    $auth = new Google_Auth_AssertionCredentials(
        $service_id,
        array($scope),
        $key);
    $auth->sub = $userEmail;
    $client = new Google_Client();
    $client->setAssertionCredentials($auth);
    return new Google_Service_Drive($client);
}

响应:

enter image description here

使用指数备份,我们修改了脚本,但仍然会抛出403错误..

<?php
set_include_path( get_include_path() . PATH_SEPARATOR . 'Google' );
require_once 'Google/autoload.php';
require_once 'Google/Client.php';
require_once 'Google/Service/Drive.php';

$service=get_service_document();
$folderid="FOLDER_ID"; 
$list_files=GetAllFilesName($service,$folderid);
for($i=0;$i<count($list_files);$i++){
    $id= $list_files[$i][0];
    $name=$list_files[$i][1];
    echo 'ID:'.$id.'<br>NAME:'.$name.'<br>';
}


function GetAllFilesName($service,$folderid){
    try{
        $n=5;
        $optParams = array(
            'fields' =>'explicitlyTrashed'
        );
        $children1 = $service->files->listFiles(array(
            'q' => "'$folderid' in parents "));
        $filenamelist=array();

        foreach ($children1 as $child) {
            try {
                if ($service->files->get($child->getId(), $optParams)->getExplicitlyTrashed() == 1) continue;
                $fileid = $service->files->get($child->getId())->id;
                $filename = $service->files->get($child->getId())->name;
                $filenamelist[] = [$fileid,$filename];
            }
            catch (apiServiceException $ex) {
                if ($ex->getCode() == 403
                    && ($ex->getErrors()[0]["reason"] == "rateLimitExceeded"
                        || $ex->getErrors()[0]["reason"] == "userRateLimitExceeded"
                        || $ex->getErrors()[0]["reason"] =="dailyLimitExceeded")
                ) {
                    // Apply exponential backoff.
                    usleep((1 << $n) * 1000000 + rand(0, 1000000));
                }
            }
        }
        return $filenamelist;
    }
    catch (Exception $ex) {
        echo $ex->getMessage();//$filenamelisterr;
    }
}
//function to get service
function get_service_document(){
     $userstamp='user@example.com';
     $driveService =buildServiceDrive($userstamp,"SERVICE-ACCOUNT","https://www.googleapis.com/auth/drive","key.p12");
    return $driveService;
}
//building service
function buildServiceDrive($userEmail,$service_id,$scope,$service_filename) {
    $key = file_get_contents($service_filename);
    $auth = new Google_Auth_AssertionCredentials(
        $service_id,
        array($scope),$key);
    $auth->sub = $userEmail;
    $client = new Google_Client();
    $client->setAssertionCredentials($auth);
    return new Google_Service_Drive($client);
}

Plz帮助我是否有任何其他方式如何使用指数退出,可能我没有正确地应用世博会。退后?我们在过去的3周内一直在运行,请帮忙。我们需要部署Drive V3。任何你的建议/提示/帮助对我们来说都是一个很大的帮助。

提前多多感谢。

1 个答案:

答案 0 :(得分:0)

文档告诉您如何处理此错误消息。

  

403:User Rate Limit Exceeded

     

已达到开发者控制台的每用户限制。

     

{&#34;错误&#34;:{&#34;错误&#34;:[{       &#34;域&#34;:&#34; usageLimits&#34;,       &#34;原因&#34;:&#34; userRateLimitExceeded&#34;,       &#34;消息&#34;:&#34;超出用户限速&#34; },&#34;代码&#34;:403,&#34;消息&#34;:&#34;超出用户速率&#34; }}

     

建议采取的行动:

     
      
  • 在Developer Console项目中提高每用户配额。
  •   
  • 如果是一个用户   正在代表Google Apps的许多用户提出大量请求   域,考虑具有权限委派的服务帐户(设置   quotaUser参数)。
  •   
  • 使用指数退避。
  •   

基本上你遇到了防洪保护,你的代码运行得很快,你需要放慢速度。为什么v2没有显示这一点,而v3就是这么简单,事实上v3比v2更快,它毕竟是一个更新的API。

解决方案:

Implementing exponential backoff

指数退避是网络应用程序的标准错误处理策略,其中客户端会在不断增加的时间内定期重试失败的请求。如果大量请求或繁重的网络流量导致服务器返回错误,则指数退避可能是处理这些错误的好策略。相反,它不是处理与速率限制,网络量或响应时间无关的错误的相关策略,例如无效的授权凭证或未找到文件的错误。

正确使用,指数退避可提高带宽使用效率,减少获得成功响应所需的请求数,并最大化并发环境中请求的吞吐量。