Tomasz+Dzieniak


 * Informacje podstawowe:**

Autor: Tomasz Dzieniak Tytuł pracy inżynierskiej: Automatyczna naprawa martwych linków HTML Opiekun projektu: prof. Włodzisław Duch Adres repozytorium: [|bitbucket.org]

Projektowi postanowiłem nadać nazwę D-Link Doctor. Nazwa - w stosunku do poprzedniej (Linkurrection) jest bardziej wymowna. Ostatecznie postanowiłem zmienić nazwę aplikacji. Słowotwórstwo może być oznaką nieprofesjonalizmu.

Dodałem repozytorium. Jest to repozytorium prywatne, hostowane na bibucket.org. Dlaczego postanowiłem wybrać właśnie tego dostawcę usług?
 * kwestia przyzwyczajenia
 * jestem zaznajomiony z ich systemem prowadzenia zadań
 * jest to firma, która świadczy usługi dobrej jakości (repozytorium nie zniknie, będzie dostępne)

Osobom zainteresowanym postępem prac (opisanym na stronie projektu) mogę zaoferować dostęp (proszę w tym celu napisać do mnie e-mail).

Ostatecznie postanowiłem zmienić język programowania z Javy na C#. Pozwoli mi to skupić się na zadaniu rozwiązania postawionego przede mną problemu. Język Java - owszem, oferuje bardzo dużo możliwości i jest przenośny. W przypadku języka C# ograniczę się tylko do systemu Windows, jednak w zamian otrzymam bogatsze środowisko programistyczne - Visual Studio 2010 Ultimate, oferujące szereg gotowych kontrolek i klas. Tym samym, w szybszym tempie zbuduję otoczkę wizualną i będę mógł skupić się na programowaniu kontrolera i modelu aplikacji. Niedużym (chociaż zależy jak na to spojrzeć...) kosztem uzyskuję szereg usprawnień.

W celu uproszczenia komunikacji programu Visual Studio 2010 Ultimate z repozytorium na serwerze używam aplikacji Git for Windows (aktualnie w wersji 1.7.8, istnieje aktualizacja).


 * Informacje nt.: przebiegu pracy:**


 * dziennik pracy - znajduje się na stronie projektu, do którego link można znaleźć powyżej
 * lista użytych aplikacji - zostanie stworzona w późniejszym czasie


 * Spis treści:**


 * 1) Wprowadzenie
 * 2) Cele pracy
 * 3) Struktura pracy
 * 4) Protokół komunikacyjny
 * 5) Opis działania protokołu
 * 6) Rodzaje protokołów
 * 7) Wnioski
 * 8) Protokół HTTP
 * 9) Komunikacja urządzeń w sieci
 * 10) Studium przypadku - komunikacja klient/serwer
 * 11) Kody odpowiedzi
 * 12) Odnośnik
 * 13) Definicja łącza
 * 14) Budowa odsyłaczy
 * 15) Sposoby zastosowania
 * 16) Rodzaje odnośników
 * 17) Analiza składniowa
 * 18) Opis i obszary zastosowania
 * 19) Działanie analizatora składni
 * 20) Przykłady algorytmów parsujących
 * 21) Podręcznik aplikacji D-Link Doctor
 * 22) Informacje podstawowe
 * 23) Użytkowanie aplikacji
 * 24) Implementacja biblioteki HtmlLinkDoctor
 * 25) Przegląd i opis
 * 26) Struktury danych
 * 27) Przedstawienie istotniejszych algorytmów
 * 28) Uwagi końcowe
 * 29) Podsumowanie wniosków
 * 30) Zrealizowane cele
 * 31) Propozycje rozwojowe
 * 32) Literatura

Mapa myśli z bardziej szczegółowym opisem: Powyższą grafikę można pobrać w większej rozdzielczości - [|tutaj]. Warto mieć na uwadze, iż jest to tylko materiał pomocniczy, a nie sztywne ramy całości pracy.


 * Proseminarium inżynierskie**

