Привет, Хабр!

Меня зовут Вадим Москаленко и я разработчик инновационных технологий Страхового Дома ВСК. В этой статье хочу поделиться с вами информацией по проведенному сравнению производительности нескольких популярных библиотек для простого HTML-парсинга.

При необходимости сбора данных с HTML или XML, многим python-разработчикам сразу вспомнятся две популярные библиотеки «BeautifulSoup4» и «lxml» — они весьма удобны и стали широко применяемыми. Но что, если в нашем проекте важна скорость сбора данных? Возникает вопрос: кто из них быстрее и есть ли еще более быстрые библиотеки? При поиске данной информации на Хабре, я нашел подобные статьи, но им уже несколько лет. Так как прогресс не стоит на месте и появляются новые инструменты или те, о которых еще не слышали, мне было интересно провести личное исследование и поделиться информацией.

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

В качестве задачи используем поисковик нашего любимого habr.com, в который отправим запрос с ключевыми словами «html parsing python» и соберем следующие данные по каждой статье: имя автора, заголовок, дату создания статьи, количество просмотров и голоса (оценки).

Участники

Python: 3.12.0

CPU: AMD Ryzen 7 3700X

Дополнительно протестируем разницу в применении парсеров «html» и «lxml» у BeautifulSoup4, использование «HTMLParser» или «LexborHTMLParser» у selectolax, разницу в применении поиска по CSS или XPath селекторам у requests-html, а также использование метода «find_class» у lxml, вместо привычного XPath.

Бенчмарк

Принцип работы скрипта: с помощью requests осуществляем запрос на получение страницы, сохраним content ответа и поочередно проведем парсинг различными методами, фиксируя время выполнения с помощью декоратора.

Запустим прогонный тест на парсинг первой страницы и при 1 раунде:

Время парсинга 1 страницы при 1 раунде
Время парсинга 1 страницы при 1 раунде

Результаты:

  • requests-html: несмотря на то, что использует «под капотом» BeautifulSoup, показывает наиболее худшие результаты. Если использовать XPath, вместо CSS результат улучшается примерно на 25%, на даже такой метод хуже варианта BeautifulSoup с использование парсера «lxml» 59,8 %

  • BeautifulSoup4: использование парсера «lxml», вместо «html.parser» ускоряет работу на 24,5%

  • lxml: использование метода поиска «find_class», хуже чем использование привычного XPath на 57,75%

  • selectolax: показывает лидерство

Запустим новый тест, в котором проведем парсинг по 10 страницам и с 10 раундами. Для информативности графика, исключим аутсайдера прошлого теста requests-html, результаты будут в таблице.

10 раундов - 10 страниц

Среднее время отработки

Медиана времени отработки

selectolax lexbor

0,01814754

0,0181863

selectolax html

0,02385281

0,02380865

lxml parser xpath

0,06488278

0,06480665

parsel xpath

0,09614886

0,0957695

lxml find class

0,17416978

0,17404505

bf4 lxml

0,40552705

0,4089891

bf4 html

0,53442332

0,5296515

requests-html xpath

1,04187903

1,04476375

requests-html

1,22853292

1,2294204

Время парсинга 10 страниц при 10 раундах
Время парсинга 10 страниц при 10 раундах

Результаты:

  • позиции участников никак не изменились

  • BeautifulSoup4: на дистанции, использование парсера «lxml», вместо «html.parser» ускоряет работу на 31,8%

  • lxml: на дистанции, использование метода поиска «find_class», хуже чем использование привычного XPath на 62,75%

  • selectolax: показывает лидерство, использование «LexborHTMLParser» быстрее, чем «HTMLParser» на 31,44 %

  • parsel: показывает средние результаты среди всех участников

Финальное тестирование: так как наш запрос, с ключевыми словами «html parsing python» выдает только 13 страниц, изменим его на «html» и получаем ограничение в 50 страниц поиска. Проведем парсинг всей информации с таким же количеством раундов. Для информативности графика, исключим аутсайдера прошлого теста BeautifulSoup4, результаты будут в таблице.

50 раундов - 50 страниц

Среднее время отработки

Медиана времени отработки

selectolax lexbor

0,08957974

0,08876955

selectolax html

0,1192404

0,11853815

lxml parser xpath

0,340518342

0,33733555

parsel xpath

0,503992694

0,5000295

lxml find class

0,931354268

0,92578665

bf4 lxml

2,195235648

2,194097

bf4 html

2,912655096

2,9080528

requests-html xpath

5,63474603

5,6141935

requests-html

6,595035754

6,5675001

Время парсинга 50 страниц при 50 раундах
Время парсинга 50 страниц при 50 раундах

Результаты и выводы:

  • используя selectolax с «LexborHTMLParser» вы получите информацию быстрее, по сравнению с:

    • selectolax с «HTMLParser» в 1,33 раза

    • lxml в 3,8 раза

    • parsel в 5,6 раза

    • BeautifulSoup4 в 24,5 раза

    • requests-html в 62,9 раза

  • используя lxml на XPath вы получите информацию быстрее, по сравнению с:

    • parsel в 1,5 раза

    • BeautifulSoup4 в 6,4 раза

    • requests-html в 16,5 раз

  • парсеры selectolax HTML и Lexbor невероятно быстры и является лидерами во всех тестах

  • парсер lxml используется и в BeautifulSoup4, и в parsel, но parsel превосходит BeautifulSoup4 с lxml «под капотом»

  • кроме selectolax, использующего CSS селекторы, во всех остальных случаях применение XPath (при поддержке) давало прирост скорости

Заключение

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

Если вам понравилась подобная подача информации, возможно вас заинтересует: «Лучший формат данных для хранения pandas.DataFrame».

Весь проект бенчмарка: ссылка на GitHub


Чтобы оставаться в курсе всех IT-новостей Страхового Дома ВСК, подписывайся на наши социальные сети:

Сообщество VK: IT-ВСК
Блог на Хабр: Страховой Дом ВСК
YouTube-канал: ВСК Страховой Дом

Комментарии (3)


  1. Sazonov
    14.12.2023 07:00

    А сравнения по скорости и памяти с RapidXML можно?


    1. V-Moskalenko Автор
      14.12.2023 07:00

      Добрый день! Библиотека на Python очень давно не обновлялась и нужно подготовить хорошие XML-кейсы для бенчмарка, как найду на это время - обязательно отпишусь


      1. Sazonov
        14.12.2023 07:00

        Ну часто обновлять то что работает не обязательно. Просто в целом, RapidXml на си очень быстрый. И если у вас парсинг является узким местом, то возможно нужно вынести этот код из питона?