Pull to refresh

Свой консольный велосипед для проверки битых ссылок — LinkInspector

Reading time 4 min
Views 4.2K
image
Мне понадобилось для своих сайтов запускать еженедельную проверку битых и несуществующих ссылок. Потратив пол часа на интернет-серфинг, я нашел несколько достойных консольных приложений (так как сервера у меня на Windows, то хотел использовать для этой задачи TaskSheduler). Все они оказались платные. А так как я мог выделить себе немного свободного времени, и задача на первый взгляд показалась не сложной, решил написать свое.

Отталкиваться решил вот от этой реализации: WebSpider, но, как оно обычно бывает в конечном итоге, почти все переписал, как мне нравится.

Составил себе небольшой список, того, что мне требуется и понемногу вычеркиваю из него таски:
Задача Описание Статус
Рекурсивно собрать все ссылки Пробежаться по всем страницам в рамках одного сайта и собрать все ссылки Сделано
Проверить N ссылок В основном для отладочных целей, остановиться после проверки N ссылок Сделано
Сохранить результат в файл Сохранение в TXT Сделано
Сохранить результат используя html template Для удобства чтения + прикрутить плагин jquery data table для фильтрации и сортировки Сделано
Показывать только ошибки В файл репорте показывать только битые ссылки Сделано
Опция архивирования файла репорта Добавить поддержку 7zip Не сделано
Посылать результат по почте Добавить поддержку консольного мейлера Не сделано
Показывать в репорте редиректы Правильно обрабатывать все редиректы и выводить информацию о них в репорте Не сделано
Добавить логирование Добавить библиотек Log4Net Не сделано
Общая информация о процессе в html темплейте Показывать когда начался процесс обработки, когда закончился, и другую общую информацию в html темплейте Не сделано
Проверить и настроить правильную обработку редиректов Не сделано
app.config конфигурация по умолчанию Так как стало слишком много параметров для утилиты, решил, что надо сделать конфигурацию по умолчанию из app.config Не сделано


Программа простая до безобразия:
1. На вход подается URI, для которого скачивается контент и в контенте ищутся ссылки при помощи регулярного выражения:
public const string UrlExtractor = @"(?: href\s*=)(?:[\s""']*)(?!#|mailto|location.|javascript|.*css|.*this\.)(?<url>.*?)(?:[\s>""'])";

2. Все найденные ссылки, если они относятся к данному сайту, помещаются в хештейбл, где ключ — это абсолютное URI, чтобы не было дублирования.
3. Для каждой ссылки из таблицы хешей мы создаем Request и пытаемся получить Response, и читаем возвращаемый статус:

 public bool Process(WebPageState state)
        {
state.ProcessSuccessfull = false;

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(state.Uri);
            request.Method = "GET";
            WebResponse response = null;

            try
            {
                response = request.GetResponse();

                if (response is HttpWebResponse)
                    state.StatusCode = ((HttpWebResponse) response).StatusCode;
                else if (response is FileWebResponse)
                    state.StatusCode = HttpStatusCode.OK;

                 if (state.StatusCode.Equals(HttpStatusCode.OK))
                {
                    var sr = new StreamReader(response.GetResponseStream());
                    state.Content = sr.ReadToEnd();
                    
                    if (ContentHandler != null)
                        ContentHandler(state);

state.ProcessSuccessfull = true;
                }
            }
            catch (Exception ex)
            {
//               обработка ошибок  todo: сделать отдельные catch блоки
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
            return state.ProcessSuccessfull;
        }


Все остальное это красивости и энтропия.

Из интересного: использовал для удобного парсинга консольных параметров вот этот пакет https://nuget.org/packages/ManyConsole.

В итоге для обработки параметра, все что от меня требуется это создать вот такой вот класс:


public class GetTime : ConsoleCommand
    {
        public GetTime()
        {
            Command = "get-text";
            OneLineDescription = "Returns the current system time.";
        }

        public override int Run()
        {
            Console.WriteLine(DateTime.UtcNow);

            return 0;
        }
    }


P.S. И В заключении, так как проект пишу для себя и все еще в процессе, то добавил его на github https://github.com/alexsuslin/LinkInspector

Ах, да… кому все-таки интерсно визуально посмотреть что получается в итоге, вот это в консоле:
D:\WORK\Projects\Own\LinkInspector\LinkInspector\bin\Debug>LinkInspector.exe -u www.google.com -n=10 -ff=html -e

Executing -u (Specify the Url to inspect for broken links.):

======================================================================================================
Proccess URI: www.google.com
Start At : 2011-12-21 04:56:09
------------------------------------------------------------------------------------------------------

0/1 : [ 2.98s] [200] : www.google.com
1/7 : [ 0.47s] [200] : accounts.google.com/ServiceLogin?hl=be&continue=http://www.google.by/
2/6 : [ 0.22s] [200] : www.google.com/preferences?hl=be
3/5 : [ 0.27s] [200] : www.google.com/advanced_search?hl=be
4/7 : [ 0.55s] [200] : www.google.com/language_tools?hl=be
5/341 : [ 0.21s] [200] : www.google.by/setprefs?sig=0_OmYw86q6Bd9tjRx1su-C4ZbrJUU=&hl=ru
6/340 : [ 0.09s] [200] : www.google.com/intl/be/about.html
7/361 : [ 0.30s] [200] : www.google.com/ncr
8/361 : [ 0.21s] [200] : accounts.google.com/ServiceLogin?hl=be&continue=http://www.google.com/advanced_search?hl=be
9/360 : [ 0.13s] [200] : www.google.com/webhp?hl=be
------------------------------------------------------------------------------------------------------
Pages Processed: 10
Pages Pending : 0
End At : 2011-12-21 04:56:14
Elasped Time : 0h 0m 5s 456ms
======================================================================================================


или вот это вот скриншот репорта в html темплейте
image

P.P.S. Попросили скомпилированные бинарники, вот пожалуйста: скачать Link Inspector 0.1 alpha
Tags:
Hubs:
+11
Comments 14
Comments Comments 14

Articles