Форум программистов, компьютерный форум, киберфорум
Mans7
Войти
Регистрация
Восстановить пароль
Рейтинг: 1.00. Голосов: 1.

[C#] Сравнение производительности веб-парсинга разными способами

Запись от Mans7 размещена 14.07.2012 в 09:43
Обновил(-а) Mans7 15.07.2012 в 03:31 (Обновление информации)

Линк на форуме

В процессе разработки очередной программы, цель которой отпарсить определенный список страниц, обработать и выдать результат, я задумался - а какой метод будет более быстрым, удобным или коротким? Решил сделать тестер и показать результаты эксперимента сюда. В качестве таймера я использовал QueryPerformanceCounter и QueryPerformanceFrequency из библиотеки Kernel32.dll. Вроде как по отзывам достаточно точно определяет затраченное время. Было сделано по 10 независимых тестов на каждый метод парсинга. Все времена указаны в секундах.

Цель эксперимента: вывести временные затраты при парсинге страницы.
Парсируемая страница: "https://www.google.ru/search?&q=Как+производить+замер+времени"
Необходимо: загрузить страницу в память, найти выданные ссылки, вывести на экран ссылки (название, описание и сам линк).

Методы:
1. Загружаем данные в виртуальный webbrowser, парсим через класс HtmlElement.
Плюсы: Приятный вид парсинга и загрузки данных, очень понятный и достаточно удобный и короткий.
Минусы: Необходимо создавать ивент для ожидания загрузки страницы в WebBrowser. Возможно на странице с каким-то мультимедийным контентом будет ещё дольше "висеть". Крайне мало настроек подключения (точнее их нет).

Среднее время на парсинг: 0,019997724;
Среднее время на инициализацию компонента и загрузку содержимого в память: 2,52409373;
Минимальное время на -//-: 2,140337;
Максимальное время на -//-: 3,079691;
Разница: 0,939354.


2. Загружаем данные через класс HTTPWebRequest в строку, парсим ручками.
Плюсы: Очень тонкие настройки соединения, GET/POST запросов, кукисов, всего чего только можно, в т.ч. кодировки.
Минусы: Ужасный вид кода парсинга ручками, очень тяжело работать в кривом коде HTML, большой код для парсинга загруженных данных. Возможно, если использовать RegEx, то вид парсинга будет более оптимальный и не такой большой (не занимался ещё RegEx'ом). Так же необходимо создавать дополнительные методы (функции) для очистки HTML кода от мусора (<em>/<br>/<b>) и подобных для вывода чистого текста. А так же очень ненадёжный вид и тяжело понимаемый.

Среднее время на парсинг: 0,018322276 (чуточку быстрее первого метода);
Среднее время на инициализацию компонента и загрузку содержимого в память: 0,38945552 (топ);
Минимальное время на -//-: 0,3817242;
Максимальное время на -//-: 0,3990794;
Разница: 0,0173552.


3. Загружаем данные через HtmlAgilityPack, парсим через методы HtmlAgilityPack
Плюсы: Весьма удобный и короткий вид загрузки данных, очень короткий код на парсинг, не надо ничего нового придумывать, есть немного настроек соединения.
Минусы: Очень непривычный и местами неудобный (а местами очень даже удобный) синтаксис (если позволите так сказать) парсинга. Чистый адрес ссылки мне так и не удалось вытащить, почему-то куча мусора приплюсовалась, но это лишь неприятная мелочь. Хотя я впервые знакомлюсь с HtmlAgilityPack, может быть он лучше и удобнее чем кажется.

Среднее время на парсинг: 0,006282992 (топ);
Среднее время на инициализацию компонента и загрузку содержимого в память: 0,44985426;
Минимальное время на -//-: 0,384168;
Максимальное время на -//-: 0,6345674;
Разница: 0,2503994.

ВЕРДИКТ: Первый метод хорош только видом парсинга. Ужасно долго по сравнению с другими методами происходит получение данных от сервера. Второй идеален для тонкой настройки подключения или цепочки соединений. Если найти хороший способ парсинга текста (обработки полученного кода), то, я думаю, это будет лучший способ для меня (надо бы RegEx почитать). Третий способ для эстетов - всё довольно аккуратно и чётко. Но лично для меня он: непривычный и неудобный.

Прошу Ваших комментариев!

P.S. Я не рассматривал возможность асинхронной загрузки данных.
P.P.S. К сообщению приложил архив с проектом. Parsing_Test.rar

Добавлено:
Кстати, надо будет попробовать сделать загрузку кода страницы через HTTPWebRequest, а потом загнать код в WebBrowser в надежде, что конкретно этот процесс не займёт времени. Тогда парсить будет очень легко (ну вот не понравился мне HtmlAgilityPack - Хочется обойтись родными библиотеками). Или всё-таки использовать Regex - как я убедился, он очень крут, но тяжело читаем (для меня пока что).

Добавлено:
Делаем Френкенштейна:
1) Соединим 1 и 2 способы. Загружаем данные через HttpWebRequest, стринг с кодом загоняем в webBrowser.DocumentText. Итого: ничего хорошего. Даже при отключении появления ошибок о скриптах, он все равно ругается на всякие xjs скрипты. При этом, парсинг не проходит. Fail.
2) Будем соединять 2 и 3 способы. Загружаем данные через HttpWebRequest, ответ напрямую получает HAP. Как и ожидалось:
- лучшая скорость загрузки страницы;
- почти лучшая скорость парса (RegEx по скорости круче будет);
- очень удобно обращаться с объектами (удобнее чем с текстом).

