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 个迭代对象(events
、fixedOddsMarkets
、outcomes
)。哪一个 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 文件结构。 fixedOddsMarkets
或 outcomes
必须被错误分配。
据我了解,它会尝试从您的游戏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:
我试图从这个页面开始 (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 个迭代对象(events
、fixedOddsMarkets
、outcomes
)。哪一个 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 文件结构。 fixedOddsMarkets
或 outcomes
必须被错误分配。
据我了解,它会尝试从您的游戏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: