/ / Най-лесният начин да изпълните scrap crawler, за да не блокира скрипта - python, scrapy

Най-лесният начин да стартирате crawler на scrapy, за да не блокира скрипта - python, scrapy

Официалните документи дават много начини за бягане scrapy роботите от кода:

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

Но всички те блокират скрипта, докато не приключи. Какъв е най-лесният начин в Python да стартирате робота в неблокиращ, асинхронен начин?

Отговори:

4 за отговор № 1

Опитах всяко решение, което можех да намеря, и единствената работа за мен беше това, Но за да работи с нея scrapy 1.1rc1 Трябваше да го оправям малко:

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()

Така че сега, когато се обадя crawl_async, тя започва да пълзи и не блокира текущата ми нишка scrapy, така че може би това не е много добро решение, но работи за мен.

Използвах тези версии на библиотеките:

cffi==1.5.0
Scrapy==1.1rc1
Twisted==15.5.0
billiard==3.3.0.22

0 за отговор № 2

Отговорът на Нетимен е правилен. process.start() повиквания reactor.run(), която блокира нишката. Просто не мисля, че е необходимо да се подклас billiard.Process, Макар и слабо документирани, billiard.Process има набор от API, за да извика друга функция асинхронно без подклас.

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()

Имайте предвид, че ако нямате stop_after_crawl=False, може да срещнете ReactorNotRestartable изключение, когато пускате робота за повече от два пъти.