Лайфхаки

Маленькие, полезные хитрости

Мастерство в настройке парсера файлов: алгоритмы и подходы

21.09.2024 в 06:44

Мастерство в настройке парсера файлов: алгоритмы и подходы


Данный генератор парсеров является LL(*) , он существует уже более 20 лет, а в 2013 год вышла его 4-я версия. Сейчас его разработка ведется на GitHub. В данный момент он позволяет генерировать парсеры на языках Java, C#, Python2, Python3, JavaScript. На подходе C++, Swift. Надо сказать, сейчас в этом инструменте достаточно просто разрабатывать и отлаживать грамматики. Несмотря на то, что LL грамматики не допускают леворекурсивных правил, в ANTLR, начиная с 4-й версии, появилась возможность записи таких правил (за исключением правил со скрытой или косвенной левой рекурсией). При генерации парсера происходит преобразование таких правил в обычные не леворекурсивные. Это сокращает запись, например, арифметических выражений:

expr : expr '*' expr | expr '+' expr | expr '^' expr | id ;

Кроме того, в 4-й версии значительна улучшена производительность парсинга благодаря использованию алгоритма Adaptive LL(*). Данный алгоритм совмещает преимущества относительно медленных и непредсказуемых алгоритмов GLL и GLR , которые, однако, способны разрешать случаи с неоднозначностью (используются при разборе естественных языков), и стандартных, быстрых LL-алгоритмов рекурсивного спуска, которые, в свою очередь, не способны разрешать все задачи с неоднозначностью. Суть алгоритма заключается в псевдопараллельном запуске LL-парсеров на каждом правиле, их кэшировании и выборе подходящего предсказания (в отличие от GLR, где допустимо несколько альтернатив). Таким образом, алгоритм является динамическим. Несмотря на то, что наихудшая теоретическая сложность алгоритма является O(n4), по факту скорость парсинга для существующих языков программирования является линейной. Также в четвертой версии сильно эволюционировала возможность восстановления процесса парсинга после обнаружения синтаксических ошибок. Подробнее об алгоритмах ANTLR 4 и их отличиях от других алгоритмов парсинга написано в Adaptive LL(*) Parsing: The Power of Dynamic Analysis .

Связанные вопросы и ответы:

Вопрос 1: Что такое алгоритм настройки парсера файлов

Ответ: Алгоритм настройки парсера файлов - это последовательность шагов, которые необходимо выполнить для того, чтобы правильно настроить парсер файлов. Этот алгоритм включает в себя определение формата файла, выбор подходящего парсера, настройку параметров парсера и проверку результатов парсинга.

Вопрос 2: Какие факторы могут повлиять на выбор алгоритма настройки парсера файлов

Ответ: Выбор алгоритма настройки парсера файлов может зависеть от многих факторов, таких как тип файла, который необходимо распарсить, размер файла, требуемая скорость обработки, наличие особенностей в структуре файла и т.д. Также важно учитывать ограничения, связанные с выбранным парсером, такие как требуемый объем памяти, требуемая производительность и т.д.

Вопрос 3: Как выбрать подходящий парсер для файла

Ответ: Выбор подходящего парсера для файла зависит от типа файла и его структуры. Существует множество различных типов парсеров, таких как XML-парсеры, JSON-парсеры, CSV-парсеры и т.д. Для того, чтобы выбрать подходящий парсер, необходимо знать тип файла и его структуру, а также учитывать требования по скорости обработки, объему памяти и т.д.

Вопрос 4: Как настроить параметры парсера

Ответ: Настройка параметров парсера зависит от выбранного парсера и его возможностей. Обычно настройки включают в себя параметры, связанные с разбором файла, такие как тип файла, кодировка, режим обработки ошибок и т.д. Также могут быть настроены параметры, связанные с производительностью, такие как максимальный объем памяти, используемый для хранения данных.

Вопрос 5: Как проверить результаты парсинга

Ответ: Проверка результатов парсинга - это важный шаг, который необходимо выполнить для того, чтобы убедиться, что файл был распарсен правильно. Проверка может быть выполнена вручную или автоматически. Вручную можно проверить, что все данные были распознаны правильно, а также проверить соответствие распознанных данных ожидаемому результату. Автоматическая проверка может быть выполнена с помощью специальных инструментов, которые могут проверить соответствие распознанных данных ожидаемому результату и выявить ошибки в распознавании данных.

Вопрос 6: Как оптимизировать алгоритм настройки парсера файлов

