为什么我对 Google 自定义搜索 API 的调用会因请求错误(无效参数)而失败?
Why does my call to the Google Custom Search API fail with a Request Error (Invalid Argument)?
我需要获取 google 搜索的结果,以便遍历并解析它们。考虑到这个目标,我(尽我所能)遵循了关于如何做到这一点的教程 here
这是我的代码,基于上面引用的文章中的 sample/example 代码:
private void btnRentFlick_Click(object sender, EventArgs e)
{
OpenBestPageForSearchString("rent amazon movie Will Penny");
}
private void OpenBestPageForSearchString(string searchStr)
{
try
{
const string apiKey = "blaBlaBla"; // "blaBlaBla" stands for my API key
const string searchEngineId = "bla"; // "bla" stands for various things I tried: my client_id
(also called UniqueId), private_key_id (also called KeyId), and project_id. Not having
the correct value may be the problem. If so, how do I get it?
const string query = "rent amazon movie Will Penny";
var customSearchService = new CustomsearchService(new BaseClientService.Initializer { ApiKey
= apiKey });
//CseResource.ListRequest listRequest = customSearchService.Cse.List(query); // This is the
code in the article, but it won't compile - "no overload for "List" takes one argument"
// So how is the value in "query" assigned, then?
CseResource.ListRequest listRequest = customSearchService.Cse.List();
listRequest.Cx = searchEngineId;
List<string> linksReturned = new List<string>();
IList<Result> paging = new List<Result>();
var count = 0; // I don't know what the purpose of the counting is, but I'll leave as-is
until I get it working at least
while (paging != null)
{
listRequest.Start = count * 10 + 1;
paging = listRequest.Execute().Items; // this takes several seconds, then it throws an
exception
if (paging != null)
{
foreach (var item in paging)
{
linksReturned.Add("Title : " + item.Title + Environment.NewLine + "Link : " +
item.Link +
Environment.NewLine + Environment.NewLine);
}
}
count++;
}
MessageBox.Show("Done with google amazon query");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
正如该行末尾的注释所说,这行代码:
paging = listRequest.Execute().Items;
...工作了几秒钟,然后抛出异常,即:
那么是什么导致了这个异常呢?是因为我分配的 searchEngineId 值不好吗?还是因为搜索字符串(分配给查询变量)没有提供给调用?
关于我的 ID 的信息包含在 google 提供的 .json 文件中,其中没有“searchEngineId”值。这是它包含的内容:
"type": "service_account", "project_id": "flix4famsasinlocator",
"private_key_id": "[my private key id]", "private_key": "-----BEGIN
PRIVATE KEY-----. . . PRIVATE KEY-----\n", "client_email":
"[bla].gserviceaccount.com", "client_id": "[my client Id]",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url":
"https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url":
"https://www.googleapis.com/robot/v1/metadata/x509/[bla]gserviceaccount.com"
因此,尽管前面提到的文章据称是,而且乍一看似乎正是医生要求的,但我 运行 进入了一堵相当大的墙。有谁知道如何攀登这堵墙 - 也许主要是通过向 CseResource.ListRequest 对象提供搜索字符串?
更新
首先尝试 DalmTo 的代码,我使用了这个(没有显示他的 GetService() 方法,我逐字复制):
var query = "rent amazon movie Will Penny";
var service = GetService("theRainInSpainFallsMainlyOnTheDirt");
var request = service.Cse.List();
// add option values to the request here.
request.ExactTerms = query;
request.Q = query;
var response = request.ExecuteAsync();
// my contribution:
List<string> linksReturned = new List<string>();
foreach (var item in response.Result.Items)
{
//Console.WriteLine(item.Title);
// next two lines also mine
MessageBox.Show(string.Format("Title: {0}; Link: {1}; ETag: {2}", item.Title, item.Link, item.ETag));
linksReturned.Add(item.Link);
}
...但是在 foreach 循环中抛出了这个异常:
更新 2
是的,这有效(改编自 Trekco 的回答):
const string apiKey = "gr8GooglyMoogly";
const string searchEngineId = "theRainInSpainFallsMainOnTheDirt";
const string query = "rent amazon movie Will Penny";
var customSearchService = new CustomsearchService(new BaseClientService.Initializer { ApiKey = apiKey });
CseResource.ListRequest listRequest = customSearchService.Cse.List();
listRequest.Cx = searchEngineId;
listRequest.Q = query;
List<string> linksReturned = new List<string>();
IList<Result> paging = new List<Result>();
var count = 0;
while (paging != null)
{
listRequest.Start = count * 10 + 1;
paging = listRequest.Execute().Items;
if (paging != null)
{
foreach (var item in paging)
{
linksReturned.Add(item.Link);
}
}
count++;
}
查询未发送至 google。要修复您的代码,您需要告诉 api 要使用的查询。在 listRequest.Cx = searchEngineId;
之后添加 listRequest.Q = query;
var count = 0;
string apiKey = "THE API KEY";
string searchEngineId = "THE SEARCH ENGIN ID";
string query = "rent amazon movie Will Penny";
var customSearchService = new CustomsearchService(new BaseClientService.Initializer
{
ApiKey = apiKey
});
CseResource.ListRequest listRequest = customSearchService.Cse.List();
listRequest.Cx = searchEngineId;
listRequest.Q = query; // <---- Add this line
List<string> linksReturned = new List<string>();
while (count < 10) // Google limit you to 100 records
{
listRequest.Start = count * 10;
var paging = listRequest.Execute().Items;
foreach (var item in paging)
{
linksReturned.Add("Title : " + item.Title + Environment.NewLine + "Link : " +
item.Link +
Environment.NewLine + Environment.NewLine);
}
count++;
}
在您的代码中有一条注释,您不知道 var count = 0;
的用途。这是为了跟踪您请求了多少项目。
如果您查看 google 的文档,您会发现它们最多只会 return 100 个结果。之后他们会给你一个错误。该错误也将是相同的通用消息:“INVALID_ARGUMENT”
您可以在此处查看自定义搜索 api 要求:https://developers.google.com/custom-search/v1/reference/rest/v1/cse/list
searchEngineId
变量是您在网站 https://www.google.com/cse/all 上生成的搜索引擎 ID。您遵循的文档有点过时了。您会在这里找到 ID:
如果你查看文档cse.list我想你会发现list方法没有必填字段,这意味着你需要按以下方式添加选项值。
我认为 ExactTerms
可能就是您要找的人。但它也可能是 Q
我认为您应该仔细阅读选项值并决定哪一个最适合您的目的。
var query = "rent amazon movie Will Penny";
var service = GetService("MYKEY");
var request = service.Cse.List();
// add option values to the request here.
request.ExactTerms = query;
request.Q = query;
var response = request.ExecuteAsync();
foreach (var item in response.Result.Items)
{
Console.WriteLine(item.Title);
}
我的获取服务方法
public static CustomsearchService GetService(string apiKey)
{
try
{
if (string.IsNullOrEmpty(apiKey))
throw new ArgumentNullException("api Key");
return new CustomsearchService(new BaseClientService.Initializer()
{
ApiKey = apiKey,
ApplicationName = string.Format("{0} API key example", System.Diagnostics.Process.GetCurrentProcess().ProcessName),
});
}
catch (Exception ex)
{
throw new Exception("Failed to create new Customsearch Service", ex);
}
}
我需要获取 google 搜索的结果,以便遍历并解析它们。考虑到这个目标,我(尽我所能)遵循了关于如何做到这一点的教程 here
这是我的代码,基于上面引用的文章中的 sample/example 代码:
private void btnRentFlick_Click(object sender, EventArgs e)
{
OpenBestPageForSearchString("rent amazon movie Will Penny");
}
private void OpenBestPageForSearchString(string searchStr)
{
try
{
const string apiKey = "blaBlaBla"; // "blaBlaBla" stands for my API key
const string searchEngineId = "bla"; // "bla" stands for various things I tried: my client_id
(also called UniqueId), private_key_id (also called KeyId), and project_id. Not having
the correct value may be the problem. If so, how do I get it?
const string query = "rent amazon movie Will Penny";
var customSearchService = new CustomsearchService(new BaseClientService.Initializer { ApiKey
= apiKey });
//CseResource.ListRequest listRequest = customSearchService.Cse.List(query); // This is the
code in the article, but it won't compile - "no overload for "List" takes one argument"
// So how is the value in "query" assigned, then?
CseResource.ListRequest listRequest = customSearchService.Cse.List();
listRequest.Cx = searchEngineId;
List<string> linksReturned = new List<string>();
IList<Result> paging = new List<Result>();
var count = 0; // I don't know what the purpose of the counting is, but I'll leave as-is
until I get it working at least
while (paging != null)
{
listRequest.Start = count * 10 + 1;
paging = listRequest.Execute().Items; // this takes several seconds, then it throws an
exception
if (paging != null)
{
foreach (var item in paging)
{
linksReturned.Add("Title : " + item.Title + Environment.NewLine + "Link : " +
item.Link +
Environment.NewLine + Environment.NewLine);
}
}
count++;
}
MessageBox.Show("Done with google amazon query");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
正如该行末尾的注释所说,这行代码:
paging = listRequest.Execute().Items;
...工作了几秒钟,然后抛出异常,即:
那么是什么导致了这个异常呢?是因为我分配的 searchEngineId 值不好吗?还是因为搜索字符串(分配给查询变量)没有提供给调用?
关于我的 ID 的信息包含在 google 提供的 .json 文件中,其中没有“searchEngineId”值。这是它包含的内容:
"type": "service_account", "project_id": "flix4famsasinlocator",
"private_key_id": "[my private key id]", "private_key": "-----BEGIN PRIVATE KEY-----. . . PRIVATE KEY-----\n", "client_email": "[bla].gserviceaccount.com", "client_id": "[my client Id]",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/[bla]gserviceaccount.com"
因此,尽管前面提到的文章据称是,而且乍一看似乎正是医生要求的,但我 运行 进入了一堵相当大的墙。有谁知道如何攀登这堵墙 - 也许主要是通过向 CseResource.ListRequest 对象提供搜索字符串?
更新
首先尝试 DalmTo 的代码,我使用了这个(没有显示他的 GetService() 方法,我逐字复制):
var query = "rent amazon movie Will Penny";
var service = GetService("theRainInSpainFallsMainlyOnTheDirt");
var request = service.Cse.List();
// add option values to the request here.
request.ExactTerms = query;
request.Q = query;
var response = request.ExecuteAsync();
// my contribution:
List<string> linksReturned = new List<string>();
foreach (var item in response.Result.Items)
{
//Console.WriteLine(item.Title);
// next two lines also mine
MessageBox.Show(string.Format("Title: {0}; Link: {1}; ETag: {2}", item.Title, item.Link, item.ETag));
linksReturned.Add(item.Link);
}
...但是在 foreach 循环中抛出了这个异常:
更新 2
是的,这有效(改编自 Trekco 的回答):
const string apiKey = "gr8GooglyMoogly";
const string searchEngineId = "theRainInSpainFallsMainOnTheDirt";
const string query = "rent amazon movie Will Penny";
var customSearchService = new CustomsearchService(new BaseClientService.Initializer { ApiKey = apiKey });
CseResource.ListRequest listRequest = customSearchService.Cse.List();
listRequest.Cx = searchEngineId;
listRequest.Q = query;
List<string> linksReturned = new List<string>();
IList<Result> paging = new List<Result>();
var count = 0;
while (paging != null)
{
listRequest.Start = count * 10 + 1;
paging = listRequest.Execute().Items;
if (paging != null)
{
foreach (var item in paging)
{
linksReturned.Add(item.Link);
}
}
count++;
}
查询未发送至 google。要修复您的代码,您需要告诉 api 要使用的查询。在 listRequest.Cx = searchEngineId;
之后添加 listRequest.Q = query;
var count = 0;
string apiKey = "THE API KEY";
string searchEngineId = "THE SEARCH ENGIN ID";
string query = "rent amazon movie Will Penny";
var customSearchService = new CustomsearchService(new BaseClientService.Initializer
{
ApiKey = apiKey
});
CseResource.ListRequest listRequest = customSearchService.Cse.List();
listRequest.Cx = searchEngineId;
listRequest.Q = query; // <---- Add this line
List<string> linksReturned = new List<string>();
while (count < 10) // Google limit you to 100 records
{
listRequest.Start = count * 10;
var paging = listRequest.Execute().Items;
foreach (var item in paging)
{
linksReturned.Add("Title : " + item.Title + Environment.NewLine + "Link : " +
item.Link +
Environment.NewLine + Environment.NewLine);
}
count++;
}
在您的代码中有一条注释,您不知道 var count = 0;
的用途。这是为了跟踪您请求了多少项目。
如果您查看 google 的文档,您会发现它们最多只会 return 100 个结果。之后他们会给你一个错误。该错误也将是相同的通用消息:“INVALID_ARGUMENT”
您可以在此处查看自定义搜索 api 要求:https://developers.google.com/custom-search/v1/reference/rest/v1/cse/list
searchEngineId
变量是您在网站 https://www.google.com/cse/all 上生成的搜索引擎 ID。您遵循的文档有点过时了。您会在这里找到 ID:
如果你查看文档cse.list我想你会发现list方法没有必填字段,这意味着你需要按以下方式添加选项值。
我认为 ExactTerms
可能就是您要找的人。但它也可能是 Q
我认为您应该仔细阅读选项值并决定哪一个最适合您的目的。
var query = "rent amazon movie Will Penny";
var service = GetService("MYKEY");
var request = service.Cse.List();
// add option values to the request here.
request.ExactTerms = query;
request.Q = query;
var response = request.ExecuteAsync();
foreach (var item in response.Result.Items)
{
Console.WriteLine(item.Title);
}
我的获取服务方法
public static CustomsearchService GetService(string apiKey)
{
try
{
if (string.IsNullOrEmpty(apiKey))
throw new ArgumentNullException("api Key");
return new CustomsearchService(new BaseClientService.Initializer()
{
ApiKey = apiKey,
ApplicationName = string.Format("{0} API key example", System.Diagnostics.Process.GetCurrentProcess().ProcessName),
});
}
catch (Exception ex)
{
throw new Exception("Failed to create new Customsearch Service", ex);
}
}