W tej sekcji zamieszczone są prezentacje mojego autorstwa przygotowane na Proseminarium Inżynierskie. Prezentacje można znaleźć pod adresami:
 * [|28 marca 2012]
 * [|16 maja 2012]
 * [|24 października 2012]
 * [|5 grudnia 2012]

Pierwsza prezentacja traktuje w ogólności o problemach związanych z naprawą martwych linków HTML, takich jak problem związany z określeniem powodu śmierci linku, problem ze świadomością programistów, ignorujących w czasie tworzenia kodu stron kluczowe znaczniki opisujące metadane. W prezentacji zaproponowanych jest kilka sposobów na poradzenie sobie z podstawowymi problemami - możliwość podmiany linku, dodanie przekierowania czy najzwyklejsze zastąpienie linku informacją o jego niepoprawności. W czasie prezentacji zaprezentowane zostały podstawowe narzędzia do tworzenia statystyki stron pod względem poprawności adresów HTML.

Druga prezentacja porusza problem wzorców projektowych. Dla mniej wprawnych programistów tematyka wydaje się mało zbieżna z głównym tematem projektu. Ostatecznie jednak - zarówno tworzenie jak i pielęgnacja kodu aplikacji tworzonej zgodnie z podstawowymi zasadami inżynierii oprogramowania - a co za tym idzie również wzorców projektowych - jest dużo prostsza, tańsza i bardziej elegancka. Dla dociekliwych - więcej o wzorcach projektowych na stronach: [[|klik]] i [[|klik]] oraz punkt 1. sekcji "Materiały".

Trzecia prezentacja przypomina zagadnienia, które stanowią clue problemu. Przypominam w niej część informacji, przedstawionych wstępnie w prezentacji pierwszej. Opisuję zmiany, jakie pojawiły się w stosunku do stanu pracy w czasie poprzednich prezentacji. Opisuję przyczyny zmiany języka na C#, obrazuję użycie wyrażeń regularnych i sugeruję kilka dodatkowych pomysłów rozwojowych.

Czwarta prezentacja to kolejny przewrót w procesie realizacji projektu. Tłumaczę podczas niej powód porzucenia stosowania wyrażeń regularnych, poruszam kwestię użytej biblioteki "Html Agility Pack" (o której była mowa podczas pierwszej prezentacji), omawiam wstępnie korzyści technologii LINQ odnoszącej się pośrednio do problemu naprawy martwych linków. Obrazuję sposób optymalizacji działania programu i związane z nim - napotkane - problemy.


 * Przedstawienie głównej idei projektu - co i dlaczego**

Realizując jakikolwiek projekt warto na samym początku zastanowić się nad głównymi celami postawionego problemu. Do tego zadania można podejść dwojako - od razu spróbować przedstawić gruntowne idee całości projektu, bądź metodą drobnych kroków - podzielić pracę na drobne etapy i w czasie ich realizacji wyznaczać kolejne kamienie milowe.

Zasadniczym celem, który należy osiągnąć jest opracowanie techniki maksymalnie zmniejszającej ilość występowań nietrafnych linków HTML. Po drodze jednak, należy poradzić sobie z kilkoma mniejszymi problemami:
 * należy stworzyć parser, który z określonej puli plików zgromadzi listę linków (na wstępie zarówno "żywych", jak i martwych - być może w celu badań statystycznych)
 * należy określić metodę sprawdzania żywotności linków (powód "śmierci" linku, czy nie jest to przypadkiem sytuacja tymczasowa)
 * należy zastanowić się nad technikami naprawy linków (inteligentne przeszukiwanie sieci w celu odnalezienia stron tematycznie powiązanych bądź przeniesionych), czy też metodami zapobiegającymi sytuacji, w których linki umierają (ostatecznie można określić szablon(y) i schemat(y) raportowania sytuacji, w których linki nie wiodą do celu)

Na pierwszy rzut oka, realizacja tychże punktów wydaje się nie przysparzać szczególnych problemów. Wnikając w temat głębiej, można dostrzec kilka kluczowych problemów, które stają na drodze w wyszukiwaniu trafnych adresów docelowych:
 * problemy z rzetelnym opisywaniem metadanych stron
 * problemy z komercyjnym pozycjonowaniem stron w wyszukiwarkach internetowych
 * problemy z niedbałością programistów (zaniedbywanie wypełniania metadanych, "brudny" i brzydki kod)

