在抓取两页时忽略请求

问题描述 投票:1回答:1

我现在每天都在抓这个网站,并且使用DeltaFetch来忽略已经访问过的网页(其中很多)。

我面临的问题是,对于这个网站,我需要首先刮取页面A,然后刮取页面B以检索有关该项目的其他信息。 DeltaFetch很好地忽略了对页面B的请求,但这也意味着每次抓取运行时,它都会向页面A运行请求,无论它是否访问过它。

这就是我的代码现在的结构:

# Gathering links from a page, creating an item, and passing it to parse_A
def parse(self, response):
    for href in response.xpath(u'//a[text()="詳細を見る"]/@href').extract():
        item = ItemLoader(item=ItemClass(), response=response)
        yield scrapy.Request(response.urljoin(href), 
                                callback=self.parse_A,
                                meta={'item':item.load_item()})

# Parsing elements in page A, and passing the item to parse_B
def parse_A(self, response):
    item = ItemLoader(item=response.meta['item'], response=response)
    item.replace_xpath('age',u"//td[contains(@class,\"age\")]/text()")
    page_B = response.xpath(u'//a/img[@alt="周辺環境"]/../@href').extract_first()
    yield scrapy.Request(response.urljoin(page_B), 
                            callback=self.parse_B,
                            meta={'item':item.load_item()})

# Parsing elements in page B, and yielding the item
def parse_B(self, response):
    item = ItemLoader(item=response.meta['item'])
    item.add_value('url_B',response.url)
    yield item.load_item()

任何帮助将被理解为使用DeltaFetch忽略在访问此页面时对页面A的第一个请求。

python scrapy scrapy-spider scrapinghub
1个回答
4
投票

DeltaFetch仅记录在其数据库中生成项目的请求,这意味着默认情况下只会跳过这些请求。

但是,您可以使用deltafetch_key元键自定义用于存储记录的密钥。如果对于调用parse_A()的请求使这个键与在parse_A()中创建的那些相同,那么你应该能够达到你想要的效果。

这样的东西应该工作(未经测试):

from scrapy.utils.request import request_fingerprint

# (...)

    def parse_A(self, response):
        # (...)
        yield scrapy.Request(
            response.urljoin(page_B),
            callback=self.parse_B,
            meta={
                'item': item.load_item(),
                'deltafetch_key': request_fingerprint(response.request)
            }
        )

注意:上面的示例通过过滤对parse_B()网址的请求,有效地取代了对parse_A()网址的请求过滤。您可能需要根据需要使用其他密钥。

© www.soinside.com 2019 - 2024. All rights reserved.