Веб-скрейпинг с Python: полное руководство [2026]
Веб-скрейпинг на Python далеко продвинулся от простых скриптов, извлекающих HTML со статических страниц. Современные веб-сайты активно используют рендеринг JavaScript, агрессивные системы защиты от ботов, фингерпринтинг и ограничения по частоте запросов, что означает, что успешный веб-скрейпинг с помощью Python теперь требует большего, чем просто requests и BeautifulSoup.
В этом руководстве вы узнаете, как на самом деле работает веб-скрейпинг на Python в 2026 году, как выполнять скрейпинг как статических, так и динамических веб-сайтов, и как выбрать правильные инструменты для разных целей.
Мы рассмотрим всё: от запросов, BeautifulSoup и lxml до Playwright, Scrapy и curl_cffi, а также практические методы работы с пагинацией, ротацией прокси, браузерным фингерпринтингом, защитой Cloudflare и крупномасштабными сценариями веб-скрейпинга.
Что такое веб-скрейпинг?
Веб-скрейпинг это автоматизированное извлечение данных с веб-сайтов. Вы пишете программу, которая посещает URL, загружает HTML страницы, находит элементы, содержащие нужные вам данные — цены, названия товаров, новостные статьи, контактные данные — и сохраняет эти данные в структурированном формате, таком как CSV, JSON или база данных.
В 2026 году Python станет языком выбора для веб-скрейпинга по трем причинам: его библиотеки изначально охватывают все этапы рабочего процесса, код достаточно понятен, чтобы его могли поддерживать даже неспециалисты, а также у него самое большое сообщество, разрабатывающее инструменты специально для веб-скрейпинга. Согласно большинству опросов разработчиков, более 70% программ для веб-скрейпинга написаны на Python.
Независимо от того, используете ли вы Python для веб-скрейпинга небольших исследовательских проектов или для создания производственных конвейеров данных, он предлагает зрелые библиотеки для HTTP-запросов, разбора HTML, автоматизации браузеров, асинхронного сканирования и обработки антиботов.
Распространенные сценарии использования веб-скрейпинга на Python:
- Мониторинг цен — отслеживать цены конкурентов на сайтах электронной коммерции
- Генерация лидов — соберите бизнес-каталоги, страницы контактов, доски вакансий
- Маркетинговые исследования — агрегировать отзывы о продуктах, настроения в социальных сетях, освещение в новостях
- Академические исследования — создавать наборы данных из общедоступных источников для обучения NLP или ML
- Данные о недвижимости — собирать списки, тенденции цен, детали объекта недвижимости
- SEO-мониторинг — отслеживать позиции, извлекать фичи SERP, мониторить бэклинки
- Путешествия и гостиничный бизнес — собрать цены на авиабилеты, наличие номеров в отелях, отзывы
Является ли веб-скрейпинг законным?
Веб-скрейпинг общедоступных данных находится в юридической "серой зоне", которая варьируется в зависимости от юрисдикции, целевого сайта и способа проведения скрейпинга. Знаковое решение 2022 года по hiQ Labs против LinkedIn (Девятый окружной суд США) подтвердил, что скрейпинг общедоступных данных, как правило, не нарушает Закон о мошенничестве и злоупотреблениях с использованием компьютеров, но это решение не дает полного разрешения на все.
Практический чек-лист перед скрейпингом любого сайта:
| Разложить на множители | Что проверить | Риск при игнорировании |
| robots.txt | Проверить `/robots.txt` на директивы Disallow | Нарушение Условий предоставления услуг, гражданский иск |
| Условия обслуживания | Прочитайте Условия предоставления услуг — многие из них явно запрещают автоматизированный доступ | Нарушение договора, блокировка аккаунта |
| Персональные данные (GDPR/CCPA) | Не собирайте и не храните имена, адреса электронной почты, идентификаторы без законных оснований | Регуляторный штраф (20 млн евро+) |
| Ограничение скорости | Добавить задержки — агрессивный скрейпинг в некоторых юрисдикциях может быть расценен как DoS | Уголовная ответственность |
| Контент, требующий входа в систему | Никогда не парсите данные за аутентификацией, которой вы не владеете | нарушение CFAA |
| Авторское право | Извлечение объектов авторского права (текст, изображения) имеет отдельные виды защиты | DMCA-уведомление о прекращении действия, судебный иск |
Как работает веб-скрейпинг
Прежде чем написать первую строку кода на Python, понимание того, что на самом деле происходит "под капотом", значительно упрощает отладку.
- HTTP-запрос
Ваш скрейпер отправляет HTTP GET-запрос на URL. Сервер его получает и решает, отвечать HTML или заблокировать вас.
- Ответ сервера
Сервер возвращает HTML страницы (статические сайты) или начальную HTML-оболочку, которую затем заполняет JavaScript (динамические сайты). Вам нужно знать, с каким типом вы имеете дело, прежде чем выбирать инструмент.
- Разбор HTML
Ваш парсер читает HTML-дерево и находит элементы по их тегу, классу, ID или XPath. Здесь вы извлекаете нужные вам данные.
- Очистка данных
Необработанный HTML содержит пробелы, специальные символы и форматирующий шум. Вы очищаете и нормализуете его до чистых, пригодных для использования значений.
- Хранилище
Сохранить в CSV, JSON, базу данных или отправить в API. Правильный формат зависит от того, что вы будете делать с данными дальше.
Статические против динамических страниц: это определяет всё
Самый важный вопрос перед написанием любого скрапера: содержится ли данные в исходном HTML-коде или они загружаются с помощью JavaScript?
Щелкните правой кнопкой мыши по странице → Просмотреть исходный код страницы. Если ваши данные видны в этом исходном коде, значит, они статичны. Если вы видите почти пустую оболочку с , это динамический, и вам понадобится инструмент автоматизации браузера, такой как Playwright.
Библиотеки Python: выбор правильного инструмента
Не существует единой “лучшей” библиотеки для веб-скрейпинга на Python. Правильный инструмент зависит от типа целевой страницы, масштаба вашего проекта и требований к задержке. Вот полный обзор:
| Библиотека | Роль | Обрабатывает JavaScript? | Скорость | Лучшее для |
| запросы | HTTP-запросы | 🔴 Нет | 🟢 Быстро | Статические страницы, API |
| BeautifulSoup4 | HTML-парсинг | 🔴 Нет | 🟡 Средний | Парсинг HTML с простыми селекторами |
| lxml | HTML/XML разбор | 🔴 Нет | 🟢 Очень быстро | Большие страницы, опытные пользователи XPath |
| Драматург | Автоматизация браузера | ✅ Да | 🟡 Медленнее | Сайты с большим количеством JavaScript, взаимодействие с формами |
| Селен | Автоматизация браузера (устаревшая) | ✅ Да | 🔴 Самый медленный | Устаревшие проекты, существующие наборы тестов |
| Скрапи | Полный фреймворк для веб-сканирования | 🌐 Плагин | 🟢 Очень быстро | 1000+ страниц, производственные конвейеры |
| curl_cffi | TLS-отпечаток-безопасный HTTP | 🔴 Нет | 🟢 Быстро | Сайты, защищенные Cloudflare |
| httpx | Асинхронный HTTP-клиент | 🔴 Нет | 🟢 Быстро | Асинхронный скрейпинг, поддержка HTTP/2 |
Дерево решений библиотеки
Данные в исходном коде (сырой HTML)?
├── ДА
│ ├── Небольшой проект (1–100 страниц)? → requests + BeautifulSoup
├── Максимальная скорость / XPath? → requests + lxml
└── Масштабный краулинг (1000+ страниц)? → Scrapy
└── НЕТ (отрендерено JavaScript)
├── Есть ли JSON API в DevTools → Network → XHR?
│ └── ДА → requests (вызывать API напрямую — быстрее всего!)
└── нет реального API
├── Заблокировали Cloudflare? → curl_cffi или Playwright + stealth
└── Стандартный рендеринг JS? → Playwright (предпочтительнее Selenium)
Первый парсер веб-сайтов на Python
Установка и настройка
Проверяйте перед написанием кода
Этот шаг сэкономит вам часы разочарования. Прежде чем писать какой-либо код на Python, откройте DevTools в браузере (F12), нажмите на Элементы вкладку и наведите курсор на данные, которые вы хотите извлечь. Обратите внимание на HTML-тег, имя класса и любую родительскую структуру. Селектор, который вы будете использовать в Python, напрямую соответствует тому, что вы видите здесь.
Рабочий скрапер
Мы соскребем books.toscrape.com, изолированный сайт, предназначенный для практики скрейпинга, поэтому он полностью легален и не будет вас блокировать.
🚀 Совет: Использование lxml как парсер BeautifulSoup (BeautifulSoup(html, “lxml”)) вместо html.parser. Это значительно быстрее для больших страниц и более корректно обрабатывает некорректный HTML.
CSS-селекторы и XPath: поиск ваших данных
Выбор правильного селектора — это разница между скрейпером, который надежно работает месяцами, и тем, который ломается каждый раз, когда сайт обновляет свой CSS. Вот практическое руководство.
CSS Селекторы (рекомендуется для большинства случаев)
XPath (лучше всего подходит для сложных обходов)
🚀 Совет: В Chrome DevTools щелкните правой кнопкой мыши на любом элементе → Копировать → Копировать селектор (или Копировать XPath). Это даст вам отправную точку, хотя автоматически сгенерированные селекторы часто неустойчивы. Упростите их, ориентируясь на стабильные атрибуты, такие как data-* атрибуты, идентификаторы или семантические имена классов вместо позиционных селекторов.
Очистка страниц, отрисованных JavaScript, с помощью Playwright
Значительная часть современных веб-сайтов — электронная коммерция, SaaS, социальные платформы — отображает свой контент с помощью JavaScript после загрузки начального HTML. Если вы не можете найти свои данные в “Просмотреть источник”, вам понадобится инструмент, который запускает настоящий браузер.
Playwright — современный выбор в 2026 году: он быстрее, имеет более чистый API, нативно поддерживает асинхронность и имеет лучшие встроенные механизмы ожидания. Selenium по-прежнему жизнеспособен для устаревших проектов, но для новой работы начните с Playwright.
Настройка
Базовый скрейпер Playwright
Асинхронный Playwright (для одновременного скрейпинга нескольких страниц)
🚀 Совет: Сначала проверьте вкладку "Сеть". Перед переходом на Playwright откройте DevTools → Network → Fetch/XHR и перезагрузите страницу. Многие сайты, которые кажутся отрисованными с помощью JavaScript, на самом деле предоставляют чистый конечный API JSON. Вызов этого API напрямую с помощью запросов в 10–50 раз быстрее, чем запуск браузера, и намного стабильнее.
Обработка пагинации
Реальный скрейпинг редко ограничивается одной страницей. Вот два распространенных шаблона и способы их обработки.
Шаблон 1: Пагинация на основе URL
Многие сайты используют предсказуемые шаблоны URL: /страница/2, ?страница=3, &start=40. Эти легче всего обращаться.
Паттерн 2: “Далее” кнопка обхода
Когда URL-адреса непредсказуемы, следуйте по ссылке следующей страницы непосредственно из HTML.
Хранение собранных данных
Правильный формат хранения полностью зависит от того, что вы планируете делать с данными в дальнейшем. Вот руководство по принятию решений и реализация для каждого варианта.
| Формат | Лучшее для | Максимальный масштаб | Запрашиваемый? |
| CSV | Разовые экспорты, потребление Excel/pandas | ~100 тыс. строк | Нет |
| JSON | API, вложенные/нерегулярные структуры данных | ~100 тыс. строк | Нет |
| SQLite | Дедупликация, локальные запросы, средний масштаб | ~10 млн строк | Да |
| PostgreSQL | Производственные конвейеры, многопользовательские, крупномасштабные | Неограниченный | Да |
| пандас DataFrame | Немедленный анализ/визуализация данных | Ограничение ОЗУ | Да |
Почему скреперы блокируют и как это исправить
Это раздел, который большинство обучающих материалов по веб-скрейпингу на Python полностью пропускают, и причина, по которой большинство скрейперов терпят неудачу в продакшене. Антиботовые системы работают многоуровнево, и понимание каждого уровня — первый шаг к их обходу.
Стек обнаружения (отсортировано по времени срабатывания)
| Слой | Что это проверяет | Исправить | |
| 1 | TLS-отпечаток | JA3/JA4 хеш вашего TLS ClientHello — срабатывает перед чтением заголовков | curl_cffi для имитации стека TLS реального браузера |
| 2 | HTTP-заголовки | Заголовки Bare requests совсем не похожи на заголовки настоящего браузера | Установить полный, реалистичный набор заголовков, включая Sec-Fetch-* |
| 3 | Репутация IP-адреса | IP-адреса дата-центров помечены; слишком много запросов с одного IP = блокировка | Вращать резидентские прокси по запросу |
| 4 | Время запроса | Машинно-идеальный тайминг — это сигнал бота | Случайные задержки (1–4с), джиттер по интервалам |
| 5 | Браузерный отпечаток | Утечки из браузера без головы: navigator.webdriver, недостающие плагины, хэш Canvas | Playwright с playwright-stealth |
| 6 | Поведенческий анализ | Нет движения мыши, скроллинга или шаблонов взаимодействия | Playwright с рандомизированной симуляцией мыши/скролла |
Уровень 1: обход TLS-отпечатка с помощью curl_cffi
Это наиболее часто упускаемое исправление в 2026 году. Cloudflare, Akamai и DataDome проверяют TLS ClientHello сообщение еще до того, как ваши HTTP-заголовки будут доставлены. Стандартный Python запросы библиотека создает отпечаток, который тривиально определяется как не браузер. Исправление заключается в curl_cffi:
Уровень 2: установка реалистичных HTTP-заголовков
Слой 5–6: скрытный playwright
Использование резидентских прокси в Python
Блокировка IP-адресов — самая частая причина сбоев Python-скрейперов в продакшене. Как только сайт идентифицирует ваш IP-адрес — через ограничение скорости запросов, обнаружение ASN дата-центров или фингерпринтинг, — каждый запрос с этого адреса блокируется. Единственное надежное решение — это вращение прокси с использованием резидентских IP-адресов.
Почему именно резидентские прокси?
| Тип прокси | Риск обнаружения | Скорость | Лучшее для |
| Центр обработки данных | 🔴 Высокий — ASN легко отмечен | 🟢 Быстро | Сайты только с низкой защитой |
| Резидентские | 🟢 Низко — настоящие IP-адреса интернет-провайдеров | 🟡 Средний | Большинство сайтов электронной коммерции, новостных, информационных |
| ISP (статический резидентский) | 🟢 Низкий — резидентское доверие + скорость | 🟢 Быстро | Скрейпинг на основе сессий, потоки входа в систему |
| Мобильный (4G/5G) | 🟢 Очень низкий — IP-адреса носителей доверенные | 🟡 Варьируется | Высоконадежные объекты, социальные платформы |
Резидентские прокси маршрутизируйте свои запросы через реальные домашние IP-адреса, назначенные интернет-провайдерами, того же типа IP, который использует человек, просматривающий информацию из своего дома. Для целевого веб-сайта трафик выглядит идентично действиям обычного пользователя. Вот почему они являются стандартным выбором для серьезного веб-скрейпинга на Python.
Начните безопасный скрейпинг с прокси NodeMaven
Прокси NodeMaven для Python Более 30 миллионов предварительно отфильтрованных IP-адресов частных пользователей обеспечивают коэффициент успешности скрейперов на уровне более 98,1 %.
Каждый IP-адрес проходит Фильтр качества — без обожженных, помеченных или переработанных адресов в пуле. Включает ротационные и статические варианты, SOCKS5 + HTTPS и географическое таргетирование на уровне почтового индекса по всей 190+ локаций.
Базовая интеграция прокси с requests
Ротационные прокси по запросу
Для максимальной защиты от обнаружения меняйте прокси при каждом запросе, чтобы каждый выглядел исходящим от нового пользователя.
Прокси на основе сессий (для потоков входа)
При скрейпинге залогиненных сайтов — или любых сценариев, требующих использования одного и того же IP-адреса для нескольких запросов — используйте прокси с «липкими» сессиями:
Геотаргетированные прокси для локализованных данных
Одним из самых мощных сценариев использования резидентские прокси В Python скрейпинг — это доступ к региональному контенту: локализованные цены, результаты поиска, наличие товаров или страницы с географическими ограничениями. NodeMaven поддерживает таргетинг на уровне почтовых индексов, наиболее детальный доступный геотаргетинг:
Прокси с Playwright
Логика повторных попыток производства
Фильтр качества IP-адресов NodeMaven отличает его от обычных поставщиков прокси. Прежде чем IP-адрес попадет в пул, он проверяется по базам данных о мошенничестве и оценивается. Только IP-адреса с чистой историей и «Оценки мошенничества <70%» — это означает, что вы будете получать меньше ошибок 403, реже сталкиваться с CAPTCHA и сможете проводить более длительные сессии сбора данных без необходимости столь частой смены доменных имен. Узнайте о фильтре качества
Масштабирование с помощью Scrapy
Для проектов, требующих извлечения тысяч или миллионов страниц, или нуждающихся в работе по расписанию с логикой повторных попыток, ограничением скорости и конвейерами структурированных данных, Scrapy — правильный выбор. Он "из коробки" управляет параллелизмом, промежуточным ПО, конвейерами элементов и развертыванием.
Быстрая настройка
Продакшн-паук со промежуточным ПО для прокси
Отладка и обработка ошибок
| Ошибка / Симптом | Вероятная причина | Исправить |
| 403 Запрещено | Отсутствующие заголовки или заблокированный IP-адрес | Добавить полные заголовки; сменить прокси |
| 429 Слишком много запросов | Превышен лимит запросов | Увеличить задержки; вращать прокси |
| AttributeError: ‘NoneType’ | select_one() ничего не вернул | Показать необработанный HTML; проверить селектор в DevTools |
| Пустой список из select() | Контент, отображаемый с помощью JS | Переключиться на Playwright; проверить XHR для API |
| Страница CAPTCHA возвращена | Обнаружен бот | Резидентские прокси + скрытые заголовки |
| ConnectionError / ProxyError | Ошибка прокси или тайм-аут | Логика повторных попыток; тестирование прокси с httpbin.org |
| Данные выглядят неправильными или усеченными | Неверный селектор или кодировка | Напечатать soup.prettify(); проверить response.encoding |
| SSLError | Выдача сертификата | verify=False (только для разработки) или обновить сертификаты |
| Тайм-аут Playwright | Селектор никогда не появлялся (JS не удалось) | Увеличить время ожидания; добавить ожидание networkidle |
Золотое правило отладки
Когда селектор ничего не возвращает, первое, что нужно сделать, — это вывести то, что вы на самом деле получили, а не то, что ожидали:
Полный справочник

