CoderCastrov logo
CoderCastrov
Парсер

Как запустить Scrapy пауки в вашей программе Python

Как запустить Scrapy пауки в вашей программе Python
просмотров
5 мин чтение
#Парсер

Узнайте, как запустить Scrapy пауки программно

Ранее мы рассмотрели, как создать проект по парсингу с помощью Scrapy и MongoDB. Обычно вы запускаете пауков с помощью команды scrapy crawl. И вы не запускаете их только один раз, а планируете их запуск регулярно, чтобы постоянно получать новые данные. Парсинговые задания можно запланировать с помощью простых CRON-заданий или более сложных программ, таких как Airflow.

Однако иногда вы можете не хотеть планировать запуск парсинговых заданий пассивно. Вместо этого вы хотите запускать парсинговые задания программно на основе некоторых условий. Например, вы можете хотеть запускать парсинговые задания на основе ввода пользователя.

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


Мы будем использовать паука, представленного в предыдущей статье, для демонстрации в этой статье. Для демонстрации в этой статье будет создан новый паук AuthorSpider, который будет использоваться для демонстрации того, как запустить несколько пауков одновременно с помощью API Scrapy. Кроме того, полученные данные не сохраняются в MongoDB для простоты. Вы можете добавить конвейер для MongoDB, если хотите.


Используйте subprocess для запуска пауков.

Мы можем запустить команду scrapy crawl как команду оболочки. Рекомендуется использовать модуль subprocess вместо функции os.system() для запуска команд оболочки из-за безопасности и других удобных функций модуля subprocess.

Если вы хотите запустить пауков синхронно и дождаться результатов, вы можете использовать subprocess.run():

Работа должна завершиться без вывода, потому что мы перенаправили журналы парсинга в /tmp/scrapy.log. Если вы хотите проверить журналы в скрипте, вы можете закомментировать следующую строку в settings.py:

LOG_FILE = "/tmp/scrapy.log"

Поскольку Scrapy перенаправляет все журналы на стандартную ошибку (STDERR), нам нужно только перенаправить STDERR:


Если вы хотите запустить пауки асинхронно, вы можете использовать subprocess.Popen():

proc.poll() возвращает None, если задание все еще выполняется, и код завершения, если задание завершено. Для получения дополнительной информации о subprocess.run() и subprocess.Popen() обратитесь к этому сообщению.


Используйте **CrawlerProcess** для запуска нескольких пауков в одном процессе.

Выше мы рассмотрели, как использовать модуль subprocess для запуска пауков Scrapy в вашей программе. Использование subprocess - это наивный способ запуска пауков в вашей программе. Он работает, когда вы хотите запустить только одного паука в одном процессе. Если вы хотите запустить несколько пауков в одном процессе или хотите получить и использовать полученные элементы непосредственно в вашей программе, вам потребуется использовать внутренний API Scrapy.

Давайте сначала покажем код для использования внутреннего API Scrapy для запуска пауков, а затем объясним интересные моменты:

Если вы новичок в Scrapy, код выше может быть сложным для понимания. Не волнуйтесь, мы объясним все технические детали, которые сделают его намного проще для вас понять:

  • Мы используем функцию get_project_settings() для получения настроек проекта на основе настроек в модуле settings.py. Возвращаемые настройки - это экземпляр класса scrapy.settings.Settings и ведут себя очень похоже на словарь.
  • Мы используем класс CrawlerProcess для запуска нескольких пауков Scrapy одновременно в одном процессе. Нам нужно создать экземпляр CrawlerProcess с настройками проекта.
  • Если мы хотим иметь пользовательские настройки для паука, нам нужно создать экземпляр Crawler для паука. Crawler - это очень абстрактное и очень важное понятие в Scrapy. Вы столкнетесь с ним, когда захотите иметь расширенные конфигурации для Scrapy. Особенно, когда вы используете метод класса from_crawler(). Объект Crawler предоставляет доступ ко всем основным компонентам Scrapy, особенно к настройкам, и это единственный способ для расширений получить к ним доступ и присоединить свою функциональность к Scrapy. Обратите внимание, что вам нужно наследовать настройки для проекта, иначе настройки проекта не будут действовать. В этом примере, если вы не используете синтаксис **settings, журналы будут в режиме DEBUG и будут выводиться на экран, а не отправляться в файл журнала /tmp/scrapy.log. Вы можете проверить это самостоятельно.
  • Мы можем запустить/пропарсить паука с помощью метода crawl() экземпляра CrawlerProcess. В частности, мы можем передать пары ключ/значение этому методу, и они будут вести себя как пользовательские свойства, как было представлено в предыдущей статье для основ Scrapy. Для паука quotes мы хотим только парсить цитаты с тегом love.
  • Мы можем парсить несколько пауков/парсеров в одном процессе, и они не начнут выполняться, пока не будет вызван метод start().

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


Используйте сигналы, чтобы получить полученные элементы непосредственно в вашей программе.

Обычно мы сохраняем полученные элементы в базе данных, либо в реляционной базе данных, такой как MySQL, либо в базе данных NoSQL, такой как MongoDB. Однако иногда мы хотим получить доступ к полученным элементам непосредственно в программе и как-то их обработать. В этом случае мы можем использовать сигналы экземпляра Crawl для паука, которые используются для уведомления о наступлении определенных событий:

Обратите внимание, что сигналы добавляются через метод Crawler.signals.connect(). В приведенном выше коде мы связываем quote_cralwer с тремя сигналами, а именно когда паук запускается (signals.spider_opened), когда получен элемент (signals.item_scraped) и когда паук закрывается (signals.spider_closed). Каждый сигнал связан с функцией, которая будет вызвана при срабатывании сигнала. Эта функция работает как функция обратного вызова в JavaScript.

Сигналы могут предоставлять несколько аргументов для подключенной функции. Вам не нужно использовать все из них, и вы можете использовать только те, которые необходимы. Например, для подключенных функций для signals.spider_opened и signals.spider_closed мы используем только аргумент spider, который является пауком, вызывающим сигналы.

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


В этой статье мы рассмотрели два способа запуска пауков Scrapy в вашей программе: с помощью модуля subprocess и с помощью класса CrawlerProcess внутреннего API Scrapy. Использование модуля subprocess для запуска команды scrapy crawl очень просто. Однако вы не можете запускать несколько пауков одновременно в одном процессе, и вы не можете получить доступ к полученным элементам непосредственно в вашей программе. Эти расширенные функции можно реализовать с помощью класса CrawlerProcess внутреннего API Scrapy. Если вы являетесь опытным пользователем Scrapy и хотите иметь еще больше контроля над тем, как пауки будут запускаться в вашей программе, вы можете использовать класс [CrawlerRunner](https://docs.scrapy.org/en/latest/topics/api.html#scrapy.crawler.CrawlerRunner) непосредственно, который используется классом CrawlerProcess внутри.


Связанные статьи: