我在一个Scrapy项目中有两只蜘蛛。 Spider1抓取页面列表或整个网站并分析内容。 Spider2使用Splash在谷歌上获取URL并将该列表传递给Spider1。
因此,Spider1可以抓取并分析内容,并且可以在不被Spider2调用的情况下使用
# coding: utf8
from scrapy.spiders import CrawlSpider
import scrapy
class Spider1(scrapy.Spider):
name = "spider1"
tokens = []
query = ''
def __init__(self, *args, **kwargs):
'''
This spider works with two modes,
if only one URL it crawls the entire website,
if a list of URLs only analyze the page
'''
super(Spider1, self).__init__(*args, **kwargs)
start_url = kwargs.get('start_url') or ''
start_urls = kwargs.get('start_urls') or []
query = kwargs.get('q') or ''
if google_query != '':
self.query = query
if start_url != '':
self.start_urls = [start_url]
if len(start_urls) > 0:
self.start_urls = start_urls
def parse(self, response):
'''
Analyze and store data
'''
if len(self.start_urls) == 1:
for next_page in response.css('a::attr("href")'):
yield response.follow(next_page, self.parse)
def closed(self, reason):
'''
Finalize crawl
'''
Spider2的代码
# coding: utf8
import scrapy
from scrapy_splash import SplashRequest
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
class Spider2(scrapy.Spider):
name = "spider2"
urls = []
page = 0
def __init__(self, *args, **kwargs):
super(Spider2, self).__init__(*args, **kwargs)
self.query = kwargs.get('q')
self.url = kwargs.get('url')
self.start_urls = ['https://www.google.com/search?q=' + self.query]
def start_requests(self):
splash_args = {
'wait:': 2,
}
for url in self.start_urls:
splash_args = {
'wait:': 1,
}
yield SplashRequest(url, self.parse, args=splash_args)
def parse(self, response):
'''
Extract URLs to self.urls
'''
self.page += 1
def closed(self, reason):
process = CrawlerProcess(get_project_settings())
for url in self.urls:
print(url)
if len(self.urls) > 0:
process.crawl('lexi', start_urls=self.urls, q=self.query)
process.start(False)
运行Spider2时出现此错误:twisted.internet.error.ReactorAlreadyRunning
并且在没有URL列表的情况下调用Spider1。
我按照Scrapy文档的建议尝试使用CrawlRunner,但它也是同样的问题。
我尝试在解析方法中使用CrawlProcess,它"工作"但是,我仍然有错误信息。在解析方法中使用CrawlRunner时,它不起作用。
答案 0 :(得分:2)
目前,如果您正在使用scrapy crawl
命令(参见https://github.com/scrapy/scrapy/issues/1226),则无法从其他蜘蛛启动蜘蛛。如果您自己编写启动脚本,则可以从蜘蛛启动蜘蛛 - 诀窍是使用相同的CrawlerProcess / CrawlerRunner实例。
我不这样做,但你再次与框架作斗争。支持这个用例很不错,但现在并不支持它。
更简单的方法是重写代码以使用单个Spider类,或创建脚本(bash,Makefile,luigi / airflow,如果你想要花哨),运行scrapy crawl spider1 -o items.jl
后跟{{ 1}};第二个蜘蛛可以读取第一个蜘蛛创建的项目并相应地生成scrapy crawl spider2
。
FTR:结合SplashRequests和常规scrapy.Requests完全支持(它应该可以正常工作),你不必为它们创建单独的蜘蛛。