Python остаётся языком по умолчанию для веб-парсинга, потому что экосистема вокруг него глубокая, зрелая и модульная. Парсер редко создаётся из одного инструмента. Вы выбираете загрузчик, парсер и (когда странице нужен браузер) уровень автоматизации, а затем соединяете их вместе. Сложная часть, знать, какая библиотека хорошо справляется с какой задачей, чтобы не тянуться за полным фреймворком краулинга для разбора одной страницы или за headless-браузером там, где хватило бы обычного HTTP-запроса.
В этом обзоре рассматриваются пять Python-библиотек, охватывающих подавляющее большинство реальных задач парсинга: Requests, Beautiful Soup, lxml, Scrapy и Selenium. По каждой вы узнаете, что это такое, в чём её сильная сторона и когда к ней обращаться, с небольшим сниппетом там, где строчка кода объясняет всё быстрее абзаца. По итогам вы сможете подобрать правильный стек для конкретной цели, а не использовать по привычке то, что применяли в прошлый раз.
Как выбрать библиотеку для скрапинга на Python
Четыре вопроса определяют большинство решений, и они чётко соответствуют библиотекам ниже. Первый: как вы получаете HTML, простым запросом или настоящим браузером, выполняющим JavaScript? Второй: как вы извлекаете данные из разметки, лояльным парсером для неаккуратного HTML или быстрым строгим для чистых документов? Третий: каков масштаб, одна страница или тысячи страниц с очередями, повторными попытками и конвейерами? Четвёртый: рендерит ли цель контент на клиенте, где скачанный HTML почти пуст до выполнения скриптов?
Сопоставьте инструмент с ответом, и стек собирается сам. Requests загружает статические страницы, Beautiful Soup и lxml их парсят, Scrapy справляется с краулингом в масштабе, а Selenium управляет браузером там, где страница существует только после JavaScript. Ни один из них не является универсально лучшим, поэтому таблица в конце сопоставляет каждый с той задачей, которой он владеет.
Requests
Requests, HTTP-клиент, с которого начинает большинство Python-парсеров. Он хорошо делает одно: отправляет запрос и передаёт ответ, обрабатывая сессии, куки, заголовки и редиректы в чистом API. Он не парсит HTML и не выполняет JavaScript, поэтому самостоятельно видит только сырую разметку, которую возвращает сервер. Для статических страниц, публичных каталогов и любых эндпоинтов, возвращающих HTML или JSON напрямую, этого вполне достаточно, и он работает быстро, потому что нет накладных расходов браузера.
Используйте Requests как уровень загрузки всегда, когда нужный контент присутствует в первоначальном ответе. Соедините с парсером (Beautiful Soup или lxml), чтобы превратить ответ в структурированные данные. Главное ограничение, обратная сторона скорости: он не может парсить страницы, собирающие контент с помощью клиентского JavaScript, потому что никогда его не выполняет.
import requests resp = requests.get("https://example.com") print(resp.status_code) # 200 html = resp.text # raw HTML, ready to parse
Beautiful Soup
Beautiful Soup (текущий релиз, Beautiful Soup 4), классический Python-парсер, и его живучесть объясняется одним качеством: он грациозно справляется с некорректной разметкой. Реальный HTML полон незакрытых тегов и сломанной вложенности, а Beautiful Soup превращает даже беспорядочные документы в навигируемое дерево Python-объектов, по которому можно искать по тегу, классу или атрибуту. API читается почти как обычный английский, поэтому он обычно становится первым парсером, который изучают начинающие.
Используйте Beautiful Soup, когда разметка нерегулярна, проект небольшой или средний, или когда читаемость важнее сырой скорости. Он не загружает страницы самостоятельно, поэтому работает за Requests, и медленнее lxml на больших документах. Для большинства задач парсинга этот разрыв никогда не имеет значения. Наше руководство по Beautiful Soup в Python подробнее рассматривает его селекторы и навигацию по дереву.
from bs4 import BeautifulSoup soup = BeautifulSoup(html, "html.parser") title = soup.find("h1").text links = [a["href"] for a in soup.select("a[href]")]
lxml
lxml, это вариант для скорости. Построенный на C-библиотеках libxml2 и libxslt, он парсит большие HTML- и XML-документы значительно быстрее, чем парсер на чистом Python, и предлагает полную поддержку XPath, дающую точные и выразительные запросы к глубоко вложенной разметке. Когда вы обрабатываете тысячи документов или извлекаете данные из структурированных XML-лент, это различие в производительности становится причиной его выбора.
Используйте lxml, когда важна скорость, документы большие или вам нужны XPath-запросы вместо CSS-селекторов. Компромисс в том, что он строже Beautiful Soup, поэтому очень сломанная разметка может его сбить с толку, а API чуть менее дружелюбен для новичков. Многие команды используют оба: lxml как базовый парсер Beautiful Soup, чтобы получить лучшее из лояльной навигации и быстрого парсинга. Если вы взвешиваете стили запросов, статья о XPath и CSS-селекторах сравнивает их напрямую.
from lxml import html as lxml_html tree = lxml_html.fromstring(html) prices = tree.xpath("//span[@class='price']/text()")
Scrapy
Scrapy, это не парсер, это полноценный фреймворк для краулинга. Там где перечисленные библиотеки выполняют каждая одну задачу, Scrapy предоставляет весь конвейер: асинхронный движок, параллельно загружающий множество страниц, планирование запросов, следование по ссылкам, повторные попытки и встроенный экспорт структурированных данных в JSON, CSV или XML. Он создан для проектов, которые обходят большое количество страниц и нуждаются в организации этой работы в пауков, определения элементов и конвейеры обработки, а не в одиночный скрипт.
Используйте Scrapy, когда масштаб и структура, это главное: периодические обходы, многие тысячи URL или данные, которые должны проходить через этапы очистки и хранения. Плата за эту мощь, более крутая кривая обучения и больший объём настройки, чем у быстрого скрипта Requests плюс парсер, поэтому для одной страницы это избыточно. Как и Requests, vanilla Scrapy не выполняет JavaScript, хотя интегрируется с браузерными инструментами, когда цель требует рендеринга.
import scrapy class BookSpider(scrapy.Spider): name = "books" start_urls = ["https://books.toscrape.com"] def parse(self, response): for book in response.css("article.product_pod"): yield {"title": book.css("h3 a::attr(title)").get()}
Selenium
Selenium, это автоматизация браузера. Он управляет настоящим браузером (Chrome, Firefox и другими), чтобы страница загружалась так, как её увидит пользователь, с JavaScript и всем остальным. Это делает его ответом на динамические сайты, где скачанный HTML почти пуст до выполнения скриптов, которые инжектируют контент. Поскольку он управляет реальным браузером, он также может кликать кнопки, заполнять формы, прокручивать и ждать появления элементов, что необходимо для контента, загружающегося только после взаимодействия.
Используйте Selenium, когда цель рендерит на клиенте и обычный запрос не возвращает полезных данных. Компромисс, вес: управление браузером медленнее и ресурсоёмче, чем HTTP-запрос, и он не может читать сырые коды статуса ответов так, как это делает клиент запросов. Используйте его только там, где рендеринг действительно необходим, и оставляйте более лёгкий стек Requests плюс парсер для всего статичного. О более широком паттерне читайте в статье о краулинге JavaScript-сайтов.
from selenium import webdriver driver = webdriver.Chrome() driver.get("https://example.com") html = driver.page_source # fully rendered DOM driver.quit()
Если вам нужен только рендеринг, а не полная UI-автоматизация, современные альтернативы вроде Playwright управляют несколькими браузерами из одного API с аналогичным набором функций. Selenium остаётся наиболее широко поддерживаемым и документированным вариантом, именно поэтому он по-прежнему является выбором по умолчанию для автоматизации браузера, но стоит знать, что поле шире одного инструмента.
Библиотеки бок о бок
Пять частей вписываются в небольшое количество слотов. Эта таблица сопоставляет каждую с задачей, которой она владеет, и типом инструмента, чтобы вы могли прочитать вашу цель по ней: загружайте с Requests, парсите с Beautiful Soup или lxml, масштабируйте с Scrapy, рендерите с Selenium.
| Library | Best for | Type |
|---|---|---|
| Requests | Загрузка статических страниц и API | HTTP-клиент |
| Beautiful Soup | Парсинг неаккуратного или нерегулярного HTML | HTML-парсер |
| lxml | Быстрый парсинг, большие документы, XPath | HTML/XML-парсер |
| Scrapy | Краулинг и конвейеры в большом масштабе | Фреймворк для краулинга |
| Selenium | Страницы с JavaScript-рендерингом и интерактивные | Автоматизация браузера |
Обратите внимание: ни одна строка не является ответом на всё. Реалистичный парсер сочетает их: Requests плюс Beautiful Soup для статических страниц, Scrapy когда краулинг вырастает, Selenium когда странице нужен браузер. Навык, в сопоставлении слота с целью, а не в выборе фаворита.
Где блокировки становятся настоящим узким местом
Выберите правильную библиотеку, и ваш код верен, но сеть по-прежнему враждебна. Многие цели противодействуют автоматизированному трафику с помощью ограничений скорости, IP-блокировок, CAPTCHA и контента, появляющегося только после выполнения JavaScript. В этот момент узким местом становится уже не парсер, а сохранение доступа в тысячах запросов, и эта работа (ротация прокси, рендеринг браузера, логика повторных попыток) находится за пределами того, для чего создавалась любая отдельная библиотека парсинга.
Какой бы библиотекой вы ни парсили, Crawlbase Crawling API может быть уровнем загрузки под ней. Вы отправляете URL, а он обрабатывает ротацию IP, рендеринг браузера для тяжёлых JavaScript-страниц и повторные попытки при блокировках на стороне сервера, затем возвращает чистый HTML прямо в Beautiful Soup, lxml или Scrapy. Он работает рядом с вашим Python-стеком, а не заменяет его, поэтому вы сохраняете свою логику парсинга и перестаёте поддерживать антиблокировочную инфраструктуру.
Это разделение труда, практический вывод: продолжайте использовать Python-библиотеку, подходящую для вашего парсинга и краулинга, а управляемый уровень загрузки пусть поглощает сетевые проблемы, для решения которых она никогда не предназначалась. О более широком наборе методов читайте в статье о парсинге сайтов без блокировок.
Ответственный скрапинг
Какой бы стек вы ни собрали, парсите сдержанно. Соблюдайте условия использования сайта и его robots.txt, сосредоточьтесь на общедоступных данных, а не на тех, что за входом в систему, на который у вас нет права, и держите темп запросов разумным, чтобы не нагружать серверы, от которых зависите. Ответственный темп к тому же практичен: деликатный, хорошо идентифицированный трафик значительно реже получает ограничение по скорости или блокировку, чем агрессивный обход, поэтому хорошие манеры и надёжный парсинг указывают в одном направлении.
Ключевые выводы
- Единственной лучшей библиотеки нет. Реальный парсер сочетает загрузчик, парсер и иногда браузер, поэтому подбирайте каждый инструмент под задачу, а не выбирайте любимый.
- Requests загружает, парсеры парсят. Requests быстро тянет статические страницы и API, а Beautiful Soup или lxml превращают этот HTML в структурированные данные.
- Beautiful Soup прощает, lxml быстр. Используйте Beautiful Soup для неаккуратной разметки и читаемости, lxml для скорости, больших документов и XPath.
- Scrapy для масштаба. Обращайтесь к полному фреймворку краулинга, когда у вас тысячи страниц, очереди, повторные попытки и конвейеры, а не одиночный скрипт.
- Selenium рендерит JavaScript. Когда страница пуста до выполнения скриптов, управляйте настоящим браузером и принимайте связанные затраты скорости и ресурсов.
Часто задаваемые вопросы
Какая библиотека Python лучшая для веб-скрапинга?
Единственно лучшей нет, потому что они выполняют разные задачи. Для большинства статических страниц Requests для загрузки плюс Beautiful Soup для парсинга, самый простой надёжный стек. Добавляйте lxml, когда нужна скорость или XPath, Scrapy когда краулинг вырастает до тысяч страниц, и Selenium когда цель рендерит контент только через JavaScript.
Использовать BeautifulSoup или lxml?
Используйте Beautiful Soup, когда разметка беспорядочная или важна читаемость, поскольку он корректно обрабатывает сломанный HTML и читается почти как обычный английский. Используйте lxml, когда вы парсите большие документы, нужна максимальная скорость или XPath-запросы. Они не исключают друг друга: lxml может служить базовым парсером Beautiful Soup, давая вам и лояльную навигацию, и быстрый парсинг.
Когда нужен Scrapy вместо Requests?
Используйте Requests плюс парсер для разовых или небольших задач. Переходите к Scrapy, когда обходите много страниц и хотите встроенный параллелизм, планирование запросов, следование по ссылкам, повторные попытки и структурированный экспорт. Scrapy организует проект в пауков и конвейеры, что является накладными расходами, которые не нужны для одной страницы, но реальным преимуществом в масштабе.
Может ли Python скрапить страницы с JavaScript-рендерингом?
Да, но не с Requests в одиночку, потому что он никогда не выполняет JavaScript. Для страниц с клиентским рендерингом используйте инструмент автоматизации браузера вроде Selenium, загружающий страницу в настоящий браузер, чтобы скрипты выполнялись и инжектировали контент. Компромисс в том, что браузеры медленнее и тяжелее HTTP-запросов, поэтому оставляйте их для страниц, которые действительно нуждаются в рендеринге. Смотрите также как парсить JavaScript-страницы с Python.
Почему мой скрапер на Python блокируют?
Большинство блокировок приходит из сети, а не из вашего кода: слишком много запросов слишком быстро, IP, помеченный целью, или CAPTCHA-вызов. Исправление, ротация IP, реалистичный темп запросов и рендеринг там, где требуется. Управляемый уровень загрузки, такой как crawling API, обрабатывает ротацию, рендеринг и повторные попытки, чтобы ваша библиотека парсинга могла сосредоточиться на извлечении данных.
Нужны ли все пять библиотек для одного проекта?
Нет. Выбирайте те, которых требует цель. Типичный парсер статических сайтов использует только Requests и Beautiful Soup. Вы добавляете lxml для скорости или XPath, Scrapy для крупных обходов и Selenium для рендеринга JavaScript. Большинство проектов используют два или три из них в сочетании для загрузки, парсинга и, при необходимости, рендеринга браузером.
Обходите любой сайт в масштабе, без борьбы с инфраструктурой.
Crawlbase берёт на себя прокси, отпечатки и CAPTCHA, чтобы ваша команда выпускала конвейеры данных вместо поддержки обвязки краулинга. 1 000 запросов бесплатно, без карты.
