BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Usługa sieciowa MSN Search w aplikacji C#

04-06-2006 20:27 | kitikat
Artykuł zawiera opis usługi sieciowej MSN Search oraz przykładowego programu, który wykorzystuje tę usługę.

Jedną z najistotniejszych technologii, które mogą dać nam, programistom, olbrzymie pole do popisu w dziedzinie programowania internetowego jest technologia Web Services. Dzięki niej można w stosunkowo prosty sposób łączyć możliwości programów napisanych w różnych językach programowania, a także wykorzystywać różnego rodzaju serwisy działające w sieci do własnych celów. Celem niniejszego artykułu jest właśnie zaprezentowanie możliwości takiego serwisu – napiszemy program, który wykorzystywać będzie usługę sieciową MSN Search Web Services.

Usługa ta umożliwia nie tylko klasyczne wyszukiwanie stron WWW, ale także przeglądanie innych usług oferowanych przez wyszukiwarkę MSN.

Do utworzenia programu wykorzystamy program Microsoft Visual C# 2005 Express Edition; dodatkowo, do pobrania specjalnego klucza, umożliwiającego korzystanie z usługi, wymagane jest posiadanie konta w usłudze Microsoft Passport (jest ono darmowe).

Zanim jednak przystąpimy do aktu twórczego, zainstalujemy MSN Search SDK oraz skonfigurujemy projekt aplikacji. Następnie omówię sposób działania usługi MSN Search.

Instalacja (opcjonalna)

Aby program mógł korzystać z dobrodziejstw usługi wyszukiwania, wymagane jest dodanie referencji sieciowej do projektu (ang. Web Reference). Dobrze jest jednak mieć pod ręką dostępną dokumentację oraz przykłady. W tym celu wystarczy wejść na stronę http://www.microsoft.com/downloads/details.aspx?FamilyID=c271309b-02de-42a7-b23e-e19f68667197&displaylang=en a następnie przeprowadzić standardowy proces instalacji.

Dodanie referencji

Po uruchomieniu środowiska Microsoft Visual C# 2005 i utworzeniu nowego projektu radzę od razu zapisać projekt przy użyciu opcji File->Save All. Dzięki temu w przyszłości unikniemy problemów związanych m.in. współdziałaniem naszej aplikacji i firewalla. Następnie w panelu Solution Explorer klikamy prawym przyciskiem na element Web References i z listy wybieramy opcję Add Web Reference…. W polu URL wpisujemy adres:http://soap.search.msn.com/webservices.asmx?WSDL. Po jego zatwierdzeniu powinien naszym oczom ukazać się poniższy obrazek:

webservice1

Rysunek 1. Opis usługi wyświetlany na podstawie pliku WSDL


W polu tekstowym Web reference name można podać własną, bardziej przyjazną od domyślnej nazwę, po czym wystarczy kliknąć przycisk Add Reference.

Gotowe, chciałoby się rzec. Niestety, musimy uzyskać jeszcze specjalny klucz. W tym celu należy wejść na stronę http://search.msn.com/developer/appids.aspx?FORM=PMPD2. Jeśli jednak nie jesteśmy zalogowani przy użyciu usługi Microsoft Passport, zostaniemy automatycznie przekierowani na stronę logowania. W przypadku braku konta należy przeprowadzić krótki i prosty proces rejestracji. Po zalogowaniu się będziemy mieli możliwość utworzenia nowego klucza. W pole Application Name wpisujemy własną nazwę, dzięki której będziemy mogli rozróżniać klucze (jeden użytkownik może posiadać więcej, niż jeden klucz). Klucz znajdujący się pod nazwą należy skopiować i zachować – użyjemy go już za chwilę. Tymczasem do zakończenia procesu tworzenia nowego klucza pozostało nam zaakceptowanie umowy.

W tym momencie jesteśmy gotowi do rozpoczęcia tworzenia projektu. Naszym celem jest stworzenie substytutu strony www.search.msn.com – aplikacji, dzięki której będziemy mogli korzystać z wyszukiwarki przy pomocy zwykłej aplikacji. Zapewne wśród wielu Czytelników pojawiło się teraz pytanie – od czego zacząć?