Замерил время выполнения StopWatch'ем. Получил:
Среднее время соединения - 462,8 мс (миллисекунд)
Среднее время парса - 6,6 мс

Так же заметил разницу между замерами QueryPerformance и StopWatch. Разницу я наблюдал 0-5%.

Добавлено:
А теперь ещё фишка - сделал то чего боялся и не хотел. Парсинг RegEx'ом . Паттерн получился такой:
C#
1
string pattern = "<h3 class=.r.><a *href=\"(.+?)\"[^>]*>(.+?)</a>.*<span *class=.st.>(.+?)</span>";
Код очень короткий, время парса 3 мс (0,00349404). Но, блин, регулярку составить трудно =(

Из вышесказанного можно сказать что парсинг регулярками имеет:
Плюсы:
- очень производительный (быстрый);
- имеет короткий код;
- не нужно загружать сторонние библиотеки.
Минусы:
- почти нечитабельный (нужно глаз набивать);
- индивидуальный под каждую страницу;
- опять-таки местами где надо вывести чистый текст надо чистить код от мусора (<b><br><em>...), но можно Replace сделать;
- в случае изменения кода на странице, скорее всего, регулярку тоже надо будет корректировать.
Размещено в Без категории
Просмотров 2267 Комментарии 4
Всего комментариев 4
Комментарии
  1. Старый комментарий
    Аватар для NickoTin
    Цитата:
    QueryPerformanceCounter и QueryPerformanceFrequency
    В .NET есть обёртка Stopwatch.
    Запись от NickoTin размещена 14.07.2012 в 13:13 NickoTin вне форума
  2. Старый комментарий
    Аватар для Mans7
    Насколько я понял, почитав про эти таймеры - если необходимо просто замерить время для подобных экспериментов и соотнести результаты - то не очень-то важно каким именно таймером пользоваться - суть будет одна и та же (погрешность не берём в счёт). Хотя это лично мое мнение. И, спасибо, я про него совсем забыл.
    Запись от Mans7 размещена 14.07.2012 в 13:30 Mans7 вне форума
  3. Старый комментарий
    Аватар для Alex_pac
    Цитата:
    1. Загружаем данные в виртуальный webbrowser, парсим через класс HtmlElement.
    Delphi + TEmbededWB + jsEmbededWB3

    для любителей регулярок

    INDY + RegExpr Preg 1.1
    Запись от Alex_pac размещена 26.07.2012 в 16:13 Alex_pac вне форума
  4. Старый комментарий
    Аватар для Avazart
    Alex_pac, какие-то ссылки у вас вирусячные.
    Запись от Avazart размещена 26.02.2015 в 22:32 Avazart вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.