首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python脚本使用cron job运行了几个星期,现在给出了一个KeyError

Python脚本使用cron job运行了几个星期,现在给出了一个KeyError
EN

Stack Overflow用户
提问于 2020-11-04 01:08:20
回答 2查看 46关注 0票数 0

这是我正在尝试运行的代码。从PyCharm执行时起作用。我建立了一个cronjob,它在几周内取得了很好的效果。它现在正在给KeyError带来一种脱颖而出的感觉。找不到问题所在,因为我没有接触cronjob中的任何内容。

代码语言:javascript
复制
import csv
import json
import os
import random
import time
from urllib.parse import urlencode

import requests


API_URL = "https://community.koodomobile.com/widget/pointsLeaderboard?"
LEADERBOARD_FILE = "leaderboard_data.json"


def get_leaderboard(period: str = "allTime", max_results: int = 20) -> list:
    payload = {"period": period, "maxResults": max_results}
    return requests.get(f"{API_URL}{urlencode(payload)}").json()


def dump_leaderboard_data(leaderboard_data: dict) -> None:
    with open("leaderboard_data.json", "w") as jf:
        json.dump(leaderboard_data, jf, indent=4, sort_keys=True)


def read_leaderboard_data(data_file: str) -> dict:
    with open(data_file) as f:
        return json.load(f)


def parse_leaderboard(leaderboard: list) -> dict:
    return {
        item["name"]: {
            "id": item["id"],
            "score_data": {
                time.strftime("%Y-%m-%d %H:%M"): item["points"],
            },
            "rank": item["leaderboardPosition"],
        } for item in leaderboard
    }


def update_leaderboard_data(target: dict, new_data: dict) -> dict:
    for player, stats in new_data.items():
        target[player]["rank"] = stats["rank"]
        target[player]["score_data"].update(stats["score_data"])
    return target


def leaderboard_to_csv(leaderboard: dict) -> None:
    data_rows = [
        [player] + list(stats["score_data"].values()) 
        for player, stats in leaderboard.items()
    ]
    random_player = random.choice(list(leaderboard.keys()))
    dates = list(leaderboard[random_player]["score_data"])
    with open("the_data.csv", "w") as output:
        w = csv.writer(output)
        w.writerow([""] + dates)
        w.writerows(data_rows)


def script_runner():
    if os.path.isfile(LEADERBOARD_FILE):
        fresh_data = update_leaderboard_data(
            target=read_leaderboard_data(LEADERBOARD_FILE),
            new_data=parse_leaderboard(get_leaderboard()),
        )
        leaderboard_to_csv(fresh_data)
        dump_leaderboard_data(fresh_data)
    else:
        dump_leaderboard_data(parse_leaderboard(get_leaderboard()))


if __name__ == "__main__":
    script_runner()

这是它给我的错误。看起来字典有问题,所以使用了KeyError。

代码语言:javascript
复制
  File "/Users/Rob/PycharmProjects/Koodo/TEST.Json.py", line 75, in <module>
    script_runner()
  File "/Users/Rob/PycharmProjects/Koodo/TEST.Json.py", line 64, in script_runner
    fresh_data = update_leaderboard_data(
  File "/Users/Rob/PycharmProjects/Koodo/TEST.Json.py", line 44, in update_leaderboard_data
    target[player]["rank"] = stats["rank"]
KeyError: 'triggered123'

下面是JSON文件中的数据:https://pastebin.com/HQyL4Kyx

EN

回答 2

Stack Overflow用户

发布于 2020-11-04 01:14:34

这是因为字典target中不存在名为triggered123的键。

来源:https://wiki.python.org/moin/KeyError

问题是,在update_leaderboard_data中,您迭代新数据并使用它们在旧数据中查找。如果旧数据中不存在新的键,您将获得KeyError

尝试打印dict target以查看密钥triggered123是否在其中。

或者使用带有默认值的dictget方法:这样就不会引发错误,并且可以在输出中搜索此默认值。

票数 0
EN

Stack Overflow用户

发布于 2020-11-04 01:19:19

在我看来,当你的代码第一次运行时,它会缓存排行榜。

在随后的运行中,它将使用新值更新现有的排行榜,方法是循环遍历每个新条目,找到它们的用户名,并在旧字典中查找该键。但是,如果有新用户,则该键将不存在于旧字典中。

出现这个错误是因为player triggered123是排行榜的新用户,并且是在您第一次运行脚本之后列出的。

您需要更新update_leaderboard_data来处理这种情况(通过在尝试访问该键之前检查该键是否存在于字典中)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64667367

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档