Krótki opis usługi

Najistotniejszą klasą, wykonującą większość pracy, jest klasa MSNSearchService. Posiada ona tylko jedną metodę: Search(), występującą w dwóch wersjach: synchronicznej i asynchronicznej. Metoda Search() przyjmuje jeden parametr – obiekt klasy SearchRequest, a zwraca obiekt klasy SearchResponse. Proces korzystania z usługi MSN Search przebiega w sposób następujący:

1. Utworzenie obiektu klasy SearchRequest i nadanie jego właściwościom żądanych wartości.

2. Wywołanie metody Search() obiektu klasy MSNSearchService.

3. Wykorzystanie (zwróconego w wywołaniu powyższej metody) obiektu klasy SearchResponse.

Przyjrzyjmy się bliżej trzem powyżej wspomnianym klasom.

Klasa SearchRequest

Ważniejsze właściwości:

  • string AppID – to właśnie w tej właściwości umieszczamy klucz specjalny.

  • string CultureInfo – w niej przechowywana jest informacja o języku oraz kraju, w jakim mają być wyszukiwane strony. Przykład: ‘en-US’ – angielski/Stany Zjednoczone

  • string Query – treść zapytania

  • SourceRequest[] Requests – tablica zawierająca żądania, określone są w nich m.in. ilość wyników, jakie mają być pobrane i numer wyniku, od którego mają być pobierane (tzw. offset)

  • SafeSearchOptions SafeSearch – określenie poziomu bezpieczeństwa, tj. ograniczeń w pobieraniu wyników. Dostępne są trzy warianty:

    • Off – brak ograniczeń

    • Moderate – pobierane są jedynie teksty zawierające treści erotyczne

    • Strict – pobierane są zarówno teksty jak i obrazki zawierające treści erotyczne

Poza właściwościami klasa ta nie udostępnia żadnych ważnych metod.

Klasa SearchResponse

Ważniejsze właściwości:

  • SourceResponses[] Responses – tablica zawierająca odpowiedzi, po jednej na każde żądanie z właściwości Requests klasy SearchRequest

Klasa SourceResponse

Ważniejsze właściwości:

  • Result[] Results – tablica zawierająca szczegółowe informacje na temat każdego zwróconego wyniku

  • int Total – liczba wszystkich wyników, jakie znalazła wyszukiwarkę

Dokładniejsze informacje o wszystkich klasach znajdują się w dokumentacji SDK; niektóre klasy (np. Result) zostaną omówione także w dalszej części artykułu.

Tworzenie aplikacji czas zacząć – projektowanie interfejsu

Jeden obraz znaczy tyle, co tysiąc słów, dlatego zamieszczam obrazek z działającym programem, wraz z krótkim komentarzem.

webservice2

Interfejs można podzielić na trzy części. Po lewej stronie znajdują się komponenty, przy pomocy których możemy określić parametry wyszukiwania. W środku została umieszczona lista pobranych wyników, oraz licznik, dzięki któremu można przeglądać również kolejne listy z wynikami. Wreszcie, po prawej stronie odnajdujemy szczegółowe informacje o stronie wybranej z listy.

Początki zabawy w kodzie

Na początek proponuję dodać do listy przestrzeni nazw przestrzeń naszej usługi – korzystanie z niej będzie znacznie wygodniejsze. Dokonamy tego przy pomocy kodu:

