Scrapy - 如果 response.status == 404 则跳出循环
Scrapy - Break out of loop if response.status == 404
如果后续 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=) 但我不确定这是否是解决此问题的正确方法。
如有任何帮助,我们将不胜感激!
由于 Scrapy 基于名为 twisted
的异步网络库 - 行为是非阻塞和异步的。您不能从请求回调中中断循环。
你可以有某种 seen_404
标志,它可以在蜘蛛实例上使用。一旦看到 404
状态 - 将其设置为 True
并在 self.seen_404
为 True
的情况下中断循环。这不是一个可靠的解决方案,因为再一次,这都是异步的——当回调被调用并且 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)
在 Scrapy 2.4.1 默认情况下 HttpErrorMiddleware 如果 response.status
不成功
将停止蜘蛛
如果后续 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=) 但我不确定这是否是解决此问题的正确方法。
如有任何帮助,我们将不胜感激!
由于 Scrapy 基于名为 twisted
的异步网络库 - 行为是非阻塞和异步的。您不能从请求回调中中断循环。
你可以有某种 seen_404
标志,它可以在蜘蛛实例上使用。一旦看到 404
状态 - 将其设置为 True
并在 self.seen_404
为 True
的情况下中断循环。这不是一个可靠的解决方案,因为再一次,这都是异步的——当回调被调用并且 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)
在 Scrapy 2.4.1 默认情况下 HttpErrorMiddleware 如果 response.status
不成功