Используем поисковый движок Bing на ASP.NET-сайте

Программирование

Tagged Under : , ,

Ну, что ж продолжим начатое мной в предыдущей статье, посвященной использованию поискового движка гугл на asp.net-сайте, только на этот раз припарировать будет творение microsoft – Bing, который выгодно отличается тем, что не лимитирует количество запросов к своему сервису, а значит может вполне быть использован даже на ресурсах, где кол-во запросов может превышать 1000 в сутки, причем бесплатно в отличие от движков google и yandex.

Оговорюсь сразу по запросу «bing api» можно найти хорошую документацию и примеры, ориентированные как раз на asp.net разработчиков, а не только на php.
Результатом же моих изысканий стал небольшой класс, код которого и представлен ниже и который вполне можно использовать при минимальной доработке в своих проектах.

    public class BingSearch
    {
        private string ServiceUrl = "http://api.bing.net/xml.aspx?AppID={0}&Options=EnableHighlighting&sources=web&query={1}{2}{3}";
        private char startSel = 'uE000';
        private char endSel = 'uE001';

        public string startTag
        {
            get;
            set;
        }

        public string endTag
        {
            get;
            set;
        }

        public string CommonParams
        {
            get;
            set;
        }
        public string AppID
        {
            get;
            set;
        }

        public string SearchTerm
        {
            get;
            set;
        }

        public BingSearchStatus Status
        {
            get
            {
                return _status;
            }
        }

        public int Count
        {
            set
            {
                _Count = value;
            }
        }
        int _Count = 10;

        public int Offset
        {
            set
            {
                _Offset = value;
            }
        }
        int _Offset = 1;

        public int AllCount
        {
            get
            {
                return _AllCount;
            }
        }
        int _AllCount = 0;

        BingSearchStatus _status = BingSearchStatus.OK;

        public BingSearch()
        {
        }

        public BingSearch(string appID, string searchTerm)
        {
            AppID = appID;
            SearchTerm = searchTerm;
        }

        public List<BingResult> GetResults()
        {
            string xml = SendRequest(GetQuery());
            List<BingResult> results = ParseResults(xml);
            return results;
        }

        public List<BingResult> GetResults(string appID, string searchTerm)
        {
            AppID = appID;
            SearchTerm = searchTerm;
            string xml = SendRequest(GetQuery());
            List<BingResult> results = ParseResults(xml);
            return results;
        }

        private string GetQuery()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("&web.count={0}", _Count);
            sb.AppendFormat("&web.offset={0}", _Offset);
            string query = string.Format(ServiceUrl, AppID, SearchTerm, sb.ToString(), CommonParams);
            return query;
        }

        private string SendRequest(string query)
        {
            string result = "";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(query);
            request.Method = "GET";
            try
            {
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                        {
                            result = sr.ReadToEnd();
                        }
                        _status = BingSearchStatus.OK;
                    }
                    else
                    {
                        result = "";
                        _status = BingSearchStatus.FAIL;
                    }
                }
            }
            catch(Exception)
            {
                _status = BingSearchStatus.FAIL;
            }
            return result;
        }

        private List<BingResult> ParseResults(string xml)
        {
            List<BingResult> list = new List<BingResult>();
                       
            XmlDocument document = new XmlDocument();
           
            document.LoadXml(xml);
            XmlElement element = document.DocumentElement;
            if (element.ChildNodes[1].Name == "Errors")
            {
                 _status = BingSearchStatus.FAIL;
                 return list;
            }
           
            _AllCount = int.Parse(element.ChildNodes[1].ChildNodes[0].InnerText);
            XmlNode root = element.ChildNodes[1];
            XmlNodeList nodes = root.ChildNodes[2].ChildNodes;
            foreach (XmlNode node in nodes)
            {
                BingResult resultItem = new BingResult();
                foreach (XmlNode child in node.ChildNodes)
                {
                    switch (child.Name)
                    {
                        case "web:Title":

                            resultItem.Title = child.InnerText.Replace(startSel.ToString(), startTag).Replace(endSel.ToString(), endTag);
                            break;
                        case "web:Description":
                            resultItem.Description = child.InnerText.Replace(startSel.ToString(), startTag).Replace(endSel.ToString(), endTag);
                            break;
                        case "web:DisplayDate":
                            resultItem.Date = Convert.ToDateTime(child.InnerText);
                            break;
                        case "web:Url":
                            resultItem.Url = child.InnerText;
                            break;
                        case "web:CacheUrl":
                            resultItem.CacheUrl = child.InnerText;
                            break;
                        case "web:DisplayUrl":
                            resultItem.DisplayUrl = child.InnerText.Replace(startSel.ToString(), startTag).Replace(endSel.ToString(), endTag);
                            break;
                    }
                }

                list.Add(resultItem);
            }
            return list;
        }
    }

    public class BingResult
    {
        public string Title;
        public string Description;
        public DateTime Date;
        public string Url;
        public string CacheUrl;
        public string DisplayUrl;
    }

    public enum BingSearchStatus
    {
        OK,
        FAIL
    }

Простейший пример использования:

            BingSearch search = new BingSearch("специальный код, дается бесплатно", "asp.net site:kosfiz.ru");
            search.endTag = "</b>";
            search.startTag = "<b>";
            search.Count = 50; //с количеством результатов надо быть осторожнее: при превышении определённого числа будет ошибка
            List<BingResult> list = search.GetResults();
            if (search.Status == BingSearchStatus.OK)
            {
                foreach (var item in list)
                    Console.WriteLine(string.Format(@"{0} n {1} n {2} nnn", item.Title, item.Description, item.DisplayUrl)); // я результаты в консоль выводил, но никто не мешает их затолкать в страницу
            }
            else
                Console.WriteLine("search is fail"); // ошибочка

Вот как-то так. Вообщем результаты даёт хорошие, использование бесплатное и уж точно лучше чем использовать продукт microsoft Search Server, о котором ещё много тут будет написано хорошего и не очень.
Собственно. как не трудно догадаться я использовал xml-интерфейс сего движка, но надо сказать что bing поддерживает ещё и soap и json, так что дерзайте.




Оставить комментарий