[Kod C#]

using MSNSearch_WebService.com.msn.search.soap;

Nazwa naszego projektu to MSNSearch_WebService, co w połączeniu z domyślną nazwą usługi tworzy taką właśnie przestrzeń nazw.

Wewnątrz klasy formatki umieszczamy definicje zmiennych.

[Kod C#]

// Deklaracja zmiennych używanych przy obsłudze usługi sieciowej


private String[] jezyki = new String[] { "en-US", "de-DE", "fr-FR" };
private const String APP_ID = "klucz";
private MSNSearchService serwis;
private SearchRequest zapytanie;
private SourceRequest[] zapytania;
private SearchResponse odpowiedz;
private Result[] wyniki;

W powyższym bloku znajdują się deklaracje wszystkich ważniejszych obiektów; zostały one zadeklarowane globalnie, gdyż będą wykorzystywane w kilku metodach formatki.

Obiekt serwis oraz zapytanie musimy zainicjalizować już w konstruktorze.

[Kod C#]

// Konstruktor formatki aplikacji – inicjalizacja obiektu usługi


public MSNSearchWebServiceForm()
{
 InitializeComponent();
 serwis = new MSNSearchService(); // zdarzenie wywoływane po zakończeniu pobierania wyników wyszukiwania
 serwis.SearchCompleted += new SearchCompletedEventHandler(serwis_SearchCompleted);
 zapytanie = new SearchRequest();
 zapytanie.AppID = APP_ID;
}

Dlaczego akurat w konstruktorze? Otóż zdarzenie obiektu serwis (SearchCompleted) może być zaktualizowane o metodę obsługi tylko raz, natomiast raz utworzony obiekt zapytanie będziemy wykorzystywać w dwóch metodach, ponadto klucz APP_ID wystarczy zapisać tylko raz – nie będziemy musieli martwić się nim w dalszej części kodu.

Jedną z dwóch najważniejszych metod w całym programie, do której zmierzamy od jakiegoś czasu, jest metoda realizująca założenia etapu 1. Jest ona wywoływana w momencie kliknięcia przycisku Szukaj.

[Kod C#]

// Wysyłanie żądania do serwera usługi.


private void btnSzukaj_Click(object sender, EventArgs e)
{
 if (comboJezyk.SelectedIndex > -1)
 {
  // przygotowanie formatki do nowego wyszukiwania
  listWyniki.Items.Clear();
  textNrStrony.Value = 1;
  // konstruowanie żądania
  if (comboIlosc.Text == "")
   comboIlosc.Text = comboIlosc.Items[0].ToString();
  // na nasze potrzeby wystarczy jedno żądanie
  zapytania = new SourceRequest[] { new SourceRequest() };
  zapytania[0].Count = int.Parse(comboIlosc.Text);
  zapytania[0].Offset = 0;
  // przeszukujemy wszystkie części strony
  zapytania[0].ResultFields = ResultFieldMask.All;
  // zakres - strony internetowe
  zapytania[0].Source = SourceType.Web;
  // ograniczenie pobieranych treści
  switch (comboFiltr.SelectedIndex)
  {
   case 0:
    zapytanie.SafeSearch = SafeSearchOptions.Off;
   break;
   case 1:
    zapytanie.SafeSearch = SafeSearchOptions.Moderate;
   break;
   case 2:
    zapytanie.SafeSearch = SafeSearchOptions.Strict;
   break;
   default:
    zapytanie.SafeSearch = SafeSearchOptions.Off;
   break;
  }
  // treść zapytania
  zapytanie.Query = textZapytanie.Text;
  // przygotowane wcześniej żądania
  zapytanie.Requests = zapytania;
  // sposób oznaczenia szukanych słów w tekście - brak
  zapytanie.Flags = SearchFlags.None;
  // język wyszukiwania, ustalony na podstawie indeksu komponentu comboJezyk
  zapytanie.CultureInfo =  jezyki[comboJezyk.SelectedIndex];
  // początek wyszukiwania
  serwis.SearchAsync(zapytanie);
 }
}

Na początek, w metodzie btnSzukaj_Click proponuję zwrócić uwagę na właściwość ResultFields w klasie SourceRequest. Dzięki niej możemy ograniczyć poszukiwania tylko do tytułu, opisu bądź adresu URL, wybierając odpowiednią wartość z typu wyliczeniowego ResultFieldMask. Kolejna właściwość tej samej klasy (Source – przyjmuje wartości typu wyliczeniowego SourceType) określa, jaki zakres sieci będziemy przeszukiwać (nie tylko strony WWW, ale też np. reklamy).Wyszukiwarka może nawet doradzić nam, w jaki sposób powinno się zapisać dany wyraz (wartość SourceType.Spelling)! Na samym końcu rozpoczynamy synchroniczne wyszukiwanie. Gdy zostanie ono zakończone, obiekt serwis wywoła zdarzenie  SearchCompleted , a następnie uruchomiona zostanie metoda serwis_SearchCompleted.

.

[Kod C#]

// Odbieranie i wyświetlanie wyników na liście


private void serwis_SearchCompleted(object sender, SearchCompletedEventArgs e)
{
 // najistotniejsza właściwość argumentu zdarzenia
 odpowiedz = e.Result;
 int liczba = odpowiedz.Responses[0].Total;
 // pobieranie poszczególnych rezultatów
 wyniki = odpowiedz.Responses[0].Results;
 lblKomunikat.Text = "Znaleziono " + liczba + " wynik" + koncowka(liczba);
 textNrStrony.Visible = true;
 btnIdz.Visible = true;
 foreach (Result rezultat in wyniki)
 {
  listWyniki.Items.Add(rezultat.Title);
 }
 int ilosc_wynikow = int.Parse(comboIlosc.Text);
 if (liczba == 0)
  textNrStrony.Maximum = 1;
 else
  textNrStrony.Maximum = liczba / ilosc_wynikow + ((liczba % ilosc_wynikow == 0)?0:1);
}

Jak można się domyśleć, najważniejszym zadaniem tej metody jest wyświetlenie na liście wyników wyszukiwania. Korzystamy z odpowiedzi o indeksie 0, ponieważ tylko jedno żądanie zostało przez nas uprzednio wysłane. Oprócz tego wyświetlamy stosowny komunikat oraz dajemy użytkownikowi dostęp do dwóch komponentów, które nie mogły być dostępne przed rozpoczęciem wyszukiwania. Ostatnie trzy linijki ograniczają komponent klasy NumericUpDown (obiekt textNrStrony) tak, aby przy kolejnych wyszukiwaniach ilość możliwych do obejrzenia stron była odpowiednia. Funkcja koncowka ma za zadanie zwrócić odpowiednią końcówkę wyrazu, w zależności od podanej liczby (pusta, ‘i’ lub ‘ów’).

Ostatnią godną uwagi metodą jest zdarzenie kliknięcia przycisku Idź. Wykorzystujemy w nim globalny dostęp do zmiennej zapytanie, dzięki czemu będziemy musieli zmienić tylko jedną właściwość żądania – Offset.

[Kod C#]

// przeglądanie kolejnych stron wyszukiwania
private void btnIdz_Click(object sender, EventArgs e)
{
 listWyniki.Items.Clear();
 zapytanie.Requests[0].Offset = (int)((textNrStrony.Value - 1) * zapytanie.Requests[0].Count);
 serwis.SearchAsync(zapytanie);
}

Offset, który przy rozpoczęciu wyszukiwania był ustawiany na 0 (pobieranie pierwszej strony), w tym momencie musimy określić tak, aby pobierane były wyniki z odpowiednich kart. Poprawność wzoru łatwo sprawdzić, podstawiając przykładowe dane. Dla strony = 2, ilości = 15, wartość offsetu wyniesie (2-1)*15 = 15, i faktycznie tak jest – wyniki od numeru 0 do 14 znajdują się na pierwszej karcie, w związku z czym pierwszy wynik na drugiej karcie będzie miał numer 15.

Pozostałe (dużo mniej skomplikowane metody) znajdują się w dołączonym kodzie aplikacji. W niniejszym artykule nie zostały poruszone niektóre drobne niuanse, inne znajdują się dopiero w stadium rozwoju (proszę pamiętać, iż usługa ta dostępna jest w wersji beta!). W artykule nie opisałem szczegółowo takich klas jak Result, czy SourceResponse, gdyż są to klasy o prostej budowie, a dokumentacja dość dokładnie opisuje wszystkie klasy należące do usługi. Obecnie licencja określa pewne ograniczenia (zastosowania – niekomercyjne; wyszukiwarka zwraca maksymalnie 250 wyników). Ograniczenie liczby wyników nie zostało uwzględnione w programie, ponieważ liczba ta może ulec zmianie w przyszłości; w przypadku próby pobrania wyników wykraczających poza określony limit program nie wyświetli żadnych pozycji na liście.

 

 

Artykuł został opublikowany w SDJ nr 9/2006.

Załączniki:

Podobne artykuły

Komentarze 0

pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.