Создание клиента поиска в виде консольного приложения на C#
Предупреждение
30 октября 2020 г. API Поиск Bing перенесены из служб ИИ Azure в Поиск Bing Services. Эта документация приводится только для справки. Обновленную информацию см. в документации по API Поиска Bing. Инструкции по созданию ресурсов Azure для Поиска Bing приведены в статье Создание ресурса для Поиска Bing с помощью Azure Marketplace.
В этом руководстве объясняется, как создать простое консольное приложение .NET Core, с помощью которого пользователи могут отправлять запросы в API Bing для поиска в Интернете и отображает ранжированные результаты.
В этом учебнике описаны следующие действия:
- выполнение простого запроса к API Bing для поиска в Интернете;
- отображение результатов запроса в порядке приоритета.
Предварительные требования
Для работы с этим руководством вам потребуется следующее:
- подписка Azure — создайте бесплатную учетную запись.
- Получив подписку Azure, создайте ресурс Поиск Bing в портал Azure, чтобы получить ключ и конечную точку. После развертывания щелкните Перейти к ресурсам.
- Интегрированная среда разработки Visual Studio.
Создание проекта консольного приложения
В Visual Studio создайте проект с помощью клавиш Ctrl
+Shift
+N
.
В диалоговом окне Создать проект выберите Visual C# > Классический рабочий стол Windows > Консольное приложение (.NET Framework).
Присвойте приложению имя MyConsoleSearchApp и нажмите кнопку ОК.
Добавление в проект пакета NuGet для JSON.NET
Json.NET позволяет работать с ответами JSON, которые возвращает API. Добавьте в проект этот пакет NuGet.
- В обозревателе решений щелкните проект правой кнопкой мыши и выберите пункт Управление пакетами NuGet... .
- На вкладке Обзор выполните поиск по
Newtonsoft.Json
. Выберите последнюю версию и щелкните Установить. - Нажмите кнопку ОК в окне Просмотреть изменения.
- Закройте вкладку Visual Studio NuGet: MyConsoleSearchApp.
Добавление ссылки на System.Web
В этом руководстве используется сборка System.Web
. Добавьте в проект ссылку на эту сборку.
- В обозревателе решений щелкните правой кнопкой мыши Ссылки и выберите Добавить ссылку... .
- Выберите Сборки > Платформа, затем прокрутите вниз и установите флажок System.Web
- Нажмите кнопку ОК.
Добавление необходимых операторов using
Чтобы работал код из этого руководства, нужны три дополнительных оператора using. Добавьте эти операторы после существующих операторов using
в верхней части файла Program.cs:
using System.Web;
using System.Net.Http;
Предложение на ввод запроса
В обозревателе решений откройте Program.cs. Внесите изменения в метод Main()
:
static void Main()
{
// Get the user's query
Console.Write("Enter Bing query: ");
string userQuery = Console.ReadLine();
Console.WriteLine();
// Run the query and display the results
RunQueryAndDisplayResults(userQuery);
// Prevent the console window from closing immediately
Console.WriteLine("\nHit ENTER to exit...");
Console.ReadLine();
}
Этот метод выполняет следующее:
- предлагает пользователю ввести запрос;
- вызывает
RunQueryAndDisplayResults(userQuery)
для выполнения запроса и отображения результатов; - ожидает ввода данных пользователем, чтобы окно консоли не закрывалось сразу после вывода.
Поиск результатов запроса с помощью API Bing для поиска в Интернете
Добавьте метод, который передает запрос в API и отображает результаты.
static void RunQueryAndDisplayResults(string userQuery)
{
try
{
// Create a query
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "<YOUR_SUBSCRIPTION_KEY_GOES_HERE>");
var queryString = HttpUtility.ParseQueryString(string.Empty);
queryString["q"] = userQuery;
var query = "https://api.cognitive.microsoft.com/bing/v7.0/search?" + queryString;
// Run the query
HttpResponseMessage httpResponseMessage = client.GetAsync(query).Result;
// Deserialize the response content
var responseContentString = httpResponseMessage.Content.ReadAsStringAsync().Result;
Newtonsoft.Json.Linq.JObject responseObjects = Newtonsoft.Json.Linq.JObject.Parse(responseContentString);
// Handle success and error codes
if (httpResponseMessage.IsSuccessStatusCode)
{
DisplayAllRankedResults(responseObjects);
}
else
{
Console.WriteLine($"HTTP error status code: {httpResponseMessage.StatusCode.ToString()}");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Этот метод выполняет следующее:
- создает
HttpClient
для отправки запроса к API поиска в Интернете; - задает заголовок HTTP
Ocp-Apim-Subscription-Key
, по которому Bing проверяет подлинность запроса; - выполняет запрос и использует JSON.net для десериализации результатов;
- вызывает
DisplayAllRankedResults(responseObjects)
для отображения результатов в порядке приоритета.
Не забудьте задать правильное значение ключа подписки в параметре Ocp-Apim-Subscription-Key
.
Отображение ранжированных результатов
Перед тем, как переходить к отображению результатов в порядке приоритета, давайте рассмотрим пример ответа на простой запрос поиска в Интернете:
{
"_type" : "SearchResponse",
"webPages" : {
"webSearchUrl" : "https:\/\/www.bing.com\/cr?IG=70BE289346...",
"totalEstimatedMatches" : 982000,
"value" : [{
"id" : "https:\/\/api.cognitive.microsoft.com\/api\/v7\/#WebPages.0",
"name" : "Contoso Sailing Club - Seattle",
"url" : "https:\/\/www.bing.com\/cr?IG=70BE289346ED4594874FE...",
"displayUrl" : "https:\/\/contososailingsea...",
"snippet" : "Come sail with Contoso in Seattle...",
"dateLastCrawled" : "2017-04-07T02:25:00"
},
{
"id" : "https:\/\/api.cognitive.microsoft.com\/api\/7\/#WebPages.6",
"name" : "Contoso Sailing Lessons - Official Site",
"url" : "http:\/\/www.bing.com\/cr?IG=70BE289346ED4594874FE...",
"displayUrl" : "https:\/\/www.constososailinglessonsseat...",
"snippet" : "Contoso sailing lessons in Seattle...",
"dateLastCrawled" : "2017-04-09T14:30:00"
},
...
],
"someResultsRemoved" : true
},
"relatedSearches" : {
"id" : "https:\/\/api.cognitive.microsoft.com\/api\/7\/#RelatedSearches",
"value" : [{
"text" : "sailing lessons",
"displayText" : "sailing lessons",
"webSearchUrl" : "https:\/\/www.bing.com\/cr?IG=70BE289346E..."
}
...
]
},
"rankingResponse" : {
"mainline" : {
"items" : [{
"answerType" : "WebPages",
"resultIndex" : 0,
"value" : {
"id" : "https:\/\/api.cognitive.microsoft.com\/api\/v7\/#WebPages.0"
}
},
{
"answerType" : "WebPages",
"resultIndex" : 1,
"value" : {
"id" : "https:\/\/api.cognitive.microsoft.com\/api\/v7\/#WebPages.1"
}
}
...
]
},
"sidebar" : {
"items" : [{
"answerType" : "RelatedSearches",
"value" : {
"id" : "https:\/\/api.cognitive.microsoft.com\/api\/v7\/#RelatedSearches"
}
}]
}
}
}
Объект JSON rankingResponse
(подробнее описан в документации) предоставляет правильный порядок отображения для результатов поиска. Он содержит одну или несколько следующих групп с учетом приоритета:
-
pole
: Результаты поиска, которые должны отображаться наиболее заметным образом (например, над основной частью и боковой панелью). -
mainline
: Результаты поиска для отображения в основном поле. -
sidebar
: Результаты поиска для отображения на боковой панели. Если боковая панель отсутствует, эти результаты отображаются под основной частью.
JSON с ранжированным ответом может содержать одну или несколько этих групп.
Добавьте в файл Program.cs следующий метод для отображения результатов в порядке приоритета:
static void DisplayAllRankedResults(Newtonsoft.Json.Linq.JObject responseObjects)
{
string[] rankingGroups = new string[] { "pole", "mainline", "sidebar" };
// Loop through the ranking groups in priority order
foreach (string rankingName in rankingGroups)
{
Newtonsoft.Json.Linq.JToken rankingResponseItems = responseObjects.SelectToken($"rankingResponse.{rankingName}.items");
if (rankingResponseItems != null)
{
foreach (Newtonsoft.Json.Linq.JObject rankingResponseItem in rankingResponseItems)
{
Newtonsoft.Json.Linq.JToken resultIndex;
rankingResponseItem.TryGetValue("resultIndex", out resultIndex);
var answerType = rankingResponseItem.Value<string>("answerType");
switch (answerType)
{
case "WebPages":
DisplaySpecificResults(resultIndex, responseObjects.SelectToken("webPages.value"), "WebPage", "name", "url", "displayUrl", "snippet");
break;
case "News":
DisplaySpecificResults(resultIndex, responseObjects.SelectToken("news.value"), "News", "name", "url", "description");
break;
case "Images":
DisplaySpecificResults(resultIndex, responseObjects.SelectToken("images.value"), "Image", "thumbnailUrl");
break;
case "Videos":
DisplaySpecificResults(resultIndex, responseObjects.SelectToken("videos.value"), "Video", "embedHtml");
break;
case "RelatedSearches":
DisplaySpecificResults(resultIndex, responseObjects.SelectToken("relatedSearches.value"), "RelatedSearch", "displayText", "webSearchUrl");
break;
}
}
}
}
}
Этот метод выполняет следующее:
- в цикле обрабатывает группы
rankingResponse
, которые содержит ответ; - отображает элементы каждой из групп, вызывая
DisplaySpecificResults(...)
.
Добавьте в файл Program.cs следующие два метода:
static void DisplaySpecificResults(Newtonsoft.Json.Linq.JToken resultIndex, Newtonsoft.Json.Linq.JToken items, string title, params string[] fields)
{
if (resultIndex == null)
{
foreach (Newtonsoft.Json.Linq.JToken item in items)
{
DisplayItem(item, title, fields);
}
}
else
{
DisplayItem(items.ElementAt((int)resultIndex), title, fields);
}
}
static void DisplayItem(Newtonsoft.Json.Linq.JToken item, string title, string[] fields)
{
Console.WriteLine($"{title}: ");
foreach( string field in fields )
{
Console.WriteLine($"- {field}: {item[field]}");
}
Console.WriteLine();
}
Эти методы работают совместно, чтобы вывести в консоль результаты поиска.
Выполнение приложения
Запустите приложение. Результат должен выглядеть следующим образом.
Enter Bing query: sailing lessons seattle
WebPage:
- name: Contoso Sailing Club - Seattle
- url: https://www.bing.com/cr?IG=70BE289346ED4594874FE...
- displayUrl: https://contososailingsea....
- snippet: Come sail with Contoso in Seattle...
WebPage:
- name: Contoso Sailing Lessons Seattle - Official Site
- url: http://www.bing.com/cr?IG=70BE289346ED4594874FE...
- displayUrl: https://www.constososailinglessonsseat...
- snippet: Contoso sailing lessons in Seattle...
...
Дальнейшие действия
Изучите дополнительные сведения об использовании ранжирования при отображении ответов.