Что такое Scrapy и зачем он нужен?
Scrapy – это мощный фреймворк для веб-скрейпинга и краулинга, написанный на Python. Он позволяет автоматизировать извлечение данных с веб-сайтов, обходя ограничения, с которыми сталкиваются обычные HTTP-запросы. Scrapy предоставляет структурированный подход к сбору информации, включая обработку данных, хранение и экспорт. Он широко используется для анализа конкурентов в интернет-маркетинге, мониторинга цен, сбора данных для машинного обучения и многого другого.
Преимущества запуска Scrapy через Python скрипт
Запуск Scrapy через Python-скрипт дает несколько важных преимуществ:
- Гибкость и контроль: Полный контроль над процессом запуска, включая настройку параметров, обработку ошибок и интеграцию с другими библиотеками Python.
- Автоматизация: Возможность автоматизировать запуск пауков по расписанию или в ответ на определенные события.
- Интеграция: Легкая интеграция с другими компонентами вашей системы, такими как базы данных, API и очереди задач (например, Celery).
- Динамическая настройка: Возможность динамически изменять настройки пауков на основе внешних данных или условий.
Необходимые зависимости и установка (Scrapy, Twisted, etc.)
Перед тем как начать, убедитесь, что у вас установлен Python (версия 3.7 или выше). Затем установите Scrapy и его зависимости, используя pip:
pip install scrapy
Scrapy использует библиотеку Twisted для асинхронной обработки. pip обычно устанавливает Twisted вместе со Scrapy. Если возникли проблемы, попробуйте установить Twisted отдельно:
pip install twisted
Создание Scrapy проекта и паука
Создание нового Scrapy проекта из командной строки
Создайте новый Scrapy проект, используя команду:
scrapy startproject my_project
Это создаст директорию my_project со следующей структурой:
my_project/
scrapy.cfg # Файл конфигурации проекта
my_project/
__init__.py
items.py # Определение структуры данных
middlewares.py # Обработчики промежуточных запросов и ответов
pipelines.py # Обработчики для обработки извлеченных данных
settings.py # Настройки проекта
spiders/ # Каталог для пауков
__init__.py
Определение паука: имя, стартовые URL, правила извлечения данных
Создайте файл паука в директории my_project/spiders/. Например, my_spider.py:
import scrapy
class MySpider(scrapy.Spider):
name: str = "my_spider" # Имя паука
start_urls: list[str] = ["https://example.com"] # Стартовые URL
def parse(self, response: scrapy.http.response.html.HtmlResponse):
# Извлечение данных со страницы
title = response.css('title::text').get()
yield {"title": title}
# Пример использования:
# scrapy crawl my_spider
В этом примере:
name– имя паука, которое используется для его запуска.start_urls– список URL, с которых начинается обход.parse– метод, который вызывается для обработки каждого ответа.
Структура проекта Scrapy: spiders, items, pipelines, settings
- spiders: Содержат логику обхода и извлечения данных.
- items: Определяют структуру извлеченных данных.
- pipelines: Обрабатывают извлеченные данные (очистка, валидация, сохранение).
- settings: Содержат настройки проекта (User-Agent, задержки, конвейеры и т.д.).
Запуск Scrapy паука из Python скрипта
Импорт необходимых модулей: scrapy, crawler process
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.settings import Settings
from my_project.spiders.my_spider import MySpider
Настройка CrawlerProcess или CrawlerRunner
CrawlerProcess упрощает запуск пауков в скрипте. CrawlerRunner предлагает более продвинутые возможности, особенно для асинхронного запуска.
process = CrawlerProcess(settings={
'USER_AGENT': 'Mozilla/5.0',
'LOG_LEVEL': 'INFO'
})
Передача настроек и запуск паука программно
process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished
Обработка результатов: экспорт в JSON, CSV и другие форматы
Для экспорта данных можно использовать FeedExporter или реализовать свой конвейер (pipeline). Пример экспорта в JSON:
class JsonWriterPipeline:
def open_spider(self, spider: scrapy.Spider):
self.file = open("output.json", 'w')
def close_spider(self, spider: scrapy.Spider):
self.file.close()
def process_item(self, item: dict, spider: scrapy.Spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
В settings.py добавьте:
ITEM_PIPELINES = {
'my_project.pipelines.JsonWriterPipeline': 300,
}
Продвинутые методы запуска и управления Scrapy
Использование Twisted Reactor для асинхронного запуска
Для асинхронного запуска можно использовать CrawlerRunner и deferLater:
from twisted.internet import reactor, defer
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
configure_logging()
runner = CrawlerRunner()
@defer.inlineCallbacks
def crawl():
yield runner.crawl(MySpider)
reactor.stop()
crawl()
reactor.run()
Запуск нескольких пауков одновременно
process.crawl(MySpider)
process.crawl(AnotherSpider)
process.start()
Интеграция с Celery для распределенных задач
Scrapy можно интегрировать с Celery для распределенного сбора данных. Создайте задачу Celery, которая запускает паука:
from celery import Celery
app = Celery('tasks', broker='redis://localhost:6379/0')
@app.task
def run_spider():
process = CrawlerProcess({
'USER_AGENT': 'Celery Scrapy',
'LOG_LEVEL': 'INFO'
})
process.crawl(MySpider)
process.start()
Обработка ошибок и отладка при запуске Scrapy из Python
Логирование и отслеживание ошибок
Настройте логирование в settings.py:
LOG_LEVEL = 'INFO'
LOG_FILE = 'scrapy.log'
Использование Scrapy Shell для интерактивной отладки
Запустите Scrapy Shell, чтобы интерактивно исследовать страницу:
scrapy shell 'https://example.com'
Распространенные ошибки и способы их решения
- 403 Forbidden: Измените User-Agent в
settings.py. - Twisted Reactor not restartable: Используйте
CrawlerRunnerи асинхронный запуск. - Неправильные селекторы CSS/XPath: Используйте Scrapy Shell для проверки селекторов.