TypeError: 'NoneType' object is not iterable when using Scrapy to crawl API

TypeError: 'NoneType' object is not iterable when using Scrapy to crawl API

我试图从这个页面开始 (https://api.pointsbet.com/api/v2/competitions/7176/events/featured), grab the key and append it to an event api (https://api.pointsbet.com/api/v2/events/),这样我就可以从事件 api 中获取一些数据,然后循环遍历。

我收到错误 TypeError: 'NoneType' object is not iterable 我不知道为什么。

提前致谢!

import scrapy
import json


class PbSpider(scrapy.Spider):
    name = 'pb'
    allowed_domains = ['api.pointsbet.com']
    start_urls = ['https://api.pointsbet.com/api/v2/competitions/7176/events/featured']

    def parse(self, response):
        resp = json.loads(response.body)
        events = resp.get('events')

        for event in events:
            eventKey = event.get('key')
            gameapi = f'https://api.pointsbet.com/api/v2/events/{eventKey}'

            if gameapi:

                yield scrapy.Request(url=gameapi, callback=self.parse)

                res = json.loads(response.body)
                fixedOddsMarkets = res.get('fixedOddsMarkets')

                for fixedOddsMarket in fixedOddsMarkets:
                    market = fixedOddsMarket.get('eventName')
                    outcomes = fixedOddsMarket.get('outcomes')

                    for outcome in outcomes:
                        name = outcome.get('name')
                        price = outcome.get('price')

                        print(market, name, price)

你能提供更多信息吗? 我在您的代码中看到至少 3 个迭代对象(eventsfixedOddsMarketsoutcomes)。哪一个 returns 错误?

错误'NoneType' object is not iterable 表示您的其中一个 .get() 方法找不到元素。为避免此错误,您可以将第二个参数添加到您的 .get() 方法中(类似于 resp.get('events', []))或 resp.get('events', {})。这取决于你的json(列表或字典)的结构。

但是,如果您在连接到 api 时遇到一些问题(或者也错误地分配了一些 json 对象)- 它无法解决您的问题。

首先,检查响应状态代码是否可接受(200、NOT 400、403 等)。您可以在 def parse(self, response) 方法中使用 print(response.status) 来完成。

如果一切正常,直接在代码中查看api returns给你的json数据(你可以用print(resp))。 如果在此步骤中您有来自 api 的适当 json 文件(并且数据适合您),请检查您的代码和 json 文件结构。 fixedOddsMarketsoutcomes 必须被错误分配。


据我了解,它会尝试从您的游戏api link 中抓取 'events',对吗? 问题是您使用 'self.parse' 作为回调参数。

添加另一种方法,它应该可以解决您的问题:

def parse(self, response):
    resp = json.loads(response.body)
    events = resp.get('events')

    for event in events:
        eventKey = event.get('key')
        gameapi = f'https://api.pointsbet.com/api/v2/events/{eventKey}'

        if gameapi:

            yield scrapy.Request(url=gameapi, callback=self.parse_event)
def parse_event(self, response):
    res = json.loads(response.body)
    fixedOddsMarkets = res.get('fixedOddsMarkets')

    for fixedOddsMarket in fixedOddsMarkets:
        market = fixedOddsMarket.get('eventName')
        outcomes = fixedOddsMarket.get('outcomes')

        for outcome in outcomes:
            name = outcome.get('name')
            price = outcome.get('price')

            print(market, name, price)

此外,使用 if gameapi 语句也不是一个好的变体,因为它始终为 True。我认为最好用 if eventKey:

替换 if gameapi: