簡體   English   中英

如果在另一個循環中滿足條件,則中斷循環 SCRAPY

[英]Break the loop if condition is met in another loop SCRAPY

我正在構建一個SCRAPY SPIDER ,我向API發送請求。 我需要檢查是否滿足條件,我需要打破循環。

我在parse方法和 content 以及parse_api方法中有循環。 我嘗試使用以下邏輯,但沒有奏效。

if 'date container' not in self.html:
    break

我收到以下異常AttributeError: 'SpiderClass' object has no attribute 'html'

處理此異常的可能邏輯是什么?

下面是我的代碼:

import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.selector import Selector
import json


class SpiderClass(scrapy.Spider):
    name = 'spider_name'

    custom_settings = {
        "FEED_FORMAT": 'csv',
        "FEED_URI": 'dataset.csv'
    }

    def start_requests(self):
        links_list = ['https://10times.com/company/informa-knect']
        for link in links_list:
            yield scrapy.Request(url=link, callback=self.parse)

    
    def parse(self, response):
        ids = response.xpath('//input[@id="companyId"]/@value').get()
        company_name = response.xpath('//h1/text()').get()

        main_data = {
            "Links": response.url,
            "CompanyName": company_name,
        }

        # sending request for upcoming event api
        off_set = 1
        while True:
            if 'date-container' not in self.html:
                break

            off_set_number = off_set * 5
            api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set_number}&pastHit=0&calValue=upcoming'

            yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)

            off_set += 1


    def parse_api(self, response):
        api_json = json.loads(response.body)
        self.html = api_json['html']


if __name__ == '__main__':
    process = CrawlerProcess()
    process.crawl(SpiderClass)
    process.start()

編輯

因此,您的代碼中還有其他一些問題。 您使用值ids但這並未在任何地方定義。 您需要以某種方式生成它。

此外,在while語句之前需要有一個初始yield 沒抓住這個是我的錯。 問題是,如果沒有初始yieldhasattr(self, 'html')的評估將始終為False

調整后的代碼

    def parse(self, response):
        company_name = response.xpath('//h1/text()').get()

        main_data = {
            "Links": response.url,
            "CompanyName": company_name,
        }

        # sending request for upcoming event api
        off_set = 1
        api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set * 5}&pastHit=0&calValue=upcoming'
        yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)

        while hasattr(self, 'html') and 'date-container' in self.html:

            off_set_number = off_set * 5
            api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set_number}&pastHit=0&calValue=upcoming'

            yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)

            off_set += 1

原答案

兩件事,使用while True后跟if語句絕對不是要走的路。 while語句已經是一個評估語句。 見 w3schools

其次,標准函數hasattr()將檢查對象是否具有列出的屬性。 如果不是,它將返回False並且不執行評估的第二部分。

調整后的 parse() 函數

    def parse(self, response):
        company_name = response.xpath('//h1/text()').get()

        main_data = {
            "Links": response.url,
            "CompanyName": company_name,
        }

        # sending request for upcoming event api
        off_set = 1
        # the while statement already does an if.
        while hasattr(self, 'html') and 'date-container' in self.html:

            off_set_number = off_set * 5
            api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set_number}&pastHit=0&calValue=upcoming'

            yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)

            off_set += 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM