我现在每天都在抓这个网站,而且我正在使用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页的第一个请求,我们将不胜感激。
答案 0 :(得分: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()
网址的请求过滤。您可能需要根据需要使用其他密钥。