Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка

Как парсить данные на Python: BeautifulSoup и Scrapy

На Python можно написать парсер — программу для автоматического сбора информации с сайтов. Рассказываем, как создать простой парсер на BeautifulSoup и Scrapy, и разбираемся в этических аспектах парсинга и лучших практики для эффективного сбора данных.

627 открытий4К показов
Как парсить данные на Python: BeautifulSoup и Scrapy

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

Чтобы использовать эти инструменты, вспомним основы HTML, DOM-дерева и принципы работы динамических страниц.

Основные понятия парсинга данных

HTML-документ — это текстовый файл с расширением .html. Он содержит набор элементов для отображения страницы в браузере.

Структура HTML-документа состоит из двух частей: заголовка (head) и тела (body). Весь документ обрамляется корневым тегом html.

			<!DOCTYPE html>
<html>
    <head>
        ...
    </head>
    <body>
        ...
    </body>
</html>
		

Заголовок содержит метаданные, стили, скрипты, заголовок страницы. В теле документа находятся теги и основной контент, который отображается в окне браузера.

			<!DOCTYPE html>
<html>
<head>
    <title>Страница с тегами</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <nav>
            <a href="#">Главная</a>
            <a href="#">О нас</a>
        </nav>
    </header>
    <main>
        <h1>Заголовок статьи</h1>
        <p>Первый абзац текста</p>
        <p>Второй абзац текста</p>  
        <div class="clicker">
            <img src="image.jpg" alt="Картинка">
            <button onclick="alert('Клик!')">Нажми меня</button>
        </div>
    </main>
    <footer>
        <p>Контакты разработчика</p>
    </footer>
</body>
</html>
		

DOM-дерево — это представление HTML-документа в виде древовидной структуры объектов. Каждый элемент HTML становится узлом этого дерева. Благодаря DOM можно взаимодействовать с элементами страницы через JavaScript:

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

Корневой элемент DOM-дерева — тег html. От него идет разветвление на head и body — его прямых потомков. Остальные элементы образуют более глубокие уровни вложенности.

Тут можно посмотреть, как выглядит DOM-дерево для определенного фрагмента кода.

Статические страницы содержат фиксированный HTML. Его код не меняется после загрузки. По этой причине статические страницы проще парсить. Достаточно отправить HTTP-запрос и будет получен весь HTML-документ, из которого можно извлечь целевые теги. С этой задачей успешно справляются любые библиотеки для парсинга: Requests, BeautifulSoup, Urllib3 и другие.

Динамические страницы формируют контент с помощью JavaScript после загрузки основного HTML. Контент может подгружаться через API, изменяться при взаимодействии пользователя или обновляться автоматически.

Простой HTTP-запрос не парсит динамически загруженные сайты. Для этого нужны инструменты, эмулирующие работу браузера. Например, Selenium WebDriver. Он запускает браузер, выполняет JavaScript-код и парсит финальное DOM-дерево с динамическим контентом.

Этические и юридические аспекты парсинга данных

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

Что можно делать:

  • Собирать информацию, которая находится в открытом доступе.
  • Парсить данные, не нагружая сайт и не мешая его работе.

Чего нельзя делать:

  • Воровать закрытую информацию компаний.
  • Собирать личные данные пользователей (телефоны, адреса, паспортные данные).
  • Намеренно вредить работе сайта большим количеством запросов.

Перед сбором данных задавайте себе простой вопрос: «Мне понравится, если кто-то соберет эту информацию обо мне?» Подумайте также о том, приносит ли ваш парсинг пользу другим людям или вы делаете это только ради собственной выгоды.

Если закон разрешает какие-то действия, это не значит, что их правильно делать с моральной точки зрения. Например, технически возможно собрать все комментарии человека в соцсетях, но будет ли это этично по отношению к нему?

Cобирайте только те данные, которые действительно нужны для вашей задачи. Не нужно сохранять личную информацию людей просто потому, что вы можете это сделать.

Если собираете данные временно, например, чтобы найти фальшивые отзывы на Яндекс Картах, а потом сразу удаляете личную информацию — это более приемлемо, чем создание постоянной базы данных о людях для продажи рекламодателям.

BeautifulSoup: простой и удобный инструмент для парсинга

BeautifulSoup — это библиотека Python для извлечения данных из HTML и XML. Следуйте пошаговому руководству, чтобы установить BeautifulSoup.

Откройте терминал и выполните команду:

			pip install beautifulsoup4
		

Установите парсер lxml:

			pip install lxml
		

Также понадобится библиотека requests для выполнения HTTP-запросов:

			pip install requests
		

Самый простой парсер на BeautifulSoup:

			import requests
from bs4 import BeautifulSoup

url = 'https://example.com'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
		

Основные функции и методы библиотеки

Найти первый абзац:

			first_paragraph = soup.find('p')
		

