Eri*_*nte 3 python scrapy web-scraping
我有一个循环,如果后续产量请求的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**
Run Code Online (Sandbox Code Playgroud)
我查看了 Request(errback=) 但不确定这是否是正确的方法。
任何帮助将不胜感激!
由于Scrapy基于一个称为异步网络库的twisted行为是非阻塞和异步的。您无法从请求回调中中断循环。
不过,您可以拥有某种seen_404可在蜘蛛实例上使用的标志。一旦您看到404状态 - 将其设置为并在情况为 时True中断循环。这不是一个可靠的解决方案,因为这都是异步的 - 当调用回调并将其设置为时,您不会知道循环经过了多少次迭代。但是,例如,如果您知道在一个页面之后,所有下一页也会有状态 - 那么这可能没问题:self.seen_404Trueseen_404True404404
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
Run Code Online (Sandbox Code Playgroud)
另一种选择是通过传递请求列表(队列)以使其同步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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2591 次 |
| 最近记录: |