Ответ: Оптимизация алгоритма настройки парсера файлов может быть выполнена путём улучшения производительности и уменьшения объема используемой памяти. Для улучшения производительности можно использовать параллельное выполнение операций, оптимизировать алгоритмы и использовать более быстрые парсеры. Для уменьшения объема используемой памяти можно использовать сжатие данных, оптимизировать алгоритмы и использовать более эффективные структуры данных. Также можно использовать специальные инструменты для оптимизации алгоритмов и структур данных.

Что такое алгоритм настройки парсера файлов

Выше мы привели графики сравнения производительности различных парсеров, но не рассказали о методике измерений. Сравнение парсеров производились на одинаковых файлах. Размер файла изменялся от 1 до 1000 Мб. Сравнение производилось по следующим метрикам:

    Время работы

    Пиковое потребление оперативной памяти

    Скорость парсинга

При помощи псевдокода эксперимент можно представить следующим образом:

for file_size in :     # Генерируем XML-файл     for parser in :         # Запускаем парсер         # Измеряем время работы и потребляемую память         # Записываем результаты

В качестве полезной нагрузки для парсера мы выбрали задачу: посчитать количество узлов и атрибутов в XML-файле. Такая постановка задачи требует прохода по всему файлу и ставит все парсеры в одинаковые условия.

Характеристики тестовой среды

Модель ноутбука: MacBook Air M1 2020 Процессор: Apple M1 OS: 13.4.1 (22F82) RAM: 16 Gb SSD: Apple SSD AP0256Q

В сравнении принимали участие следующие библиотеки:

    xerces-c 3.2.3 (DOM/SAX)

    libxml2 2.9.13 (DOM/SAX)

    pugixml 1.12.1

    expat 2.4.7

    rapidxml 1.13

    vtd-xml 2.12

Исходный код парсинга

Ниже выложен код наших программ на C++.

Какие задачи решает алгоритм настройки парсера файлов


Когда мы сталкиваемся с задачей создания парсера, решение сводится, как правило, к 4 основным вариантам:
  • Решать задачу в лоб, то есть анализировать посимвольно входящий поток и используя правила грамматики, строить АСД или сразу выполнять нужные нам операции над нужными нам компонентами. Из плюсов — этот вариант наиболее прост, если говорить об алгоритмике и наличии математической базы. Минусы — вероятность случайной ошибки близка к максимальной, поскольку у вас нет никаких формальных критериев того, все ли правила грамматики вы учли при построении парсера. Очень трудоёмкий. В общем случае, не слишком легко модифицируемый и не очень гибкий, особенно, если вы не имплементировали построение АСД. Даже при длительной работе парсера вы не можете быть уверены, что он работает абсолютно корректно. Из плюс-минусов. В этом варианте все зависит от прямоты ваших рук. Рассказывать об этом варианте подробно мы не будем.
  • Используем регулярные выражения! Я не буду сейчас шутить на тему количества проблем и регулярных выражений, но в целом, способ хотя и доступный, но не слишком хороший. В случае сложной грамматики работа с регулярками превратится в ад кромешный, особенно если вы попытаетесь оптимизировать правила для увеличения скорости работы. В общем, если вы выбрали этот способ, мне остается только пожелать вам удачи. Регулярные выражения не для парсинга! И пусть меня не уверяют в обратном. Они предназначены для поиска и замены. Попытка использовать их для других вещей неизбежно оборачивается потерями. С ними мы либо существенно замедляем разбор, проходя по строке много раз, либо теряем мозговые клеточки, пытаясь измыслить способ удалить гланды через задний проход. Возможно, ситуацию чуть улучшит попытка скрестить этот способ с предыдущим. Возможно, нет. В общем, плюсы почти аналогичны прошлому варианту. Только еще нужно знание регулярных выражений, причем желательно не только знать как ими пользоваться, но и иметь представление, насколько быстро работает вариант, который вы используете. Из минусов тоже примерно то же, что и в предыдущем варианте, разве что менее трудоёмко.
  • Воспользуемся кучей инструментов для парсинга BNF! Вот этот вариант уже более интересный. Во-первых, нам предлагается вариант типа lex-yacc или flex-bison, во вторых во многих языках можно найти нативные библиотеки для парсинга BNF. Ключевыми словами для поиска можно взять LL, LR, BNF. Смысл в том, что все они в какой-то форме принимают на вход вариацию BNF, а LL, LR, SLR и прочее — это конкретные алгоритмы, по которым работает парсер. Чаще всего конечному пользователю не особенно интересно, какой именно алгоритм использован, хотя они имеют определенные ограничения разбора грамматики (остановимся подробнее ниже) и могут иметь разное время работы (хотя большинство заявляют O(L), где L — длина потока символов). Из плюсов — стабильный инструментарий, внятная форма записи (БНФ), адекватные оценки времени работы и наличие записи БНФ для большинства современных языков (при желании можно найти для sql, python, json, cfg, yaml, html, csv и многих других). Из минусов — не всегда очевидный и удобный интерфейс инструментов, возможно, придется что-то написать на незнакомом вам ЯП, особенности понимания грамматики разными инструментами.
  • Воспользуемся инструментами для парсинга PEG! Это тоже интересный вариант, плюс, здесь несколько побогаче с библиотеками, хотя они, как правило, уже несколько другой эпохи (PEG предложен Брайаном Фордом в 2004, в то время как корни BNF тянутся в 1980-е), то есть заметно моложе и хуже выглажены и проживают в основном на github. Из плюсов — быстро, просто, часто — нативно. Из минусов — сильно зависите от реализации. Пессимистичная оценка для PEG по спецификации вроде бы O(exp(L)) (другое дело, для создания такой грамматики придется сильно постараться). Сильно зависите от наличия/отсутствия библиотеки. Почему-то многие создатели библиотек PEG считают достаточными операции токенизации и поиска/замены, и никакого вам AST и даже привязки функций к элементам грамматики. Но в целом, тема перспективная.

