Die offiziellen Dokumente viele Wege zum Laufen geben scrapy
Crawler vom Code:
import scrapy
from scrapy.crawler import CrawlerProcess
class MySpider(scrapy.Spider):
# Your spider definition
...
process = CrawlerProcess({
"USER_AGENT": "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
})
process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished
Aber alle blockieren das Skript, bis das Crawlen beendet ist. Was ist der einfachste Weg in Python, den Crawler asynchron auf blockierende Weise auszuführen?
Antworten:
4 für die Antwort № 1Ich habe jede Lösung ausprobiert, die ich finden konnte, und die einzige, die für mich funktionierte, war Dies. Aber damit es funktioniert scrapy 1.1rc1
Ich musste es ein bisschen anpassen:
from scrapy.crawler import Crawler
from scrapy import signals
from scrapy.utils.project import get_project_settings
from twisted.internet import reactor
from billiard import Process
class CrawlerScript(Process):
def __init__(self, spider):
Process.__init__(self)
settings = get_project_settings()
self.crawler = Crawler(spider.__class__, settings)
self.crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
self.spider = spider
def run(self):
self.crawler.crawl(self.spider)
reactor.run()
def crawl_async():
spider = MySpider()
crawler = CrawlerScript(spider)
crawler.start()
crawler.join()
Also jetzt, wenn ich anrufe crawl_async
, es beginnt zu kriechen und blockiert meinen aktuellen Thread nicht. Ich bin absolut neu bei scrapy
Vielleicht ist das keine sehr gute Lösung, aber es hat für mich funktioniert.
Ich habe diese Versionen der Bibliotheken verwendet:
cffi==1.5.0
Scrapy==1.1rc1
Twisted==15.5.0
billiard==3.3.0.22
0 für die Antwort № 2
Die Antwort von Netimen ist richtig. process.start()
Anrufe reactor.run()
, der den Thread blockiert. Nur glaube ich nicht, dass es notwendig ist, eine Unterklasse zu erstellen billiard.Process
. Obwohl schlecht dokumentiert, billiard.Process
hat eine Reihe von APIs, um eine andere Funktion asynchron ohne Unterklassifizierung aufzurufen.
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from billiard import Process
crawler = CrawlerProcess(get_project_settings())
process = Process(target=crawler.start, stop_after_crawl=False)
def crawl(*args, **kwargs):
crawler.crawl(*args, **kwargs)
process.start()
Beachten Sie, wenn Sie nicht haben stop_after_crawl=False
, können Sie stoßen ReactorNotRestartable
Ausnahme, wenn Sie den Crawler mehr als zweimal ausführen.