Прямой ответ
Скрейпинг — техника простая и юридически/этически тонкая одновременно. Техническое ядро: HTTP-клиент (requests/httpx) + HTML-парсер (selectolax/BeautifulSoup для статических страниц; браузер-автоматизация только там, где контент рисуется JS и нет API), обязательные задержки между запросами (rate limiting), ретраи с backoff и корректный User-Agent. Этическое ядро: сначала искать официальный API или выгрузку данных (они есть чаще, чем кажется), уважать robots.txt и Terms of Service, не собирать персональные данные и не создавать нагрузку, способную положить сайт. Скрейпинг, который ведёт себя как вежливый пользователь — читает публичные данные, медленно и с представлением, — устойчив и технически, и репутационно.
Прежде чем скрейпить: альтернативы и границы
Чек-лист перед написанием первого запроса: есть ли публичный API (многие сайты отдают JSON тем же URL, что и страницу — проверьте Network-вкладку браузера: часто нужный JSON лежит рядом, и скрейпинг HTML не нужен вовсе); есть ли датасет/выгрузка (госданные, открытые каталоги, RSS); разрешает ли robots.txt нужный путь (формально не закон, но сигнал владельца — и его игнорирование ставит вас в плохую позицию); не нарушает ли сбор ToS и законодательство о данных (персональные данные, авторские права, базы данных — в ЕС отдельные директивы). Правило совести: если данные закрыты логином/платёжной стеной или владелец явно против — скрейпинг не «техзадача», а конфликт, и он того не стоит.
Статические страницы: requests + парсер
Минимальный устойчивый пайплайн: сессия с заголовками (честный User-Agent с контактом, Accept-Language) → запрос с таймаутом → проверка статуса (429/403 — сигнал сбавить темп, а не «обойти») → парсинг селекторами (selectolax/BeautifulSoup — CSS/XPath, а не regex по HTML: вложенность и экранирование ломают регулярки — о самих паттернах regex статья отдельная, вот она) → извлечение полей с дефолтами → запись в структурированное хранилище (JSONL/SQLite/CSV — с последующей очисткой в pandas: типы, дубликаты, пропуски — по паттернам очистки). Клиентская дисциплина (таймауты, сессии, ретраи) — из статьи про HTTP-клиенты; она же защищает сайт от вашего же ретрай-шторма.
Динамические страницы и «вежливость»
Если контент рендерится JavaScript, лестница решений: найти скрытый API (лучший вариант — JSON без браузера); попробовать серверный рендер (иногда ?print=true или старая версия страницы отдаёт статический HTML); и только потом браузер-автоматизация (Playwright) — тяжёлый инструмент: память, скорость, хрупкость селекторов, и нагрузка на сайт на порядок выше (десятки запросов ресурсов на «одну страницу»). Вежливость измеряется конкретно: задержка 1–5 секунд между запросами (или по Crawl-delay из robots.txt), последовательный обход вместо сотен параллельных соединений, кеш уже скачанных страниц (не перечитывать неизменное), проверка Last-Modified/ETag, уважение 429 и Retry-After. Скрейпер, который быстрее человека в 100 раз, — это уже DDoS по эффекту, независимо от намерений.
Устойчивость пайплайна сбора
Скрейпинг ломается тихо: сайт изменил вёрстку — и вы неделю собираете пустые поля. Защита — инварианты на каждой итерации: ожидаемое число записей на странице в диапазоне; ключевые поля непустые; контрольная сумма/количество за период; алерт при нуле результатов («страница есть, данные пропали» — типичный признак редизайна или блокировки). Идемпотентность хранения: первичный ключ записи (URL+дата) и upsert вместо слепой вставки — повторный прогон не дублирует данные. Сырые HTML-ответы стоит сохранять (объектное хранилище/архив): при изменении парсера историю можно перепарсить, не перечитывая сайт. Логи — структурированные, с URL и статусом (подход — в статье про логирование).
Хранение и легализация результата
Дальше данные живут по обычным правилам: очистка и типизация (pandas-паттерны), дедупликация, фиксация «когда и с какой версии сайта собрано» (provenance) — без этого данные невозможно ни проверить, ни обновить. Персональные данные — отдельный правовой режим (GDPR в ЕС): публичность не означает свободы обработки, и «собрал имена и телефоны со страницы» без основания — нарушение, а не находка. Коммерческое использование собранного — сверьтесь с ToS и правом баз данных; внутренняя аналитика и исследования — существенно более безопасная зона.
Практический сценарий: мониторинг цен на десять страниц
Задача из практики: раз в час проверять цены у трёх конкурентов на десяти товарных страницах — классический «вежливый» скрейпинг малого масштаба. Подготовка: robots.txt каждого домена прочитан (нужные пути разрешены; Crawl-delay — 2 секунды — принят к исполнению), в User-Agent — имя бота и контактный email (владелец сайта, которому мониторинг помешает, знает, кому написать, вместо того чтобы банить молча). Пайплайн: десять URL обходятся последовательно с паузой 2–5 секунд (не параллельно — десять страниц в час не требуют скорости, а «пачка» запросов заметна и некрасива), каждый ответ кешируется по ETag/Last-Modified (страница не изменилась — тело не перечитывается, трафик падает в разы); сессия requests с таймаутами и двумя ретраями с backoff на сетевые ошибки. Извлечение — selectolax-селекторами по цене и наличию, с инвариантами: цена распарсилась, положительна, изменилась не более чем на 50% к прошлому значению (скачок больше — подозрение на редизайн или антибот-заглушку, алерт и ручная проверка, а не тихая запись мусора). Хранение — SQLite с историей и provenance (URL, время, версия селекторов); сырой HTML последних снятий — рядом, чтобы при смене вёрстки понять, что произошло. Вся конструкция ведёт себя как очень медленный, очень вежливый посетитель — и именно поэтому работает годами без блокировок.
FAQ
Обязателен ли robots.txt юридически?
Это не закон, а конвенция, но суды и платформы учитывают его как выражение воли владельца; его нарушение ломает вашу позицию «я добросовестный сборщик». Технически его читает urllib.robotparser — три строчки кода.
Playwright или просто requests? Если HTML приходит готовым — requests в десятки раз легче и быстрее. Playwright оправдан только для JS-рендеринга без альтернатив, и даже тогда сначала поищите скрытый JSON-эндпоинт.
Как не получить бан по IP? Честный способ один — снизить темп и вести себя как человек (задержки, последовательность, кеш). Ротация прокси для обхода блокировки — эскалация конфликта с владельцем сайта; если вас забанили за вежливый темп, данные вам, скорее всего, собирать не разрешают.
Scrapy нужен? Для обходов с очередью URL, дедупликацией и politeness-настройками из коробки Scrapy экономит самописный каркас. Для «собрать сто страниц по списку» достаточно requests-цикла с задержкой.
Источники: robotstxt.org, документация requests и selectolax — ссылки в шапке.