【问题标题】:extract data from JSON api with python使用python从JSON api中提取数据
【发布时间】:2021-11-24 03:57:37
【问题描述】:

大家好,正如您在我的代码中看到的,我得到了最低价格值 但问题是我无法获得与最低价格相关的其余数据,例如 ingame_name 和 status 尤其是最低价格的状态:

例如我们取这个项目的 url : https://api.warframe.market/v1/items/mirage_prime_systems/orders?include=item

因此,我们将从该 JSON 链接获得大量未结订单,我需要在这里做的事情是从在线玩家那里获得最低销售价格以及用户的所有基本信息。

这是我的代码

import requests
import json


item = input('put your item here please :  ')
gg = item.replace(' ', '_')
response_url =  requests.get(f'https://api.warframe.market/v1/items/'+ gg +'/orders?include=item')

data = json.loads(response_url.text)
orders = data["payload"]["orders"]
           
min_price = min(o["platinum"] for o in orders if o["order_type"] == "sell")


print(min_price)

除非你们帮助我,否则我似乎做不到,我真的很感激。

【问题讨论】:

    标签: python arrays json api


    【解决方案1】:

    您可以使用内置min() 和自定义key。由于您需要对初始数据进行一些过滤,因此有两种可能的方法:

    1. 在搜索最小值之前过滤数据this答案中显示的可能方法之一);
    2. 利用在 python 中使用的字典比较来比较序列(docs)

    我发现第二种方法更好,因为它可以只对所有订单进行一次迭代(效率更高)

    所以要实现这一点,我们应该从 lambda 返回,我们将把它传递给 min() 不仅是 "platinum" 键值,还有 inverted 条件的布尔结果.

    为什么要倒置?因为我们正在寻找最小值。这意味着我们lambda 的每次返回都会与之前的最小值进行比较。在 python 中,False 等于 0,True 等于 1 (docs)0 < 1 因此,如果任何反转条件为True,则忽略"platinum" 值,所有键都会更大。

    代码:

    import requests
    from json import JSONDecodeError
    
    item = input("Put your item here please: ")
    
    try:
        response = requests.get("https://api.warframe.market/v1/items/" +
                                item.lower().replace(" ", "_") + "/orders",
                                params={"include": "item"})
        json_data = response.json()
        orders = json_data["payload"]["orders"]
    except requests.RequestException as e:
        print("An error occurred during processing request:", e)
    except JSONDecodeError:
        print("Server response is not valid json:", response.text)
    except KeyError as e:
        print("Response doesn't contain", e, "key")
    except Exception as e:
        print("Unexpected error:", e)
    else:
        min_price_order = min(orders, key=lambda x: (x["order_type"] != "sell",
                                                     x["user"]["status"] != "ingame",
                                                     x["platinum"]))
        print(min_price_order)
    

    【讨论】:

      【解决方案2】:

      按订单类型过滤列表并使用 lambda 找到最小值

      orders = [{'order_type':'sell','other':88,'platinum':4},
                {'order_type':'sell','other':77,'platinum':9},
                {'order_type':'buy','other':88,'platinum':4}]
      
      min_price = min([o for o in orders if o["order_type"] == "sell"],key= lambda x : x ['platinum'])
      print(min_price)
      

      输出

      {'order_type': 'sell', 'other': 88, 'platinum': 4}
      

      【讨论】:

      • 是的,它确实得到了最低售价的订单,但是如果我尝试从 min_price 结果 status = min_price['status'] 中提取玩家的状态,则会出现错误?
      • 在帖子中分享orders,我们将看到导致错误的原因。顺便说一句 - 错误是什么?
      • min_price['status'] --> min_price['user']['status'] 应该可以工作
      • min(orders, key=lambda x: (x.get("order_type") != "sell", x["platinum"])) 可以替代不创建其他列表
      • 这里的一切都很棒,使用 lambda 解决了所有问题,唯一的问题是我试图从游戏玩家那里获得最小值,所以 ["status"] == "ingame" 你觉得兄弟怎么样
      猜你喜欢
      • 2017-04-16
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 2020-05-06
      • 2021-09-25
      • 2020-06-02
      • 2021-03-27
      • 1970-01-01
      相关资源
      最近更新 更多