Бенчмарк HTML парсеров в Python: сравнение скорости
Привет, Хабр!
Меня зовут Вадим Москаленко и я разработчик инновационных технологий Страхового Дома ВСК. В этой статье хочу поделиться с вами информацией по проведенному сравнению производительности нескольких популярных библиотек для простого 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 раунде
Результаты:
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 раундах
Результаты:
позиции участников никак не изменились
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 раундах
Результаты и выводы:
используя 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-канал: ВСК Страховой Дом