我试着抓取一个用scrapy分页的网站,结果还不错!但是,随着这个网站的更新和新帖子的加入,我每天都需要运行我的代码,所以每次我运行代码,它都会抓取所有的页面。幸运的是,我使用的是django,在我的django模型中,我使用了
唯一=真
因此,在我的数据库中没有重复的记录,但我想在分页爬行发现重复记录时立即停止它。我应该如何做到这一点?下面是我的蜘蛛代码片段:
class NewsSpider(scrapy.Spider):
name = 'news'
allowed_domains = ['....']
start_urls = ['....']
duplicate_record_flag = False
def parse(self, response,**kwargs):
next_page = response.xpath('//a[@class="next page-numbers"]/@href').get()
news_links = response.xpath('//div[@class="content-column"]/div/article/div/div[1]/a/@href').getall()
for link in news_links:
if self.duplicate_record_flag:
print("Closing Spider ...")
raise CloseSpider('Duplicate records found')
yield scrapy.Request(url=link, callback=self.parse_item)
if next_page and not self.duplicate_record_flag:
yield scrapy.Request(url=next_page, callback=self.parse)
def parse_item(self, response):
item = CryptocurrencyNewsItem()
...
try:
CryptocurrencyNews.objects.get(title=item['title'])
self.duplicate_record_flag = True
return
except CryptocurrencyNews.DoesNotExist:
item.save()
return item
我使用了一个类变量(duplicate_record_flag)来在所有函数中访问它,并且在遇到重复记录时也知道这一点。问题是,当发现第一个重复记录时,蜘蛛不会真实的停止!在解析函数的for迭代中,如果我们有10个news_links,并且在第一次迭代中我们发现了一个重复记录,那么我们的标志在那一刻不会改变,如果我们在for循环中打印该标志,它将为每次迭代打印10个“False”值!!!而在第一次迭代中它应该被更改为“True”!
换句话说,爬虫会在每次解析时抓取每个页面中的所有链接!2我该如何防止这种情况?
1条答案
按热度按时间myzjeezk1#
如果您想在满足特定条件后停止蜘蛛,您可以引发CloseSpider
如果您只想跳过重复的项,可以从管道中引发DropItem异常。Scrapy docs中的示例代码: