Парсер сайтов на Python для новичка: пошаговый старт

Rate this post

Коротко про головне

Для кого материал: программисты с базовым знанием Python — переменные, циклы, функции, — которые хотят впервые написать парсер и разобраться, что при этом разрешено законом.

Что нужно на старт: Python 3.10 или выше, умение работать с терминалом, базовое понимание того, что такое HTML и CSS-классы.

Реалистичный результат: рабочий скрипт, который скачивает данные с учебного сайта и сохраняет их в CSV-файл. На первый запуск уходит от 30 минут до пары часов.

Главный риск: запустить парсер на сайте, который это явно запрещает, и получить блокировку по IP или, в крайних случаях, юридические претензии.

Легален ли парсинг сайтов

Парсинг — это автоматизированный сбор данных: программа делает HTTP-запросы, получает HTML-код страниц и извлекает из него нужную информацию. Технически это то же самое, что делает браузер, только без графического интерфейса.

Легальность зависит от трёх вещей, и их стоит проверять перед каждым новым проектом.

  • robots.txt. Файл, в котором сайт сообщает, какие страницы нельзя обходить роботам. Найти его просто: добавьте /robots.txt к адресу домена. Это не юридический документ, но игнорировать его — плохая практика. У части сайтов нарушение robots.txt прямо прописано в условиях пользования как основание для блокировки.
  • Пользовательское соглашение (Terms of Service). Большинство крупных платформ явно запрещают автоматический сбор данных. Нарушение ToS может привести к блокировке аккаунта и, в отдельных случаях, к судебным претензиям — такие прецеденты существуют.
  • Содержимое данных. Персональные данные физических лиц — имена, адреса, телефоны, электронная почта — охраняются законодательством в большинстве стран. Парсить контактные базы без согласия людей — это правовой риск вне зависимости от того, что написано в robots.txt.

Безопасная зона для обучения: сайты, которые созданы специально для практики парсинга. Например, quotes.toscrape.com и books.toscrape.com. Их можно парсить без ограничений, они не заблокируют IP и не предъявят претензий. На первом из них и построен пример ниже.

Какие инструменты выбрать

Для первого скрипта не нужен тяжёлый фреймворк. Достаточно двух библиотек — requests и BeautifulSoup4. Ниже сравнение основных инструментов, чтобы понимать, когда что применять.

ИнструментНазначениеПорог входаКогда не хватает
requestsОтправка HTTP-запросов, получение HTMLНизкийСайты с JavaScript-рендерингом
BeautifulSoup4Разбор HTML, поиск по тегам и CSS-классамНизкийКогда нужна высокая скорость на больших объёмах
lxmlБыстрый парсер HTML/XML, работает вместе с BS4НизкийПрактически не бывает
Selenium / PlaywrightУправление реальным браузером, JavaScript-сайтыСреднийКогда важна производительность на тысячах страниц
ScrapyПолноценный фреймворк для крупных проектовВысокийОбычно хватает для любых задач

Для первого скрипта: requests + BeautifulSoup4 + lxml. Selenium и Scrapy — следующий уровень, когда базовый подход перестаёт справляться с конкретной задачей.

Подготовка: устанавливаем окружение

Рекомендую создавать виртуальное окружение для каждого проекта — это изолирует зависимости и не засоряет системный Python. Работает одинаково на любой операционной системе.

# Создаём виртуальное окружение
python -m venv venv

# Активируем на Linux и macOS
source venv/bin/activate

# Активируем на Windows
venv\Scripts\activate

# Устанавливаем нужные библиотеки
pip install requests beautifulsoup4 lxml

После активации перед строкой ввода появится (venv) — это значит, что вы работаете внутри изолированного окружения. Все дальнейшие команды выполняйте в нём.

Первый рабочий парсер: пошаговый разбор

Задача: собрать текст и автора каждой цитаты с первых трёх страниц quotes.toscrape.com и сохранить результат в CSV-файл. Сайт создан именно для такой практики — никаких ограничений нет.

