Scrapy:如何检查和停止爬行

时间:2017-11-23 20:04:52

标签: scrapy web-crawler scrapy-spider

我正在抓取一个页面列表,其中每个页面都有一个我需要解析的网址列表。我在这些第一页上进行了循环,但我不知道何时应该停止爬行。例如,这个仍然需要解析:

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']

        (...)

注意:对于这个特殊情况,我知道内容何时结束,但我需要在许多其他情况下运行此内容,而我不知道这样的限制。

1 个答案:

答案 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