4

我們正在嘗試通過調用WebmastersService.SearchAnalytics.Query()來下載使用Webmasters API .NET客戶端庫的網站的頁面數據。爲此,我們使用Batching併發送約。一批中有600個請求。但是,其中大部分都會因「超出配額」錯誤而失敗。失敗的數量每次都不相同,但只有600個工作中的10個(並且它在批次內的位置有所不同)。我們能夠實現它的唯一方法是將批量減小到3,並在每次調用之間等待1秒鐘。網站管理員API - 限額

根據開發者控制檯,我們的每日配額設置爲1,000,000(並且我們還剩99%),並且我們的每個用戶限制設置爲10,000個請求/秒/用戶。

的錯誤,我們得到的回覆是:

超出配額[403]錯誤[留言[超出配額]地址[ - ] 原因[超出限額]域[usageLimits]

是還有另一個強制執行的配額? 「域名[使用限制]」是什麼意思 - 我們查詢網頁數據的域名是域名,還是我們的用戶賬號?

如果我們分別運行每個請求,我們仍然會遇到問題,除非我們在每次調用之間等待1秒鐘。由於網站的數量和頁面的數量,我們需要下載這些數據並不是真正的選擇。

我發現this post其中指出,因爲最大批量爲1000並不意味着您要撥打的Google服務支持這些尺寸的批量。但我真的很想知道配額限制究竟是什麼(因爲它們與開發人員控制檯數據無關)以及如何避免這些錯誤。

更新1

下面是一些示例代碼。它專門編寫只是爲了證明這個問題所以沒必要在它的質量發表意見; O)

using Google.Apis.Auth.OAuth2; 
using Google.Apis.Services; 
using Google.Apis.Util.Store; 
using Google.Apis.Webmasters.v3; 
using Google.Apis.Webmasters.v3.Data; 
using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      new Program().Run().Wait(); 
     } 

     private async Task Run() 
     { 
      List<string> pageUrls = new List<string>(); 
      // Add your page urls to the list here 

      await GetPageData("<your app name>", "2015-06-15", "2015-07-05", "web", "DESKTOP", "<your domain name>", pageUrls); 
     } 

     public static async Task<WebmastersService> GetService(string appName) 
     { 
      //if (_service != null) 
      // return _service; 
      //TODO: - look at analytics code to see how to store JSON and refresh token and check runs on another PC 
      UserCredential credential; 
      using (var stream = new FileStream("c:\\temp\\WMT.json", FileMode.Open, FileAccess.Read)) 
      { 
       credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets, 
        new[] { Google.Apis.Webmasters.v3.WebmastersService.Scope.Webmasters }, 
        "user", CancellationToken.None, new FileDataStore("WebmastersService")); 
      } 

      // Create the service. 
      WebmastersService service = new WebmastersService(new BaseClientService.Initializer() 
      { 
       HttpClientInitializer = credential, 
       ApplicationName = appName, 
      }); 

      //_service = service; 
      return service; 

     } 

     private static async Task<bool> GetPageData(string appName, string fromDate, string toDate, string searchType, string device, string siteUrl, List<string> pageUrls) 
     { 
      // Get the service from the initial method 
      bool ret = false; 

      WebmastersService service = await GetService(appName); 
      Google.Apis.Requests.BatchRequest b = new Google.Apis.Requests.BatchRequest(service); 

      try 
      { 
       foreach (string pageUrl in pageUrls) 
       { 
        SearchAnalyticsQueryRequest qry = new SearchAnalyticsQueryRequest(); 
        qry.StartDate = fromDate; 
        qry.EndDate = toDate; 
        qry.SearchType = searchType; 
        qry.RowLimit = 5000; 
        qry.Dimensions = new List<string>() { "query" }; 
        qry.DimensionFilterGroups = new List<ApiDimensionFilterGroup>(); 
        ApiDimensionFilterGroup filterGroup = new ApiDimensionFilterGroup(); 
        ApiDimensionFilter filter = new ApiDimensionFilter(); 
        filter.Dimension = "device"; 
        filter.Expression = device; 
        filter.Operator__ = "equals"; 

        ApiDimensionFilter filter2 = new ApiDimensionFilter(); 
        filter2.Dimension = "page"; 
        filter2.Expression = pageUrl; 
        filter2.Operator__ = "equals"; 

        filterGroup.Filters = new List<ApiDimensionFilter>(); 
        filterGroup.Filters.Add(filter); 
        filterGroup.Filters.Add(filter2); 
        qry.DimensionFilterGroups.Add(filterGroup); 

        var req = service.Searchanalytics.Query(qry, siteUrl); 
        b.Queue<SearchAnalyticsQueryResponse>(req, (response, error, i, message) => 
        { 
         if (error == null) 
         { 
          // Process the results 
          ret = true; 
         } 
         else 
         { 
          Console.WriteLine(error.Message); 
         } 

        }); 
        await b.ExecuteAsync(); 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Exception occurred getting page stats : " + ex.Message); 
       ret = false; 
      } 

      return ret; 
     }   
    } 
} 

粘貼此進入一個新的控制檯應用程序的Program.cs文件,並通過添加的NuGet Google.Apis.Webmasters.v3。它在c:\ temp中查找wmt.json文件,但調整驗證碼以適應您的設置。如果我向pageUrls列表添加超過5個頁面的URL,那麼我會得到Quota Exceeded異常。

+0

您知道600批次的批次仍然會計爲600,而您的配額是正確的嗎?你在使用Oauth2嗎? – DaImTo

+0

是的,實際上它似乎使用600 + 1,但它仍低於我所理解的配額。是的,我們正在使用OAuth2 –

+0

你可以發佈一些代碼,以便我可以測試它。 – DaImTo

回答

2

我發現所述配額似乎並不是配額。儘管我總是處於或低於規定的速率限制(20 /秒),爲了避免同樣的問題(1 /秒),我必須減慢我的請求速度。此外,它聲稱在文檔中出現rateLimitExceeded錯誤的速度過快,但實際上它返回quotaExceeded錯誤。這可能與Google如何平均處理請求率有關(因爲我們提出的一些請求是同時發生的,儘管長期平均值設計爲低於20 /秒),但我無法確定。