我正在抓取一个页面列表,其中每个页面都有一个我需要解析的网址列表。我在这些第一页上进行了循环,但我不知道何时应该停止爬行。例如,这个仍然需要解析:
http://www.cmjornal.pt/opiniao/colunistas/acacio-pereira/MoreContent?firstContent=183
但这不是因为已经空了:
http://www.cmjornal.pt/opiniao/colunistas/acacio-pereira/MoreContent?firstContent=200
所以我的问题是:如何通过url解析找到条件来停止爬虫?我尝试使用CloseSpider()
但它不起作用,因为它在解析其他网址之前完全关闭了蜘蛛。
我使用CloseSpider()
显示我使用的代码:
class CmSpider(scrapy.Spider):
name = "historical"
start_urls = ['http://www.cmjornal.pt/opiniao/colunistas/acacio-pereira/MoreContent?firstContent=']
hostname = 'http://www.cmjornal.pt'
def parse(self, response):
for i in range(180,200,3):
url = response.url + str(i)
yield scrapy.Request(url,callback=self.parse_page,priority = 1)
def parse_page(self,response):
if len(response.xpath('/html/body//*')) <= 2:
raise CloseSpider('bandwidth_exceeded')
else:
pass
articles_url = response.xpath('//*[@class="lead"]/../h3/a/@href').extract()
for url in articles_url:
url = self.hostname+url
item = CmItem()
item['hostname'] = self.hostname
request = scrapy.Request(url,callback=self.parse_article)
request.meta['item'] = item
yield request
def parse_article(self,response):
item = response.meta['item']
(...)
注意:对于这个特殊情况,我知道内容何时结束,但我需要在许多其他情况下运行此内容,而我不知道这样的限制。
答案 0 :(得分:1)
您应该停止产生更多请求而不是关闭蜘蛛,如下所示:
# -*- coding: utf-8 -*-
import scrapy
from w3lib.url import add_or_replace_parameter
from w3lib.url import url_query_parameter
class HistorialSpider(scrapy.Spider):
name = 'historial'
allowed_domains = ['cmjornal.pt']
def start_requests(self):
base_url = 'http://www.cmjornal.pt/opiniao/colunistas/acacio-pereira/MoreContent'
new_url = add_or_replace_parameter(base_url, 'firstContent', 180)
yield scrapy.Request(new_url, callback=self.parse_page)
def parse_page(self, response):
if len(response.xpath('/html/body//*')) <= 2:
return
next_page = int(url_query_parameter(response.url, 'firstContent')) + 1
yield scrapy.Request(add_or_replace_parameter(response.url, 'firstContent', next_page),
callback=self.parse_page)
articles_url = response.xpath('//*[@class="lead"]/../h3/a/@href').extract()
for url in articles_url:
yield response.follow(url, callback=self.parse_article)
def parse_article(self, response):
pass