Python 刮痧蜘蛛不';t接收到卡盘空闲信号

Python 刮痧蜘蛛不';t接收到卡盘空闲信号,python,web-scraping,scrapy,web-crawler,scrapy-spider,Python,Web Scraping,Scrapy,Web Crawler,Scrapy Spider,我有一个spider,它使用meta处理链中的请求,以生成包含来自多个请求的数据的项。 我用来生成请求的方法是在第一次调用parse函数时启动所有请求,但是,如果我有太多的链接要请求,那么并不是所有的请求都被安排好了,最终我也没有得到我所需要的一切 为了解决这个问题,我尝试让爬行器每次请求5个产品,在爬行器空闲时再次请求(通过连接来自爬虫的中的信号)。 问题是,由于我的代码是现在,spider_idle没有运行请求功能,因此spider会立即关闭。就好像蜘蛛没有闲着 下面是一些代码: class

我有一个spider,它使用
meta
处理链中的请求,以生成包含来自多个请求的数据的项。 我用来生成请求的方法是在第一次调用parse函数时启动所有请求,但是,如果我有太多的链接要请求,那么并不是所有的请求都被安排好了,最终我也没有得到我所需要的一切

为了解决这个问题,我尝试让爬行器每次请求5个产品,在爬行器空闲时再次请求(通过连接来自爬虫的
中的信号)。
问题是,由于我的代码是现在,spider_idle没有运行
请求
功能,因此spider会立即关闭。就好像蜘蛛没有闲着

下面是一些代码:

class ProductSpider(scrapy.Spider):
    def __init__(self, *args, **kwargs):
        super(ProductSpider, self).__init__(*args, **kwargs)
        self.parsed_data = []
        self.header = {}
        f = open('file.csv', 'r')
        f_data = [[x.strip()] for x in f]
        count=1
        first = 'smth'
        for product in f_data:
            if first != '':
                header = product[0].split(';')
                for each in range(len(header[1:])):
                    self.header[header[each+1]] = each+1
                first = ''
            else:
                product = product[0].split(';')
                product.append(count)
                count+=1
                self.parsed_data.append(product)
        f.close()

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(ProductSpider, cls).from_crawler(crawler, *args, **kwargs)
        crawler.signals.connect(spider.request, signal=signals.spider_idle)
        return spider

    name = 'products'
    allowed_domains = [domains]
    handle_httpstatus_list = [400, 404, 403, 503, 504]

    start_urls = [start]

    def next_link(self,response):
        product = response.meta['product']
        there_is_next = False
        for each in range(response.meta['each']+1, len(product)-1):
            if product[each] != '':
                there_is_next = True
                yield scrapy.Request(product[each], callback=response.meta['func_dict'][each], meta={'func_dict': response.meta['func_dict'],'product':product,'each':each,'price_dict':response.meta['price_dict'], 'item':response.meta['item']}, dont_filter=True)
                break
        if not there_is_next:
            item = response.meta['item']
            item['prices'] = response.meta['price_dict']
            yield item

    #[...] chain parsing functions for each request

    def get_products(self):
        products = []
        data = self.parsed_data

        for each in range(5):
            if data:
                products.append(data.pop())
        return products

    def request(self):
        item = Header()
        item['first'] = True
        item['sellers'] = self.header
        yield item

        func_dict = {parsing_functions_for_every_site}

        products = self.get_products()
        if not products:
            return

        for product in products:

            item = Product()

            price_dict = {1:product[1]}
            item['name'] = product[0]
            item['order'] = product[-1]

            for each in range(2, len(product)-1):
                if product[each] != '':
                    #print each, func_dict, product[each]
                    yield scrapy.Request(product[each], callback=func_dict[each], 
                    meta={'func_dict': func_dict,'product':product,
                    'each':each,'price_dict':price_dict, 'item':item})
                    break

        raise DontCloseSpider

 def parse(self, response=None):
        pass

我假设您已经证明了您的
请求
方法正在实现,而实际问题是该方法没有生成请求(甚至项目)

在Scrapy中处理信号时,这是一个常见的错误,因为关联的方法无法生成项/请求。绕过此问题的方法是使用

请求:

request = Request('myurl', callback=self.method_to_parse)
self.crawler.engine.crawl(
    request,
    spider
)
item = MyItem()
self.crawler.engine.scraper._process_spidermw_output(
    item, 
    None, 
    Response(''), 
    spider,
)
对于项目:

request = Request('myurl', callback=self.method_to_parse)
self.crawler.engine.crawl(
    request,
    spider
)
item = MyItem()
self.crawler.engine.scraper._process_spidermw_output(
    item, 
    None, 
    Response(''), 
    spider,
)
另外,
spider\u idle
signal方法需要接收
spider
参数,因此在您的情况下,它应该如下所示:

def request(self, spider):
    ...

它应该可以工作,但我会推荐一个更好的方法名。

好的!谢谢,它似乎可以工作:)普通的scrapy.Request()和self.crawler.engine.crawl有什么区别?没有什么真正的区别,唯一的区别是
scrapy
处理回调方法,将它们添加到请求队列中,而您没有注意到,使用
self.crawler.engine..
可以明确地添加请求