Ich sammle tägliche Daten mit Scrapy unter Verwendung eines zweistufigen Crawls. Die erste Stufe erzeugt eine Liste von URLs von einer Indexseite und die zweite Stufe schreibt das HTML für jede der URLs in der Liste zu einem Kafka-Thema.Scrapy `ReactorNotRestartable`: Eine Klasse, um zwei (oder mehr) Spider auszuführen
Obwohl die beiden Komponenten des Crawl verwendet sind, würde Ich mag sie, unabhängig zu sein: die url_generator
würde als eine geplante Aufgabe ausgeführt werden einmal am Tag, und die page_requester
liefe ständig, Verarbeitung URL, wenn verfügbar. Um "höflich" zu sein, passe ich die DOWNLOAD_DELAY
so an, dass der Crawler gut innerhalb der 24 Stunden endet, aber die Seite nur minimal belastet.
Ich habe eine CrawlerRunner
Klasse, die Funktionen der URL und rufen Sie die HTML zu erzeugen hat:
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()
Wenn ich die Klasse instanziiert, ich bin in der Lage erfolgreich entweder Funktion auf eigene auszuführen, aber leider ich bin nicht in der Lage, sie zusammenführen:
from crawl.somesite import crawler_runner
cr = crawler_runner.CrawlerRunner()
cr.create_urls()
cr.crawl_urls()
der zweite Funktionsaufruf ein twisted.internet.error.ReactorNotRestartable
erzeugt, wenn er versucht reactor.run()
in der crawl_urls
Funktion auszuführen.
Ich frage mich, ob es eine einfache Lösung für diesen Code gibt (z. B. eine Möglichkeit, zwei getrennte Twisted-Reaktoren zu betreiben), oder ob es eine bessere Möglichkeit gibt, dieses Projekt zu strukturieren.
Gibt es eine Möglichkeit, Crawler zum Reaktor hinzuzufügen, während er läuft? Wie kann dies getan werden reactor.run() blockiert? –
Danke für den Kredit :) –