Я собираю ежедневные данные с помощью Scrapy, используя двухэтапное сканирование. На первом этапе создается список URL-адресов со страницы индекса, а на втором этапе HTML-код для каждого URL-адреса в списке записывается в тему Kafka.
Хотя два компонента обхода связаны, я бы хотел, чтобы они были независимыми: url_generator
запускался как запланированная задача один раз в день, а page_requester
запускался постоянно, обрабатывая URL-адреса, когда они доступны. Ради «вежливости» я настрою DOWNLOAD_DELAY
так, чтобы краулер завершал работу в течение 24 часов, но при этом загружал сайт минимально.
Я создал класс CrawlerRunner
, в котором есть функции для генерации URL и извлечения HTML:
from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy import log, signals
from scrapy_somesite.spiders.create_urls_spider import CreateSomeSiteUrlList
from scrapy_somesite.spiders.crawl_urls_spider import SomeSiteRetrievePages
from scrapy.utils.project import get_project_settings
import os
import sys
class CrawlerRunner:
def __init__(self):
sys.path.append(os.path.join(os.path.curdir, "crawl/somesite"))
os.environ['SCRAPY_SETTINGS_MODULE'] = 'scrapy_somesite.settings'
self.settings = get_project_settings()
log.start()
def create_urls(self):
spider = CreateSomeSiteUrlList()
crawler_create_urls = Crawler(self.settings)
crawler_create_urls.signals.connect(reactor.stop, signal=signals.spider_closed)
crawler_create_urls.configure()
crawler_create_urls.crawl(spider)
crawler_create_urls.start()
reactor.run()
def crawl_urls(self):
spider = SomeSiteRetrievePages()
crawler_crawl_urls = Crawler(self.settings)
crawler_crawl_urls.signals.connect(reactor.stop, signal=signals.spider_closed)
crawler_crawl_urls.configure()
crawler_crawl_urls.crawl(spider)
crawler_crawl_urls.start()
reactor.run()
Когда я создаю экземпляр класса, я могу успешно выполнить любую функцию по отдельности, но, к сожалению, я не могу выполнить их вместе:
from crawl.somesite import crawler_runner
cr = crawler_runner.CrawlerRunner()
cr.create_urls()
cr.crawl_urls()
Второй вызов функции генерирует twisted.internet.error.ReactorNotRestartable
при попытке выполнить reactor.run()
в функции crawl_urls
.
Мне интересно, есть ли простое решение для этого кода (например, какой-то способ запуска двух отдельных реакторов Twisted) или есть ли лучший способ структурировать этот проект.