Какие типы файлов можно парсить с помощью алгоритма настройки парсера файлов

Парсер — это программа, с помощью которой можно собирать данные с указанных веб-страниц, анализировать их и объединять их в базы в различных форматах. Такой сервис избавляет пользователя от необходимости выполнения большого объема однотипных действий и экономит значительное количество времени и сил.

А парсингом называется сам процесс сбора данных — вручную или с помощью программы.

Парсинг и краулинг: отличия

Многие путают понятия парсинг и краулинг между собой. Это неудивительно, ведь принцип работы у них схожий – сканирование источников для сбора данных. Различаются только источники и тип данных, которые собирают программы.

При парсинге добывается любая информация – от номеров телефонов до каталогов цен. Программа для парсинга (или человек вручную) сканирует все открытые источники, чтобы собрать как можно больше данных. Задачи для такого инструмента могут быть самые разные, начиная со сбора статистики и заканчивая конкурентным анализом.

При краулинге специальный робот сканирует страницы в Сети, проверяя их на обновления и соответствие поисковым запросам. Поэтому сканирование осуществляется исключительно в поисковых системах, а сам инструмент применяется в основном для SEO-оптимизации сайтов.

Пример парсинга

Заказчик хочет провести анализ ценовой политики. Чтобы определить среднее значение стоимости товара, ему необходимо узнать информацию о стоимости данного товара. Эту задачу можно решить с помощью парсинга. Парсер просканирует сайты конкурентов и соберет необходимые данные о продукте.

Пример краулинга

Чтобы эта статья отображалась в поисковой видимости, краулер сканирует страницу сайта Zvonobot и добавляет ее в базу данных (индекс) поисковой системы.

Как работает алгоритм настройки парсера файлов


Если задачи, стоящие при сборе данных нестандартные, нужно выстроить подходящую архитектуру, работать с множеством потоков, и существующие решения вас не устраивают, нужно писать свой собственный парсер. Для этого нужны ресурсы, программисты, сервера и специальный инструментарий, облегчающий написание и интеграцию парсинг программы, ну и конечно поддержка (потребуется регулярная поддержка, если изменится источник данных, нужно будет поменять код). Рассмотрим какие библиотеки существуют в настоящее время. В этом разделе не будем оценивать достоинства и недостатки решений, т.к. выбор может быть обусловлен характеристиками текущего программного обеспечения и другими особенностями окружения, что для одних будет достоинством для других – недостатком.Библиотеки для парсинга сайтов на Python предоставляют возможность создания быстрых и эффективных программ, с последующей интеграцией по API. Важной особенностью является, что представленные ниже фреймворки имеют открытый исходный код.– наиболее распространенный фреймворк, имеет большое сообщество и подробную документацию, хорошо структурирован.Лицензия: BSD– предназначен для анализа HTML и XML документов, имеет документацию на русском, особенности – быстрый, автоматически распознает кодировки.Лицензия: Creative Commons, Attribution-ShareAlike 2.0 Generic (CC BY-SA 2.0)– мощный и быстрый, поддерживает Javascript, нет встроенной поддержки прокси.Лицензия: Apache License, Version 2.0– особенность – асинхронный, позволяет писать парсеры с большим количеством сетевых потоков, есть документация на русском, работает по API.Лицензия: MIT License– простая и быстрая при анализе больших документов библиотека, позволяет работать с XML и HTML документами, преобразовывает исходную информацию в типы данных Python, хорошо документирована. Совместима с BeautifulSoup, в этом случае последняя использует Lxml как парсер.Лицензия: BSD– инструментарий для автоматизации браузеров, включает ряд библиотек для развертывания, управления браузерами, возможность записывать и воспроизводить действия пользователя. Предоставляет возможность писать сценарии на различных языках, Java, C#, JavaScript, Ruby.Лицензия: Apache License, Version 2.0JavaScript также предлагает готовые фреймворки для создания парсеров с удобными API.— это headless Chrome API для NodeJS программистов, которые хотят детально контролировать свою работу, когда работают над парсингом. Как инструмент с открытым исходным кодом, Puppeteer можно использовать бесплатно. Он активно разрабатывается и поддерживается самой командой Google Chrome. Он имеет хорошо продуманный API и автоматически устанавливает совместимый двоичный файл Chromium в процессе установки, а это означает, что вам не нужно самостоятельно отслеживать версии браузера. Хотя это гораздо больше, чем просто библиотека для парсинга сайтов, она очень часто используется для парсинга данных, для отображения которых требуется JavaScript, она обрабатывает скрипты, таблицы стилей и шрифты, как настоящий браузер. Обратите внимание, что хотя это отличное решение для сайтов, которым для отображения данных требуется javascript, этот инструмент требует значительных ресурсов процессора и памяти.Лицензия: Apache License, Version 2.0– быстрый, анализирует разметку страницы и предлагает функции для обработки полученных данных. Работает с HTML, имеет API устроенное так же, как API jQuery.Лицензия: MIT License– является библиотекой Node.js, позволяет работать с JSON, JSONL, CSV, XML,XLSX или HTML, CSS. Работает с прокси.Лицензия: Apache License, Version 2.0– написан на Node.js, ищет и загружает AJAX, поддерживает селекторы CSS 3.0 и XPath 1.0, логирует URL, заполняет формы.Лицензия: MIT LicenseJava также предлагает различные библиотеки, которые можно применять для парсинга сайтов.– библиотека предлагает легкий headless браузер (без графического интерфейса) для парсинга и автоматизации. Позволяет взаимодействовать с REST API или веб приложениями (JSON, HTML, XHTML, XML). Заполняет формы, скачивает файлы, работает с табличными данными, поддерживает Regex.Лицензия: Apache License (Срок действия программного обеспечения истекает ежемесячно, после чего должна быть загружена самая последняя версия)– библиотека для работы с HTML, предоставляет удобный API для получения URL-адресов, извлечения и обработки данных с использованием методов HTML5 DOM и селекторов CSS. Поддерживает прокси. Не поддерживает XPath.Лицензия: MIT License– не является универсальной средой для модульного тестирования, это браузер без графического интерфейса. Моделирует HTML страницы и предоставляет API, который позволяет вызывать страницы, заполнять формы, кликать ссылки. Поддерживает JavaScript и парсинг на основе XPath.Лицензия: Apache License, Version 2.0– простой парсер, позволяет анализировать HTML документы и обрабатывать с помощью XPath.

Какие преимущества дает использование алгоритма настройки парсера файлов

Как и говорилось выше, парсер – это специальная программа, которая отвечает за получение данных, за их обработку и при необходимости конвертацию. То есть она берёт (получает на входе) одни данные, обрабатывает их (конвертирует и/или очищает) и возвращает в другом формате – в том, с которым вам удобнее работать.

Как и любые программы, парсеры могут быть написаны на разных языках программирования, могут быть платными, бесплатными или распространяться по модели фримиума (с триал-версией), иметь открытый или закрытый код, предназначаться для разных узких задач и т.п. Естественно, парсеры могут работать как stand-alone-софт (то есть устанавливаться на рабочие места клиентов) или использовать модель SaaS (PaaS), то есть работать в облаке по подписке.

В каждом парсере используются свои подходы, алгоритмы и технические решения. Но есть у них и общие черты, так как непосредственно в процессе парсинга сложно придумать что-то нестандартное, особенно, если речь идёт об анализе web-страниц.

