0

我正在使用 Python 使用 Steam 的 API 提取数据。我有一个随机生成的 Steam ID 列表。问题是,并非所有这些 ID 都指向有效帐户。当我尝试访问没有对象值的帐户时,程序给了我一个“KeyError”。Steam API 将为任何请求输出一个 ['response'] 级别对象,因此当我使用该最高级别进行打印时,我将获得每个请求的响应。但是,如果我再上一层(例如 ['response']['game_count']),当程序到达没有任何 ['game_count'] 值的帐户时,程序将失败。我如何告诉 python 跳过这些帐户?

示例输出:

带有游戏的帐户(删除了额外的回报以提高可读性)

{
"response": {
    "game_count": 1,
    "games": [
        {
            "appid": 205790,
            "playtime_forever": 0
        }
    ]
}

没有游戏的账号

{
    "response": {
    }
}

我当前的代码:

import urllib2, random, sys, json

list = open('d:\python\SteamUserIDs.txt').read().splitlines()
SteamID = str(list)


for SteamID in list[0:10:1]:
    request = urllib2.Request('http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=05475AE5A8410CE01236A8A29E1DEE8E&steamid=%s&format=json' %SteamID, headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"})
    response = json.load(urllib2.urlopen(request))
    request2 = urllib2.Request('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0001/?key=05475AE5A8410CE01236A8A29E1DEE8E&steamids=%s&format=json' %SteamID, headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"})
    response2 = json.load(urllib2.urlopen(request2))
4

2 回答 2

2

有几个选择。

  • 第一个选项是innot in。关于这一点的重要说明,如果您看到使用建议has_key(),请不要。它已在 Python 2.x 中被弃用,并在 Python 3.x 中被删除。相反,您使用in运算符。

如果 d 有一个键 key,则返回 True,否则返回 False。

if 'game_count' in response:
    # Do something

或者,not版本:

if 'game_count' not in response:
    # skip/pass on this record
else:
    # Do something
  • 下一个选项,就像另一个答案中提到的那样,是get方法

如果键在字典中,则返回键的值,否则返回默认值。如果未给出默认值,则默认为无,因此此方法永远不会引发 KeyError。

if response.get('game_count', None):
    # Do something
else:
    # skip/pass on this record

更新:您没有对您的回复做任何事情。这就是为什么看起来什么都没有发生的原因。

您的代码还有一些需要修复的地方:

  • 您正在对 API 进行不必要的调用。每次调用最多可以将 100 个 SteamID 传递给GetPlayerSummaries. 您无需为每个 ID 一次调用一个。
  • 不要命名你的变量list
  • SteamID = str(list)毫无意义,因为您SteamID在循环中重用变量

这是您的代码的略微修改版本

steam_ids = open('d:\python\SteamUserIDs.txt').read().splitlines()
steam_str = ','.join(steam_ids)    # This make a comma separated string that we will use in our API calls 

owned_games = {}

for s in steam_ids:
    request = urllib2.Request('http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=<<YOURKEY>>&steamid=%s&format=json' % s,headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"})
    response = json.load(urllib2.urlopen(request))['response']
    if response.get('game_count', None):
        owned_games[s] = response['game_count']
    else:
        owned_games[s] = None

# This call will only work if you have less than 100 steam ids. If you have more, you
# will need to build steam_str differently for batches of 100
request2 = urllib2.Request('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0001/?key=<<YOURKEY>>&steamids=%s&format=json' %steam_str, headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"})
response2 = json.load(urllib2.urlopen(request2))

最后,您将得到一个owned_games看起来像这样的字典(在此示例中配置文件 ID 不准确)。

{'76561197992702437': 63,
 '76561197992702438': 0,
 '76561197992702439': 0,
 '76561197995066524': 62,
 '76561197995066525': 0,
 '76561197995066526': 0,
 '76561197995066527': 0}

这本词典向您显示每个配置文件拥有多少游戏。然后,在您的response2对象中,您可以解析每个项目response2['response']['players']以进行比较。或者,您可以将列表重建players为字典(或将其组合起来,games_owned这样您就不需要每次都遍历列表以找到合适的配置文件。但这两个练习中的任何一个都超出了您最初问题的范围。

现在,您需要查看解析中的数据responseresponse2进行解析。

于 2014-04-16T03:51:14.953 回答
0

像这样的东西?

您收到密钥错误,因为密钥game_count不存在。在做某事(比如打印)之前检查那个键

for response in steam_id_responses:
    if response.get('game_count', None):
        print response
于 2014-04-16T03:15:15.140 回答