Что происходит внутри скрипта

  1. Отправляем HTTP-запрос. Функция requests.get(url) обращается к серверу и возвращает объект ответа со статус-кодом и HTML-телом страницы. Метод raise_for_status() автоматически бросает исключение, если сервер вернул ошибку 4xx или 5xx.
  2. Передаём HTML парсеру. BeautifulSoup(html, 'lxml') превращает строку с HTML в объект-дерево, по которому можно ходить методами библиотеки.
  3. Ищем нужные элементы. Метод soup.select('.quote') возвращает список всех тегов с CSS-классом quote. Это аналог поиска элементов через DevTools в браузере — принцип тот же.
  4. Извлекаем текст. Метод .get_text(strip=True) вытаскивает текст из тега, убирая лишние пробелы и переносы строк по краям.
  5. Делаем паузу между запросами. time.sleep(1) — задержка в одну секунду. Без неё скрипт отправляет запросы так быстро, что сервер может расценить это как атаку и заблокировать IP.
  6. Сохраняем результат. Стандартный модуль csv записывает данные в файл с заголовками колонок. Кодировка UTF-8 нужна для корректного отображения нелатинских символов.

Полный код

import requests
from bs4 import BeautifulSoup
import csv
import time


def get_page_html(url):
    headers = {
        'User-Agent': (
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
            'AppleWebKit/537.36 (KHTML, like Gecko) '
            'Chrome/120.0.0.0 Safari/537.36'
        )
    }
    response = requests.get(url, headers=headers, timeout=10)
    response.raise_for_status()
    return response.text


def parse_quotes(html):
    soup = BeautifulSoup(html, 'lxml')
    quotes = []
    for item in soup.select('.quote'):
        text = item.select_one('.text').get_text(strip=True)
        author = item.select_one('.author').get_text(strip=True)
        quotes.append({'text': text, 'author': author})
    return quotes


def save_to_csv(quotes, filename='quotes.csv'):
    with open(filename, 'w', newline='', encoding='utf-8') as f:
        writer = csv.DictWriter(f, fieldnames=['text', 'author'])
        writer.writeheader()
        writer.writerows(quotes)
    print(f'Сохранено {len(quotes)} записей в {filename}')


def main():
    base_url = 'http://quotes.toscrape.com'
    all_quotes = []

    for page_num in range(1, 4):  # страницы 1, 2, 3
        url = f'{base_url}/page/{page_num}/'
        print(f'Обрабатываем страницу {page_num}...')

        html = get_page_html(url)
        quotes = parse_quotes(html)

        if not quotes:
            print('Цитаты не найдены, останавливаемся.')
            break

        all_quotes.extend(quotes)
        time.sleep(1)  # пауза — не перегружаем сервер

    save_to_csv(all_quotes)


if __name__ == '__main__':
    main()

Сохраните код в файл parser.py и запустите командой python parser.py. В той же папке появится quotes.csv с тридцатью цитатами — по десять с каждой страницы. Это полностью воспроизводимый пример: он работает без регистрации и дополнительных настроек.

Как сайты защищаются и что с этим делать

Большинство базовых защит рассчитаны на простые автоматические запросы без каких-либо заголовков. Вот что встречается чаще всего.

Проверка User-Agent. Сервер смотрит, какой браузер якобы делает запрос. Если заголовок пустой или содержит python-requests/2.x, запрос могут отклонить. Решение — передавать User-Agent реального браузера в заголовках, как в примере выше. Это не обход защиты, а корректное поведение клиента.

Слишком частые запросы. Сотни запросов в минуту с одного IP — подозрительно. Пауза в 1–3 секунды между запросами снижает нагрузку на сервер и уменьшает вероятность блокировки. Это также проявление уважения к ресурсу, который вы парсите.

JavaScript-рендеринг. Часть сайтов формирует контент на стороне браузера через JavaScript. Библиотека requests получает пустой или неполный HTML, потому что JS ещё не выполнился. Здесь нужен Selenium или Playwright — они запускают настоящий браузер и ждут, пока страница отрисуется. Это следующий шаг после освоения базового подхода.

Капча. Появление капчи — явный сигнал, что автоматический доступ нежелателен. Технически её можно обойти, но это входит в серую зону с точки зрения ToS большинства сервисов. Лучше поискать официальный API или другой источник данных.

Кому парсинг на Python не подойдёт

Парсинг — инструмент с реальными ограничениями, о которых лучше знать заранее.

  • Нужны данные в промышленных масштабах и в реальном времени. Парсинг HTML хрупок: любое изменение структуры страницы ломает скрипт. Для бизнес-задач, где счёт идёт на миллионы записей, обычно нужна профессиональная инфраструктура или готовые API.
  • Сайт явно запрещает парсинг в Terms of Service. Риск блокировки и потенциальных юридических претензий. Не стоит строить проект на источнике, который может заблокировать вас в любой момент.
  • Нужны персональные данные людей. Сбор имён, адресов, телефонов, данных из социальных сетей без согласия — нарушение законодательства о персональных данных в большинстве юрисдикций, вне зависимости от технической возможности это сделать.
  • Нет готовности разбираться с HTML. Парсинг требует умения открыть DevTools в браузере, найти нужный элемент, определить его CSS-класс или XPath-путь. Без этого навыка даже простой скрипт написать не получится.