Алгоритм работы почти любого web-парсера выглядит примерно так:

  1. Скрипт обращается к конкретному адресу страницы (по заданному URL, к слову, список URL на парсинг может формироваться автоматически, на основе адресов, извлечённых с исходной/стартовой страницы). Чтобы увеличить шансы на одобрение автоматического ответа, парсер может представляться браузером или ботом поисковых машин.
  2. После успешного коннекта скрипт получает HTML-код страницы.
  3. Далее HTML-код разбирается на теги, внутри страницы выделяются нужные участки или блоки. Для целей более качественного анализа HTML-кода многие парсеры могут иметь встроенный браузер.
  4. Выделенные данные копируются в специальную внутреннюю базу (обычно это SQL-формат, но могут использоваться и любые другие).
  5. Из внутренней базы данных информация может быть выгружена в другие форматы: CSV, XML, JSON, YAML и пр.
  6. Собранные данные хранятся на локальном диске или в облачном хранилище (в зависимости от типа программы и возможностей подписки).

Базовые возможности парсинга могут расширяться за счёт плагинов или модулей. Например, могут задействоваться списки прокси серверов. Тогда парсер будет отправлять запросы не от своего имени (не со своего IP-адреса), а с IP-прокси. Таким образом можно существенно увеличить количество потоков и обработать параллельно огромный объём данных за меньшее время.

Некоторые парсеры могут работать с API, например, программный интерфейс есть у Яндекса, у Амазон ( про инструменты для парсинга Amazon ) и у других крупных площадок. Тогда для успешной «разборки» автоматических ответов сервера применяются дополнительные модули, каждый из которых будет отвечать за свой API-интерфейс – потому что у каждого сайта свои особенности.

Сами парсеры могут отдавать данные по своему API. Обычно такой функционал есть у облачных сервисов или у программ/скриптов, предназначенных для работы внутри удалённого сервера.

Программы для парсинга сайтов могут быть универсальными, то есть рассчитанными на широкий круг задач, или специализированными. Пример последних – сникер-боты . Это парсеры, работающие только с сайтами брендовых кроссовок. В российском сегменте многие знают KeyCollector – это программный комплекс для широкого пула SEO-задач. Умеет парсить поисковую выдачу и сервисы сбора ключевых слов (Яндекс.Вордстат, Тренды Google, Яндекс.Директ и пр.). Ещё один пример узкой специфики – Netpeak Spider, это парсер мета-тегов и кодов ответа сервера.

Какие ограничения и недостатки имеет алгоритм настройки парсера файлов


При использовании такой техники загрузки можно значительно повысить скорость загрузки и никаких специальных навыков для этого не понадобится. Но если вы веб разработчик, то знание механизма спекулятивного парсинга поможет использовать его по максимуму.Различные браузеры предзагружают различные типы ресурсов. Все основные браузеры обязательно предзагружают следующие:
  • скрипты
  • внешние CSS
  • и изображения в теге
Firefox ="//somehost.com/widget.js" id="3c8_h3_0" src="/sites/all/modules/_custom/mainsitesettings/load.gif" data-pin-hover="1" data-pin-description="Мастерство в настройке парсера файлов: алгоритмы и подходы" alt="Мастерство в настройке парсера файлов: алгоритмы и подходы" title="Мастерство в настройке парсера файлов: алгоритмы и подходы" class="lazyload" data-src="https://lajfhak.ru-land.com/sites/default/files/i/lajfhak.ru-land.com/26424/6-9/d76a09ae53d6.jpg" />

Отпечатки TCP/IP

Более сложный способ распознание парсеров – это обнаружение отпечатков TCP/IP. TCP – это один из основных протоколов интернета, отвечающий за транспортировку данных, он так же оставляет множество сопутствующих параметров, например, начальное состояние окна. Если эти значения параметров не будут совпадать, доступ будет ограничен. Например, отправка запроса от имени Chrome с сервера на linux ожидаемый TTL будет отличаться от актуального.

Блокировка IP

Если один IP-адрес будет неоднократно уличён в отправке нечеловеческих запросов, то его могут просто заблокировать. Это ограничение легко обходится при помощи прокси серверов, или других инструментов, изменяющих ваш ip.

Геоблокировка

Некоторые сайты могут блокировать запрос, который исходит из определённого региона. Похожая проблема может возникнуть, если в зависимости от региона меняется контент. Эти сложности так же легко решаются при помощи прокси.