TypeError:使用Scrapy爬网API时,“非类型”对象不可编辑

2024-09-19 23:44:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从这个页面(https://api.pointsbet.com/api/v2/competitions/7176/events/featured)开始,获取密钥并将其附加到事件api(https://api.pointsbet.com/api/v2/events/)中,这样我就可以从事件api中获取一些数据,然后进行循环

我得到了错误TypeError:“NoneType”对象是不可编辑的,我不知道为什么

提前谢谢

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)

Tags: nameinhttpscomapijsonforget
1条回答
网友
1楼 · 发布于 2024-09-19 23:44:07

你能再多介绍一下吗? 我在代码中看到至少3个迭代对象(eventsfixedOddsMarketsoutcomes)。哪一个返回错误

错误“非类型”对象不可编辑表示.get()方法之一找不到元素。为了避免此错误,可以将第二个参数添加到.get()方法中(类似于resp.get('events', []))或resp.get('events', {})。这取决于json的结构(列表或dict)

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

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

如果一切正常,检查api直接在代码中返回给您的json数据(您可以使用print(resp))。 如果在这一步中,您从api中获得了适当的json文件(数据对您来说还可以),请检查您的代码和json文件结构fixedOddsMarketsoutcomes必须被错误分配


据我所知,它试图从您的gameapi链接中获取“事件”,对吗? 问题是使用“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语句也不是一个好的变体,因为它总是正确的。我认为最好用if eventKey:代替if gameapi:

相关问题 更多 >