Jednym z kamieni milowych w realizacji projektu może okazać się znalezienie złotego środka zaradczego, umniejszającego wpływ powyższych problemów.


 * Badanie gruntu**

Dobrym punktem, w którym warto rozpocząć pracę nad projektem jest zapoznanie się z istniejącymi na rynku aplikacji do sprawdzania poprawności linków. Zgodnie z sugestiami Promotora (zawartymi w sekcji: "Sugestie i propozycje Promotora") na pierwszy ogień idą aplikacje: Xenu i AM-DeadLink. Opis i spostrzeżenia, które pojawiają się w czasie użytkowania aplikacji zostały zamieszczone poniżej.

Linki do stron domowych aplikacji:
 * [|Xenu's Link Sleuth]
 * [|AM-DeadLink]

Na początek Xenu. Interfejs użytkownika wydaje się stosunkowo prosty. Na wstępie poza oknem ze wskazówkami (zasadniczo z nich nigdy nie korzystam...) do dyspozycji pozostaje klasyczne okno systemu Windows z grupą przycisków użytkowych (plik, edycja, pomoc...). Intuicyjny interfejs jest zdecydowanie zaletą programu.

Przystępując do pracy - do dyspozycji użytkownikowi oddane zostają takie opcje jak: możliwość skanowania stron internetowych (pod adresem URL i z pliku), otwieranie gotowych plików pracy programu (w specjalnym formacie) oraz możliwość sprawdzania listy adresów URL (kumulowanych w pliku *.txt).

Efektem pracy pierwszej z opcji (skanowania pojedynczej strony - wybrałem adres: http://www.is.umk.pl/~duch/books-fsk/adr-fsk01.html) jest tabela podstawowych informacji. Poza adresem docelowym elementu badanego można sprawdzić jego status (a więc czy jest dostępny, czy nie znaleziony, nie możliwe było połączenie z serwerem itd), jego typ, rozmiar, tytuł, data utworzenia, rodzaj serwera na którym jest przechowywany, komentarz błędu i inne, mniej czy bardziej użyteczne informacje.

Po wykonaniu pełnego skanowania aplikacja proponuje zapisać raport swojego działania do pliku. Jest to opcja jak najbardziej użyteczna. Pozwala w jakimś stopniu prowadzić statystykę działania serwerów, na których znajdują się pliki docelowe i tym samym zgromadzić dane archiwalne dotyczące badanych plików (co może okazać się w późniejszym czasie użyteczne w celu naprawy martwych linków).

Efektem użytkowania tego programu był nie tylko wzrost informacji, na które należy zwrócić uwagę w czasie badania linków (a więc stan serwerów, numer raportowanego błędu) ale też czysto stylistyczny - zarysował się w mojej wyobraźni ogólny pogląd interfejsu aplikacji, którą mam zamiar napisać. Jeżeli nie odejdę od tego - ogólnego - zarysu, spróbuję powielić ideę tworzenia tabeli informacji o linkach (uzupełnioną o kilka użytecznych opcji, jak na przykład ukrywanie linków działających poprawnie czy możliwość powtórnego sprawdzenia pojedynczego adresu).

AM-DeadLink wita użytkownika oknem wyboru lokalizacji językowej - zdecydowana zaleta dla osób, których znajomości językowe są ograniczone, albowiem wybór dostępnych języków jest imponujący.

Tuż po dokonaniu wyboru odpowiedniego sobie języka oczom ukazuje się nieco bardziej wzbogacony ikonami interfejs użytkownika i... pierwsze efekty działania programu. Aplikacja natychmiast po uruchomieniu wykrywa zakładki dostępnych w systemie przeglądarek internetowych i listuje je w eleganckiej tabelce.

Z zasady jest to program, którego założenia nieznacznie się różnią. Nacisk kładziony jest na sprawdzenie poprawności zakładek używanych przez użytkowników systemu, co jednak nie oznacza, iż odstaje od poprzednio wspomnianego Xenu. AM-DeadLink również został wyposażony w możliwość skanowania plików HTML, adresów URL, list linków. W stosunku do poprzedniego programu ustępuje mnogością informacji dołączanych do znalezionych linków, co jednak nie umniejsza mu sytuacji, w których można się nim posługiwać (zwłaszcza przez użytkowników indywidualnych).

Idea działania aplikacji jest zbliżona i wytycza niejako pierwszy kamień milowy, jaki należy osiągnąć. W celu umożliwienia naprawy linków najpierw należy je znaleźć, zdiagnozować i dopiero później poczynić odpowiednie kroki.


 * Podstawa diagnostyki**

Jednym z kryteriów, jakim należy się kierować w diagnostyce poprawności adresów URL i linków HTML jest kod odpowiedzi HTTP (więcej o protokole HTTP - [[|klik]] i w punkt 2. sekcji "Materiały".

Kodem odpowiedzi nazywa się informację zwrotną, jaką serwer przesyła do aplikacji klienckiej poprzez protokół HTTP. Informuje o sposobie realizacji (lub nie) zapytania wysłanego przez aplikację klienta. Szczególnie interesującymi numerami kodów błędów, które można wykorzystać w diagnostyce adresów są kody błędów (aplikacji klienta: 400-418 i serwera: 500-505), niemniej użyteczne jednak są wszystkie pozostałe kody odpowiedzi (informujące np. o przekierowaniach). Ich szczegółowy opis zamieszczony został w tabeli poniżej:


 * Kody informacyjne:**
 * ~ kod ||~ opis słowny ||~ znaczenie/zwrócony zasób ||
 * 100 || Continue || Kontynuuj – prośba o dalsze wysyłanie zapytania ||
 * 101 || Switching Protocols || Zmiana protokołu ||
 * 110 || Connection Timed Out || Przekroczono czas połączenia. Serwer zbyt długo nie odpowiada. ||
 * 111 || Connection refused || Serwer odrzucił połączenie ||


 * Kody powodzenia:**
 * ~ kod ||~ opis słowny ||~ znaczenie/zwrócony zasób ||
 * 200 || OK || Zawartość żądanego dokumentu (najczęściej zwracany nagłówek odpowiedzi w komunikacji WWW Internetu) ||
 * 201 || Created || Utworzono – wysłany dokument został zapisany na serwerze ||
 * 202 || Accepted || Przyjęto – zapytanie zostało przyjęte do obsłużenia, lecz jego zrealizowanie jeszcze się nie skończyło ||
 * 203 || Non-Authoritative Information || Informacja nieautorytatywna – zwrócona informacja nie odpowiada dokładnie odpowiedzi pierwotnego serwera, lecz została utworzona z lokalnych bądź zewnętrznych kopii ||
 * 204 || No content || Brak zawartości – serwer zrealizował zapytanie klienta i nie potrzebuje zwracać żadnej treści ||
 * 205 || Reset Content || Przywróć zawartość – serwer zrealizował zapytanie i klient powinien przywrócić pierwotny wygląd dokumentu ||
 * 206 || Partial Content || Część zawartości – serwer zrealizował tylko część zapytania typu GET, odpowiedź musi zawierać nagłówek Range informujący o zakresie bajtowym zwróconego elementu ||


 * Kody przekierowania:**
 * ~ kod ||~ opis słowny ||~ znaczenie/zwrócony zasób ||
 * 300 || Multiple Choices || Wiele możliwości – istnieje więcej niż jeden sposób obsłużenia danego zapytania, serwer może podać adres zasobu, który pozwala na wybór jednoznacznego zapytania spośród możliwych ||
 * 301 || Moved Permanently || Trwale przeniesiony – żądany zasób zmienił swój URI i w przyszłości zasób powinien być szukany pod wskazanym nowym adresem ||
 * 302 || Found || Znaleziono – żądany zasób jest chwilowo dostępny pod innym adresem a przyszłe odwołania do zasobu powinny być kierowane pod adres pierwotny ||
 * 303 || See Other || Zobacz inne – odpowiedź na żądanie znajduje się pod innym URI i tam klient powinien się skierować. To jest właściwy sposób przekierowywania w odpowiedzi na żądanie metodą POST. ||
 * 304 || Not Modified || Nie zmieniono – zawartość zasobu nie podległa zmianie według warunku przekazanego przez klienta (np. data ostatniej wersji zasobu pobranej przez klienta – pamięć podręczna przeglądarki) ||
 * 305 || Use Proxy || Użyj serwera proxy – do żądanego zasobu trzeba odwołać się przez serwer proxy podany w nagłówku Location odpowiedzi ||
 * 306 ||  || Kod nieużywany, aczkolwiek zastrzeżony dla starszych wersji protokołu ||
 * 307 || Temporary Redirect || Tymczasowe przekierowanie – żądany zasób znajduje się chwilowo pod innym adresem URI, odpowiedź powinna zawierać zmieniony adres zasobu, na który klient zobowiązany jest się przenieść ||
 * 310 || Too many redirects || Zbyt wiele przekierowań. ||


 * Kody błędu aplikacji klienta:**
 * ~ kod ||~ opis słowny ||~ znaczenie/zwrócony zasób ||
 * 400 || Bad Request || Nieprawidłowe zapytanie – żądanie nie może być obsłużone przez serwer z powodu błędnej składni zapytania ||
 * 401 || Unauthorized || Nieautoryzowany dostęp – żądanie zasobu, który wymaga uwierzytelnienia ||
 * 402 || Payment Required || Wymagana opłata – odpowiedź zarezerwowana na przyszłość ||
 * 403 || Forbidden || Zabroniony – serwer zrozumiał zapytanie lecz konfiguracja bezpieczeństwa zabrania mu zwrócić żądany zasób ||
 * 404 || Not Found || Nie znaleziono – serwer nie odnalazł zasobu według podanego URL ani niczego co by wskazywało na istnienie takiego zasobu w przeszłości ||
 * 405 || Method Not Allowed || Niedozwolona metoda – metoda zawarta w żądaniu nie jest dozwolona dla wskazanego zasobu, odpowiedź zawiera też listę dozwolonych metod ||
 * 406 || Not Acceptable || Niedozwolone – zażądany zasób nie jest w stanie zwrócić odpowiedzi mogącej być obsłużonej przez klienta według informacji podanych w zapytaniu ||
 * 407 || Proxy Authentication Required || Wymagane uwierzytelnienie do serwera pośredniczącego //(ang. proxy)// – analogicznie do kodu 401, dotyczy dostępu do serwera proxy ||
 * 408 || Request Timeout || Koniec czasu oczekiwania na żądanie – klient nie przesłał zapytania do serwera w określonym czasie ||
 * 409 || Conflict || Konflikt – żądanie nie może być zrealizowane, ponieważ występuje konflikt z obecnym statusem zasobu, ten kod odpowiedzi jest zwracany tylko w przypadku podejrzewania przez serwer, że klient może nie znaleźć przyczyny błędu i przesłać prawidłowego zapytania ||
 * 410 || Gone || Zniknął (usunięto) – zażądany zasób nie jest dłużej dostępny i nie znany jest jego ewentualny nowy adres URI; klient powinien już więcej nie odwoływać się do tego zasobu ||
 * 411 || Length required || Wymagana długość – serwer odmawia zrealizowania zapytania ze względu na brak nagłówka Content-Length w zapytaniu; klient może powtórzyć zapytanie dodając doń poprawny nagłówek długości ||
 * 412 || Precondition Failed || Warunek wstępny nie może być spełniony – serwer nie może spełnić przynajmniej jednego z warunków zawartych w zapytaniu ||
 * 413 || Request Entity Too Large || Encja zapytania zbyt długa – całkowita długość zapytania jest zbyt długa dla serwera ||
 * 414 || Request-URI Too Long || Adres URI zapytania zbyt długi – długość zażądanego URI jest większa niż maksymalna oczekiwana przez serwer ||
 * 415 || Unsupported Media Type || Nieznany sposób żądania – serwer odmawia przyjęcia zapytania, ponieważ jego składnia jest niezrozumiała dla serwera ||
 * 416 || Requested Range Not Satisfiable || Zakres bajtowy podany w zapytaniu nie do obsłużenia – klient podał w zapytaniu zakres, który nie może być zastosowany do wskazanego zasobu ||
 * 417 || Expectation Failed || Oczekiwana wartość nie do zwrócenia – oczekiwanie podane w nagłówku Expect żądania nie może być spełnione przez serwer lub – jeśli zapytanie realizuje serwer proxy – serwer ma dowód, że oczekiwanie nie będzie spełnione przez następny w łańcuchu serwer realizujący zapytanie ||
 * 418 || I'm a teapot || "Jestem czajnikiem" - tzw. easter egg. Zdefiniowany w 1998. Obecnie nie jest implementowany do serwerów HTTP, ale znane są takie przypadki. ||


 * Kody błędu wewnętrznego:**
 * ~ kod ||~ opis słowny ||~ znaczenie/zwrócony zasób ||
 * 500 || Internal Server Error || Wewnętrzny błąd serwera – serwer napotkał niespodziewane trudności, które uniemożliwiły zrealizowanie żądania ||
 * 501 || Not Implemented || Nie zaimplementowano – serwer nie dysponuje funkcjonalnością wymaganą w zapytaniu; ten kod jest zwracany, gdy serwer otrzymał nieznany typ zapytania ||
 * 502 || Bad Gateway || Błąd bramy – serwer – spełniający rolę bramy lub pośrednika – otrzymał niepoprawną odpowiedź od serwera nadrzędnego i nie jest w stanie zrealizować żądania klienta ||
 * 503 || Service Unavailable || Usługa niedostępna – serwer nie jest w stanie w danej chwili zrealizować zapytania klienta ze względu na przeciążenie ||
 * 504 || Gateway Timeout || Przekroczony czas bramy – serwer – spełniający rolę bramy lub pośrednika – nie otrzymał w ustalonym czasie odpowiedzi od wskazanego serwera HTTP, FTP, LDAP, itp. lub serwer DNS jest potrzebny do obsłużenia zapytania ||
 * 505 || HTTP Version Not Supported || Wersja HTTP nie obsługiwana – serwer nie obsługuje bądź odmawia obsługi wskazanej przez klienta wersji HTTP ||

Źródłem wszystkich powyższych tabel jest strona Wikipedii - [[|klik]]. W późniejszym czasie być może wytnę fragment powyższy i pozostawię wyłącznie odniesienie do odpowiedniej strony.


 * Parser stron:**

Zmiana języka programowania na C# udostępniła mi szereg użytecznych klas. Jedną z nich jest klasa Regex, pozwalająca na tworzenie i używanie wyrażeń regularnych. Podstawą aplikacji jest algorytm, który spośród stron HTML niejako "wyłuska" adresy stron internetowych czy elementów takich stron określonych adresami URL, które ostatecznie należy zbadać i w razie potrzeby wyleczyć.

W chwili obecnej zastanawiam się nad dwoma wyrażeniami regularnymi, które ze stu-procentową skutecznością parsują mi pliki stron HTML i pozyskują z niej ciągi tekstów zawierających adresy URL.

Pierwsze wyrażenie regularne: ]*?href[\\s]?=[\\s\\\"\']+(? .*?)[\\\"\\']+.*?>(?[^<]+|.*?)?

Drugie wyrażenie regularne, zdecydowanie prostsze, ale pociągające ze sobą kilka efektów ubocznych: @""

Problemy związane z użytkowaniem powyższych wyrażeń regularnych opiszę wkrótce. Nie zmienia jednak to faktu, że są one wciąż przedmiotem moich badań. Znacząco ułatwiają mi pracę nad parsowaniem strony, gdyż niejako "za darmo" wraz z kompletnym adresem, kilkoma elementami meta-tagowymi specyfiki kodu HTML otrzymuję jeszcze wnętrze tagu, które w przyszłości będzie stanowić przedmiot badań (na ich podstawie możliwe będzie wyszukiwanie docelowej strony).

Efektem pracy polegającej na tworzeniu elementów parsujących jest program, który ze strony HTML "wyciąga" niejako informacje potrzebne do dalszej pracy. Przykładowe okno - w chwilę po zakończeniu przeszukiwania pliku - można zobaczyć poniżej.

Kolejnym etapem jest stworzenie algorytmu sprawdzającego status linków widocznych w kolumnie "Address". W tym celu najprawdopodobniej utworzę pulę wątków i będę sprawdzał kilka adresów URL jednocześnie.


 * Parser stron - wersja zaktualizowana**

Porzuciłem ideę wyżej przedstawionych wyrażeń regularnych. W powyższej sekcji wspomniałem, iż napotykane problemy utrudniają rzetelność łuskania adresów URL. W przypadku zagmatwanych typów adresów (niedotyczących bezpośrednio przekierowań, a raczej źródeł danych) algorytm parsujący - wraz ze wzrostem ilości tego typu linków na stronie - nie odnajdował części adresów (wprost proporcjonalnie do pochodnej ilości liczby linków na stronie).

Z pomocą przychodzi biblioteka Html Agility Pack, do której strony projektu można odnaleźć link poniżej. Jest to biblioteka tworząca obiektowe modele dokumentu (DOM) wspierające technologię LINQ. Mając do dyspozycji taką abstrakcję nad danymi przeszukiwanie plików staje się zdecydowanie prostsze, skuteczniejsze i szybsze.

Porównując efekt działania parsera opartego o bibliotekę Html Agility Pack z poprzednim parserem opartym o wyrażenia regularne notuję zdecydowany przyrost skuteczności algorytmu, wraz ze wzrostem ilości adresów URL na stronie.

Zaktualizowana wersja programu z implementacją nowej biblioteki parsującej przedstawiona jest na zdjęciu poniżej. Kolumna "Status" nie zawiera jeszcze informacji o kodzie statusu. Jest automatycznie wypełniana zerami. Implementacja kodu wstawiającego konkretną wartość jest trywialna, w przeciwieństwie do uzupełnienia kodu o pozyskiwanie informacji kodu statusu spoza puli poprawnych adresów - nad czym teraz pracuję.

Wszelkie testy pojedynczych linków przebiegają już pomyślnie. Zbierana jest kompletna informacja oferowana przez protokół HTTP i tegoż nagłówek.


 * Wielowątkowość**

Pierwszym etapem optymalizacji działania aplikacji jest przyspieszenie procesu łuskania linków (poprzez zmianę podejścia do algorytmu parsującego na oparty o bibliotekę Html Agility Pack). Niejako swoistą alegorią staje się tutaj konieczność optymalizacji również algorytmu sprawdzającego status adresu URL. Polega on na utworzeniu puli wątków i ograniczeniu sposobu odpytywania adresu do pobierania wyłącznie jego nagłówka (w przeciwieństwie do całości w poprzedniej wersji).

Pula wątków oddaje do dyspozycji użytkownikowi (pośrednio przez warstwę aplikacji) dynamicznie zmienianą liczbę wątków - zależną od preferencji i potrzeb. Wątki z puli pobierają kolejno zadania sprawdzenia dostępności adresu URL i po zakończeniu pracy powracają do kolejki wątków.

Zadania w międzyczasie "przychodzą" do puli po dostępy wątek i uruchamiają się na nim.

Cały mechanizm oparty jest o wzorzec Producenta i Konsumenta.

Testowanie listy odnośników odbywa się równolegle. W zależności od konfiguracji zaproponowanej przez użytkownika, aplikacja ma do użytku od jednego do dziesięciu wątków.


 * Sprawdzanie kodu statusu adresu URL:**

Kolejnym prezentem języka C# jest klasa //WebRequest// i //HtmlWebRequest//. Opis klas można łatwo znaleźć w dokumentacji online na stronie Microsoftu (link w materiałach na dole strony). Pozwala ona w prosty sposób, poprzez przekazanie do jednej z metod statycznych klasy adresu URL w postaci ciągu znaków pozyskać informacje z ramki protokołu HTTP. Jedną z tychże informacji jest poszukiwany kod statusu. Jak się okazuje, wybór języka C# okazuje się niemal zbawienny.

Warto również dodać, iż jednym z elementów architektury przestrzeni nazw zawierającej wyżej wspomniane klasy jest również wyliczenie kodów statusów wraz z ich opisem. Ułatwi to konstruowanie przejrzystej tabelki z informacjami dotyczącymi dostępności badanych elementów i stron.

Tabelka skonstruowana za pomocą kontrolki GridView, która została zbindowana do struktury danych przechowującej przedmiot badań (kolekcję linków). Wszelkie aktualizacje (mimo, że odbywają się w różnych wątkach) przedstawiane są na ekranie w czasie rzeczywistym.


 * Funkcjonalności dodatkowe:**

Program oferuje kilka funkcjonalności dodatkowych. Pierwszą, którą przedstawię jest możliwość sporządzenia listy odnośników (bądź ich fragmentów), które podczas parsowania będą ignorowane.

Przykładowy zrzut ekranu:

GUI aplikacji ulega zmianie bardzo często, stąd różnica w zrzutach ekranu. Ilość zmian wynika z dopasowania do maksymalnej wygody i intuicyjności aplikacji.


 * Komentarze:**


 * logicznie powiązane i uporządkowane informacje spróbuję grupować w rozdziały i umieszczać je do plików PDF - w celu uproszczenia organizacji niniejszej strony
 * w sekcji "Informacje podstawowe" zamieszczone są podstawowe informacje opisujące moją pracę inżynierską
 * w sekcji "Informacje nt.: przebiegu pracy" widnieją informację o przeniesieniu opisu postępu prac na stronę projektu hostowaną na Bitbucketcie.
 * w sekcji "Komentarze" publikowane będą luźne przemyślenia związane z projektem, które najpewniej w jakimś stopniu przyczynią się do rozwoju pracy
 * w sekcji "Sugestie i propozycje Promotora" znajdują się początkowe informacje autorstwa prof. Włodzisława Ducha, będące zalążkiem rozpoczęcia pracy nad projektem


 * Sugestie i propozycje Promotora:**

Są różne programy do sprawdzania poprawności linków, ten wyszukuje duplikaty, również na zakładach Firefox i innych: http://www.aignes.com/deadlink.htm

To zdaje się ambitny projekt, ale tylko monitoruje stronę a nie szuka gdzie się przeniosła: Automatically check web pages for updates and changes: http://www.aignes.com/

Zacznijmy od Xenu Link, ale warto uwzględnić inne programy tego rodzaju, http://home.snafu.de/tilman/xenulink.html Weżmy jako przykład stronę http://www.is.umk.pl/~duch/books-fsk/adr-fsk01.html na której na pewno jest sporo martwych linków.


 * 1) Jakie są problemy, które pokaże nam Xenu? Brak serwera, brak pliku, no response, inne?
 * 2) Jak możemy postąpić w każdym przypadku?
 * 3) Czy wyszukiwanie słów kluczowych ze zdania, które zawiera dany link jest pomocne by odnaleźć pierwotna infromację?

Możemy próbować
 * automatycznie podmienić zły link na dobry (jeśli jest jakaś infromacja typu "address change", trzeba porobić filtry wykrywająca czy taka sytuacja ma miejsce;
 * zamienić link na słowa kluczowe i użyć odwołania do Googla, np. http://www.google.com/search?q=Wlodzislaw+Duch
 * całkowicie usunąć i zmienić kolor by to zaznaczyć.


 * Materiały:**


 * 1) Freeman, Robson, Bates, Sierra - Head First Design Patterns, O'Reilly Media, 2004
 * 2) Tanenbaum, Sieci komputerowe, Helion, 2004


 * Linki:**
 * []
 * []
 * []