首页 > 解决方案 > 抓取某些网址时无法使我的脚本停止

问题描述

我在 scrapy 中创建了一个脚本来解析start_urls. 该脚本完美地完成了它的工作。

我现在想做的是让我的脚本在解析两个 url 后停止,无论有多少 url。

到目前为止,我已经尝试过:

import scrapy
from scrapy.crawler import CrawlerProcess

class TitleSpider(scrapy.Spider):
    name = "title_bot"
    start_urls = ["https://www.google.com/","https://www.yahoo.com/","https://www.bing.com/"]

    def parse(self, response):
        yield {'title':response.css('title::text').get()}

if __name__ == "__main__":
    c = CrawlerProcess({
        'USER_AGENT': 'Mozilla/5.0', 
    })
    c.crawl(TitleSpider)
    c.start()

当两个列出的 url 被抓取时,如何让我的脚本停止?

标签: pythonpython-3.xweb-scrapingscrapy

解决方案


正如 Gallaecio 所提议的,您可以添加一个计数器,但这里的不同之处在于您在 if 语句之后导出一个项目。这样,它几乎总是会导出 2 个项目。

import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.exceptions import CloseSpider


class TitleSpider(scrapy.Spider):
    name = "title_bot"
    start_urls = ["https://www.google.com/", "https://www.yahoo.com/", "https://www.bing.com/"]
    item_limit = 2

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.counter = 0

    def parse(self, response):
        self.counter += 1
        if self.counter > self.item_limit:
            raise CloseSpider

        yield {'title': response.css('title::text').get()}

为什么几乎总是?你可能会问。它与parse方法中的竞争条件有关。

想象一下,self.counter当前等于1,这意味着预计将再导出一项。但是现在 Scrapy 同时收到两个响应,并parse为它们调用方法。如果运行该方法的两个线程parse将同时增加计数器,则它们都将self.counter等于3,因此都会引发CloseSpider异常。

在这种情况下(这不太可能发生,但仍有可能发生),spider 将只导出一项。


推荐阅读