Что изучить дальше

Если первый скрипт заработал и задача вам интересна, логичный путь развития выглядит так.

  1. XPath. Альтернативный способ поиска элементов — часто точнее CSS-селекторов для сложных и глубоко вложенных структур. Поддерживается в lxml напрямую.
  2. Selenium или Playwright. Для сайтов, где контент генерируется JavaScript. Playwright в среднем проще в настройке и быстрее в работе, чем Selenium, — можно начинать с него.
  3. Scrapy. Фреймворк для систематического обхода сайтов с очередями запросов, пайплайнами обработки и встроенной обработкой ошибок. Подходит, когда нужно обойти тысячи страниц.
  4. Официальные API. Многие сайты предоставляют API для доступа к данным. Это надёжнее и чище парсинга HTML: структура ответа не меняется без предупреждения. Всегда проверяйте наличие API перед тем, как писать парсер.

Парсинг — полезный инструмент для автоматизации и исследований, но не универсальный. Чем лучше вы понимаете его ограничения с самого начала, тем меньше времени уходит впоследствии на переработку скриптов, которые «сломались» после очередного редизайна сайта.

Частые вопросы

Нужно ли разрешение владельца сайта, чтобы его парсить?

Прямого разрешения для парсинга открытых данных обычно не требуется, но нужно соблюдать три условия: не нарушать директивы robots.txt, не противоречить пользовательскому соглашению сайта и не собирать персональные данные без правовых оснований. Перед парсингом коммерческого ресурса стоит проверить его Terms of Service — там часто прямо прописан запрет на автоматический сбор данных.

Что делать, если сайт заблокировал мой IP-адрес?

Чаще всего причина — слишком частые запросы без пауз. Добавьте задержку между запросами (1–3 секунды), передавайте корректный заголовок User-Agent и убедитесь, что не нарушаете правила сайта. Если блокировка сохраняется, это, как правило, сигнал, что автоматический доступ нежелателен: поищите официальный API или другой источник данных.

Можно ли парсить сайты, где контент загружается через JavaScript?

Да, но библиотека requests для этого не подходит — она получает исходный HTML до выполнения JS, поэтому динамический контент будет недоступен. Для таких сайтов нужен Selenium или Playwright: они запускают настоящий браузер и ждут, пока JavaScript отрисует страницу. Это следующий шаг после освоения базового парсинга.

Зачем указывать User-Agent в заголовках запроса?

User-Agent — это строка, которая сообщает серверу, какое приложение делает запрос. По умолчанию библиотека requests отправляет значение вида python-requests/2.x, и многие серверы автоматически блокируют такие запросы как ботовые. Указание User-Agent реального браузера снижает вероятность отказа, хотя и не гарантирует доступ на все сайты.

Чем парсинг отличается от использования API?

API — это официальный интерфейс, который сайт предоставляет для структурированного доступа к данным. Он стабилен, задокументирован и не ломается при редизайне страниц. Парсинг HTML — обходной путь, когда API нет или он платный. Парсер хрупок: любое изменение вёрстки может его сломать, и его придётся переписывать. Всегда проверяйте наличие API перед тем, как браться за парсер.

Зарабатывай больше с нашим комьюнити
Приватные связки по арбитражу, обзоры новых ИИ-инструментов и аналитика крипторынка — всё это мы публикуем в нашем Telegram-канале раньше, чем на сайте.
Присоединиться к Telegram
NJ

Nova J.

Lead Architect

Архитектор профитных систем и системный аналитик. Я не верю в удачу — я верю в код, математику и агрессивную автоматизацию. Лично контролирую каждый пост на этом ресурсе.

Узнать больше о моей системе

Оставьте комментарий

[ PROTOCOL: ZERO LUCK ]

Мы презираем случайность. На этом ресурсе нет, не было и не будет рекламы онлайн-казино, ставок на спорт, бинарных опционов и серых схем. Азарт — это налог на отсутствие системного мышления. Мы верим в математику, нейросети, код и жесткую дисциплину. Если вы ищете «кнопку бабло» и надеетесь на удачу — закройте этот сайт. Наши частоты не совпадают.