Scrapy - 如果response.status == 404,则跳出循环

时间:2015-02-24 21:05:29

标签: python web-scraping scrapy scrapy-spider

如果后续yield Request的response.status为404,我有一个循环,我试图突破。我正在迭代页码,但不知道有多少页面可用。最终我会点击一个404的页面,我希望它打破while循环。我把它硬编码到40页,但有超过40页

def parse(self, response):
    cat = json.loads(response.body_as_unicode())
    for c in cat:
        while **RESPONSE.STATUS == 200**:
            url = 'http://www.url.com/'+str(c)+'/'+str(page)+'.json'
            page += 1
            yield Request(url, callback=self.parse_cats)

def parse_cats(self, response):
    if response.status  == '404':
        **BREAK ABOVE LOOP**

我查看了Request(errback =),但我不确定这是否是正确的方法。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:4)

由于Scrapy基于名为twisted的异步网络库 - 行为是非阻塞和异步的。您无法从请求回调中断循环


你可以在蜘蛛实例上使用某种seen_404标志。看到404状态后 - 将其设置为True并在self.seen_404True的情况下中断循环。这不是一个可靠的解决方案,因为这也是异步的 - 您不知道在调用回调并且seen_404设置为True时循环的循环次数。但是,例如,如果您知道在404页面之后所有下一页也会有404状态 - 那么这可能没问题:

def parse(self, response):
    cat = json.loads(response.body_as_unicode())
    for c in cat:
        if self.seen_404:
            break

        url = 'http://www.url.com/'+str(c)+'/'+str(page)+'.json'
        page += 1
        yield Request(url, callback=self.parse_cats)

def parse_cats(self, response):
    if response.status == '404':
        self.seen_404 = True

另一个选择是使其同步,方法是传递请求列表(队列)以在请求本身内部(meta内):

def parse(self, response):
    cat = json.loads(response.body_as_unicode())
    urls = ['http://www.url.com/%s/%s.json' % (c, page) 
            for page, c in enumerate(cat)]  # if you want page to start with 1: enumerate(cat, start=1)

    url = urls.pop(0)
    yield Request(url, meta={'urls': urls}, callback=self.parse_cats)

def parse_cats(self, response):
    if response.status == '404':
        # stop crawling
        raise CloseSpider('404 found at %s' % response.url)

    urls = response.meta['urls']
    try:
        url = urls.pop(0)
    except IndexError:
        raise CloseSpider('No more urls to go')

    yield Request(url, meta={'urls': urls}, callback=self.parse_cats)

答案 1 :(得分:0)

在 Scrapy 2.4.1 中,如果 response.status 不成功,默认情况下 Void 将停止蜘蛛