Найти все абзацы:

			all_paragraphs = soup.find_all('p')
		

Один элемент с классом 'content':

			content = soup.find(class_='content')
		

Все элементы с классом 'content':

			all_content = soup.find_all(class_='content')
		

Поиск ссылки по href:

			link = soup.find('a', href='https://example.com')
		

Поиск по нескольким атрибутам:

			element = soup.find('div', attrs={'id': 'main', 'class': 'content'})
		

Найти все абзацы с определенным классом:

			paragraphs = soup.find_all('p', class_='text-block')
		

Найти все ссылки внутри div с определенным id:

			links = soup.find('div', id='menu').find_all('a')
		

Плюсы BeautifulSoup

  • Простой синтаксис, поэтому библиотекой пользуются даже начинающие разработчики. 
  • Гибкий поиск элементов ищет теги по имени, классу, id, атрибутам. Можно комбинировать условия поиска и использовать CSS-селекторы.
  • Автоматическое исправление невалидного HTML. BeautifulSoup пытается восстановить неправильную структуру документа, что полезно при работе с некачественной версткой.
  • Низкие требования к ресурсам компьютера по сравнению с браузерными решениями вроде Selenium.

Недостатки BeautifulSoup

  • Нет поддержки JavaScript. Библиотека работает только со статическим HTML и не может обрабатывать динамически загружаемый контент.
  • Ограниченная производительность при работе с большими документами. Для парсинга крупных файлов лучше использовать потоковые парсеры.
  • Отсутствие встроенной поддержки асинхронности. Для параллельной обработки нескольких страниц требуются дополнительные библиотеки asyncio и aiohttp
BeautifulSoup не подходит для парсинга сайтов с динамической загрузкой контента, высоконагруженных проектов. Для этих целей выбирайте фреймворк Scrapy.

Scrapy: мощный фреймворк для парсинга больших объемов данных

Scrapy — это фреймворк для парсинга сайтов, построенный на асинхронной архитектуре. Рассмотрим его основные компоненты.

Пауки (Spiders) — это классы, которые определяют как парсить конкретный сайт. В пауке указываются начальные URL-адреса, правила извлечения данных и переходов между страницами. Паук обходит страницы сайта и извлекает информацию с помощью CSS-селекторов или XPath-выражений.

Элементы (Items) — это контейнеры для хранения извлеченных данных. Они похожи на словари Python, но предоставляют дополнительную валидацию полей. Items определяют структуру данных, которые будут собраны пауком.

Каналы обработки (Pipelines) — это компоненты для обработки извлеченных данных. Каждый элемент проходит через цепочку pipeline-обработчиков. В pipeline можно выполнять очистку данных, удалять дубликаты, сохранять информацию в базу данных.

Парсинг HTML на Scrapy выглядит так:

  1. Паук отправляет запрос к сайту.
  2. Получает ответ и извлекает данные.
  3. Создает элементы с данными.
  4. Передает элементы в pipeline.
  5. Pipeline обрабатывает и сохраняет данные.

Установка и настройка Scrapy

Откройте терминал и выполните команду::

			pip install scrapy
		

Создайте новый проект:

			scrapy startproject имя_проекта
		

Эта команда создаст структуру каталогов — файлы настроек и шаблоны пауков.

Файл settings.py содержит основные настройки проекта. Базовые параметры, которые требуют настройки:

  • USER_AGENT = 'Mozilla/5.0...' (идентификация парсера).
  • ROBOTSTXT_OBEY = True (соблюдение правил robots.txt).
  • CONCURRENT_REQUESTS = 16 (количество одновременных запросов).
  • DOWNLOAD_DELAY = 1 (задержка между запросами).
  • COOKIES_ENABLED = False (использование cookies).

Для создания нового паука используйте команду:

			scrapy genspider имя_паука domain.com
		

Пример простого паука:

			import scrapy

class ExampleSpider(scrapy.Spider):
name = 'example'
allowed_domains = ['ваш_домен.com']
start_urls = ['http://ваш_домен.com']

def parse(self, response):
    title = response.css('h1::text').get()
    yield {'title': title}
		

Запуск паука выполняется командой:

			scrapy crawl имя_паука
		

Для сохранения результатов в файл:

			scrapy crawl имя_паука -o результат.json
		

Для обработки данных перед сохранением используется pipelines.py:

			class ExamplePipeline:
def process_item(self, item, spider):
item['title'] = item['title'].strip()
return item
		

Активация pipeline происходит в settings.py:

			ITEM_PIPELINES = {
'название_проекта.pipelines.ExamplePipeline': 300
}
		

Плюсы Scrapy

  • Обрабатывает запросы асинхронно.
  • Автоматически управляет порядком обработки URL и перераспределяет нагрузку.
  • Легко добавлять прокси-серверы, ротацию User-Agent, обработку ошибок.
  • Встроенная поддержка экспорта в JSON, CSV, XML.

