python - 抓取某些网址时无法使我的脚本停止
问题描述
我在 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 被抓取时,如何让我的脚本停止?
解决方案
正如 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 将只导出一项。