Python 如何限制scrapy中每个域的刮取项目数?

Python 如何限制scrapy中每个域的刮取项目数?,python,scrapy,scrapy-spider,Python,Scrapy,Scrapy Spider,我正在从多个网站上抓取项目(同样使用scrapy)。 我试图搜集的项目并不总是很明确,可能在文本中。所以我使用字符串匹配来识别项目。然而,这也会产生一些不需要的信息以及我所需的数据,我的刮刀需要很长时间来刮除不需要的信息。 为了避免这种情况,我对被刮的物品数量设置了上限。通过使用“if”条件,我在达到上限时引发CloseSpider()异常。 这种方法在我只有一个域需要抓取之前效果很好。如何将其扩展到多个域 class CustomSpider(CrawlSpider): name = "mys

我正在从多个网站上抓取项目(同样使用scrapy)。 我试图搜集的项目并不总是很明确,可能在文本中。所以我使用字符串匹配来识别项目。然而,这也会产生一些不需要的信息以及我所需的数据,我的刮刀需要很长时间来刮除不需要的信息。 为了避免这种情况,我对被刮的物品数量设置了上限。通过使用“if”条件,我在达到上限时引发CloseSpider()异常。 这种方法在我只有一个域需要抓取之前效果很好。如何将其扩展到多个域

class CustomSpider(CrawlSpider):
name = "myspider"
start_urls = ['https://www.example1.com/']
allowed_domains = ['www.example1.com']
rules = [Rule(LinkExtractor(allow=()), callback='parse_info', follow = True)]

def parse_info(self, response):
    scrape_count = self.crawler.stats.get_value('item_scraped_count')
    if scrape_count == 20:
        raise CloseSpider("Limit Reached")
我的问题是,如何为以下场景扩展此代码:

class CustomSpider(CrawlSpider):
name = "myspider"
start_urls = ['https://www.example1.com/', 'https://www.example2.com/']
allowed_domains = ['www.example1.com', 'www.example2.com/']
rules = [Rule(LinkExtractor(allow=()), callback='parse_info', follow = True)]

def parse_info(self, response):
建议在这里改变逻辑
    scrape_count = self.crawler.stats.get_value('item_scraped_count')
    if scrape_count == 20:
        raise CloseSpider("Limit Reached")
请参见此玩具示例:

from __future__ import print_function

import collections
try:
    from urllib.urlparse import urlsplit
except ImportError:
    from urlparse import urlsplit

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class MySpider(CrawlSpider):
    name = 'myspider'
    start_urls = ['http://quotes.toscrape.com/',
                  'http://webscraper.io/test-sites']
    allowed_domains = ['quotes.toscrape.com', 'webscraper.io']

    scraped_count = collections.defaultdict(int)
    limit = 10

    rules = [Rule(LinkExtractor(allow=()), callback='parse_page',
                  follow=True, process_request='process_request')]

    def parse_page(self, response):
        yield {
            'url': response.url
        }

    def process_request(self, request):
        url = urlsplit(request.url)[1]
        if self.scraped_count[url] < self.limit:
            self.scraped_count[url] += 1
            return request
        else:
            print('Limit reached for {}'.format(url))
from\uuuuu future\uuuuu导入打印功能
导入集合
尝试:
从urllib.urlparse导入urlspilt
除恐怖外:
从URL解析导入URL拆分
从scrapy.LinkExtractor导入LinkExtractor
从scrapy.spider导入爬行蜘蛛,规则
类MySpider(爬行蜘蛛):
name='myspider'
起始URL=['http://quotes.toscrape.com/',
'http://webscraper.io/test-sites']
允许的_域=['quotes.toscrape.com','webscraper.io']
scraped_count=collections.defaultdict(int)
限值=10
rules=[规则(LinkExtractor(allow=()),callback='parse_page',
follow=True,process\u request='process\u request')]
def解析页面(自我,响应):
屈服{
“url”:response.url
}
def过程_请求(自我,请求):
url=urlspit(request.url)[1]
如果self.scraped_count[url]
它在属性
scraped\u count
中跟踪每个域刮取的项目数。属性
limit
保存每个域的限制。逻辑放在
process\u request
方法中,该方法作为参数传递给,并为该规则提取的每个请求调用(请参阅文档)。当您超过限制时,请求将被过滤,否则它将原封不动地返回并得到处理

如果您需要更复杂或适用于多个spider的东西,我建议您扩展扩展类,在那里实现逻辑并替换
设置.py中的默认类,您可以使用

指定项目数的整数。如果蜘蛛刮 超过该金额且这些项目通过项目管道传递, spider将关闭,原因为closespider\u itemcount。 当前在下载程序队列中的请求(最多 并发_请求)仍在处理中。如果为零(或非零 设置),爬行器不会按传递的项目数关闭


它取决于您如何将
关联,它是否有一个字段指示它属于哪个域?类似于
item={'domain':'www.example2.com'}
?目前它没有这样做。假设我做了这一部分,我如何才能达到预期的逻辑?嗨@TomášLinhart,谢谢你的建议。这接近我想要的。但我不会在达到限制后尝试过滤请求。我希望蜘蛛停止向该域发送请求。一旦所有域的限制都达到,蜘蛛就会停止。嗨,parik…我可以为蜘蛛抓取的项目数量设置限制。我想对我的start_URL中“每个域”的项数设置一个限制。如果你想让蜘蛛停止向该域发送请求,你可以在发送请求之前计算每个域的项数,并将它们放入一个变量或dict中,如果项目的数量小于您想要的数量,您可能会有一个条件这就是@TomášLinhart的解决方案。我正在寻找一种更复杂的方法,让scrapy了解不要生成更多请求,而不是我停止请求