Python 具有多个回调的Scrapy CrawlSpider规则

Python 具有多个回调的Scrapy CrawlSpider规则,python,scrapy,Python,Scrapy,我正在尝试创建一个示例Spider,它实现了scrapy CrawlSpider。我的ExampleSpider应该能够处理只包含艺术家信息的页面, 仅包含相册信息的页面,以及一些同时包含相册和艺术家信息的其他页面 我能够处理前两种情况。但问题出现在第三种情况下。我正在使用parse\u artist(response)方法处理艺术家数据,parse\u album(response)方法处理相册数据。 我的问题是,如果一个页面同时包含艺术家和专辑数据,我应该如何定义我的规则 我应该喜欢下面的吗

我正在尝试创建一个示例Spider,它实现了scrapy CrawlSpider。我的ExampleSpider应该能够处理只包含艺术家信息的页面, 仅包含相册信息的页面,以及一些同时包含相册和艺术家信息的其他页面

我能够处理前两种情况。但问题出现在第三种情况下。我正在使用
parse\u artist(response)
方法处理艺术家数据,
parse\u album(response)
方法处理相册数据。 我的问题是,如果一个页面同时包含艺术家和专辑数据,我应该如何定义我的规则

  • 我应该喜欢下面的吗?(同一url模式有两条规则)
  • 我应该多次回拨吗?(scrapy是否支持多个回调?)
  • 还有别的办法吗。(正确的方法)


  • CrawlSpider
    调用
    \u requests\u to\u follow()
    方法来提取URL并生成后续请求:

    def _requests_to_follow(self, response):
        if not isinstance(response, HtmlResponse):
            return
        seen = set()
        for n, rule in enumerate(self._rules):
            links = [l for l in rule.link_extractor.extract_links(response) if l not in seen]
            if links and rule.process_links:
                links = rule.process_links(links)
            seen = seen.union(links)
            for link in links:
                r = Request(url=link.url, callback=self._response_downloaded)
                r.meta.update(rule=n, link_text=link.text)
                yield rule.process_request(r)
    
    如你所见:

    • 变量
      seen
      记忆
      url
      已被处理
    • 每个
      url
      将最多由一个
      回调
      解析

    您可以定义一个
    parse_item()
    来调用
    parse_artist()
    parse_album()


    parse\u-artist(response)
    将返回一个
    ArtistItem()
    parse\u-album(response)
    将返回一个
    AlbumItem()
    。因此,如果我使用项目管道(比方说为了持久化),它(持久化管道)会是带有两种数据类型的调用twise吗?@GrainierPerera管道将逐个处理每个项目。
    def _requests_to_follow(self, response):
        if not isinstance(response, HtmlResponse):
            return
        seen = set()
        for n, rule in enumerate(self._rules):
            links = [l for l in rule.link_extractor.extract_links(response) if l not in seen]
            if links and rule.process_links:
                links = rule.process_links(links)
            seen = seen.union(links)
            for link in links:
                r = Request(url=link.url, callback=self._response_downloaded)
                r.meta.update(rule=n, link_text=link.text)
                yield rule.process_request(r)
    
    rules = [
        Rule(SgmlLinkExtractor(allow=[r'same regex_rule']), callback='parse_item', follow=True),
        # more rules .....
    ]
    
    def parse_item(self, response):
    
        yield self.parse_artist(response)
        yield self.parse_album(response)