Недостатки Scrapy

  • Сложность отладки асинхронного кода.
  • Ограниченная поддержка JavaScript.

Сравнение BeautifulSoup и Scrapy

Выбор инструмента зависит от масштаба задачи. Для извлечения данных с нескольких страниц достаточно BeautifulSoup. Для создания поискового робота или регулярного парсинга больших объемов данных оптимальным выбором будет Scrapy.

Парсинг на Python BeautifulSoup лучше подходит для:

  • Парсинга отдельных страниц.
  • Небольших скриптов.
  • Интеграции в существующие проекты.

BeautifulSoup дает разработчику полную свободу в организации кода и выборе дополнительных инструментов, но ограничивается только базовыми функциями извлечения данных.

Scrapy эффективнее для:

  • Парсинга интернет-магазинов с тысячами товаров. 
  • Регулярного мониторинга цен конкурентов. 
  • Полноценных парсинг-проектов со сложной логикой обработки.

Фреймворк используют для масштабного сбора данных. Python Scrapy имеет встроенные механизмы для работы с прокси, управления cookies, организации очередей запросов и конвейерной обработки данных.

Продвинутые техники парсинга

Динамически загружаемый контент — это проблема при парсинге. Чтобы выгрузить целевой контент со страницы, нужно имитировать действия пользователя. Для этого часто используют Selenium. Библиотека управляет браузером — загружает страницы, выполняет JavaScript и получает доступ к DOM после его изменения.

При обработке динамического контента учитывайте задержки. JavaScript выполняется асинхронно, поэтому Selenium должен дождаться полной загрузки элементов, прежде чем пытаться с ними взаимодействовать.

Пример ожидания:

			# Ожидание элемента с id="dynamic_content" (до 10 секунд)
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "dynamic_content"))
)
		

Еще можно использовать time.sleep, но это менее эффективно — задержка фиксирована и не зависит от скорости загрузки страницы.

Если контент загружается через AJAX, можно использовать execute_script для проверки состояния загрузки. Например, можно проверить значение переменной JavaScript, которая отслеживает состояние загрузки.

Когда контент загружается поэтапно, приходится комбинировать ожидания, execute_script и циклы для обработки всех частей динамического контента.

Работа с API

Многие сайты предоставляют API для получения данных. Это предпочтительный способ парсинга на Python. Сбор данных через API:

  • не нагружает сервер излишними запросами;
  • предоставляет данные в структурированном виде;
  • обычно имеет официальную документацию.

Для работы с API в Python есть библиотека requests.

Большинство API имеют ограничения на количество запросов. Для их соблюдения нужно добавлять задержки.

Использование прокси и обход блокировок

Прокси помогают обходить блокировки, которые сайты применяют для защиты от парсинга — не всем нравится, когда их контент собирают в базы. Если сайт блокирует ваш IP-адрес из-за частых запросов, использование прокси позволит продолжить работу под другим IP.

В Python для работы с прокси нужно импортировать библиотеки requests и urllib. Достаточно указать адрес прокси в параметрах запроса.

Пример использования прокси с requests:

			proxies = {
'http': 'http://user:password@yourproxy.com:port',
'https': 'https://user:password@yourproxy.com:port'
}
response = requests.get('https://example.com', proxies=proxies)
		

Ваш парсер останется незамеченным, если выполнять подмену User-Agent, ставить задержки между запросами, настроить автоматическое распознавание капчи.

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

Рекомендации по парсингу данных

Структура проекта способствует его поддержке, расширению и повторному использованию. Делите большие парсеры на отдельные компоненты по функциональности — один модуль для авторизации, другой для навигации по страницам, третий для извлечения тегов.

Файлы, полученные при парсинге, также требуют правильной организации хранения и обработки. Выбор формата зависит от объема и структуры данных:

  • JSON подходит для иерархических данных и удобен для дальнейшей обработки в Python. 
  • CSV эффективен для табличных данных и открывается в Excel.

Для больших объемов информации используйте БД — SQLite для небольших проектов, PostgreSQL для масштабных. Создавайте промежуточное хранилище перед финальной записью — это защитит от потери информации при сбоях.

Задержки между запросами — обязательный элемент парсинга. Базовая рекомендация — выдерживайте паузу 1-3 секунды между запросами. Для высоконагруженных сайтов увеличивайте интервал до 5-10 секунд.

Дополнительные советы по созданию парсера:

  • Реализуйте систему логирования для отслеживания ошибок и прогресса. 
  • Обрабатывайте сетевые ошибки, делайте повторные попытки с экспоненциальной выдержкой.
  • Используйте прокси, User Agent для распределения нагрузки и маскировки запросов. 
  • Проверяйте работоспособность парсера перед запуском, так как структура сайтов может меняться.
Следите за новыми постами
Следите за новыми постами по любимым темам
627 открытий4К показов