【问题标题】:How do I grab information from an API?如何从 API 中获取信息?
【发布时间】:2020-09-07 05:47:48
【问题描述】:

所以当我尝试从 API 获取信息时遇到了一些问题,我可以获取每个产品的名称,但对于一个来说很好:当我尝试返回“float”值(产品的价格)时我收到此错误: TypeError: 'float' 对象不可迭代

这是我的 Python 代码:

import requests
from flask import Flask, render_template
import datetime
import array

product = [
    "BROWN_MUSHROOM",
    "INK_SACK:3",  # cocao beans
    "INK_SACK:4",  # lapis lazuli
    "TARANTULA_WEB",
    "CARROT_ITEM",
    "ENCHANTED_POTATO",
    "ENCHANTED_SLIME_BALL",
    "ENCHANTED_GOLDEN_CARROT",
    "ENCHANTED_RED_MUSHROOM",
    "ENCHANTED_RABBIT_HIDE",
    "ENCHANTED_BIRCH_LOG",
    "ENCHANTED_GUNPOWDER",
    "ENCHANTED_MELON",
    "ENCHANTED_SUGAR",
    "CACTUS",
    "ENCHANTED_BLAZE_ROD",
    "ENCHANTED_CAKE",
    "PUMPKIN",
    "ENCHANTED_BROWN_MUSHROOM",
    "WHEAT",
    "ENCHANTED_RAW_SALMON",
    "ENCHANTED_GLISTERING_MELON",
    "PRISMARINE_SHARD",
    "PROTECTOR_FRAGMENT",
    "ENCHANTED_EMERALD",
    "ENCHANTED_SPIDER_EYE",
    "RED_MUSHROOM",
    "MUTTON",
    "ENCHANTED_MELON_BLOCK",
    "DIAMOND",
    "WISE_FRAGMENT",
    "COBBLESTONE",
    "SPIDER_EYE",
    "RAW_FISH",
    "ENCHANTED_PUFFERFISH",
    "POTATO_ITEM",
    "ENCHANTED_HUGE_MUSHROOM_1",  # enchanted brown mushroom block
    "ENCHANTED_COBBLESTONE",
    "ENCHANTED_HUGE_MUSHROOM_2",  # enchanted red mushroom block
    "PORK",
    "PRISMARINE_CRYSTALS",
    "ICE",
    "HUGE_MUSHROOM_1",  # brown mushroom block
    "HUGE_MUSHROOM_2",  # red mushroom block
    "LOG_2:1",  # dark oak
    "ENCHANTED_SNOW_BLOCK",
    "GOLDEN_TOOTH",
    "STRING",
    "RABBIT_FOOT",
    "REDSTONE",
    "ENCHANTED_CACTUS_GREEN",
    "ENCHANTED_CARROT_STICK",
    "ENCHANTED_LAPIS_LAZULI_BLOCK",
    "ENCHANTED_COOKIE",
    "ENCHANTED_ENDSTONE",
    "ENCHANTED_SAND",
    "ENCHANTED_STRING",
    "STRONG_FRAGMENT",
    "SLIME_BALL",
    "ENCHANTED_ACACIA_LOG",
    "SNOW_BALL",
    "ENCHANTED_EGG",
    "SAND",
    "RAW_CHICKEN",
    "ENCHANTED_LAPIS_LAZULI",
    "ENCHANTED_GHAST_TEAR",
    "ENCHANTED_COCOA",
    "SEEDS",
    "ENCHANTED_LEATHER",
    "ENCHANTED_SPONGE",
    "HAY_BLOCK",
    "FLINT",
    "INK_SACK",
    "WOLF_TOOTH",
    "ENCHANTED_SPRUCE_LOG",
    "ENCHANTED_ROTTEN_FLESH",
    "ENCHANTED_GRILLED_PORK",
    "ENCHANTED_NETHER_STALK",
    "ENCHANTED_REDSTONE_BLOCK",
    "ENCHANTED_QUARTZ_BLOCK",
    "GREEN_CANDY",
    "ENCHANTED_REDSTONE",
    "ENCHANTED_REDSTONE_LAMP",
    "GRAVEL",
    "MELON",
    "ENCHANTED_LAVA_BUCKET",
    "ENCHANTED_PACKED_ICE",
    "RAW_FISH:3",  # pufferfish
    "ENCHANTED_PRISMARINE_SHARD",
    "ENCHANTED_CARROT_STICK",
    "ENCHANTED_IRON_BLOCK",
    "BONE",
    "RAW_FISH:2",  # clownfish
    "RAW_FISH:1",  # raw salmon
    "REVENANT_FLESH",
    "ENCHANTED_PORK",
    "ENCHANTED_GLOWSTONE",
    "FEATHER",
    "NETHERRACK",
    "SPONGE",
    "BLAZE_ROD",
    "ENCHANTED_DARK_OAK_LOG",
    "YOUNG_FRAGMENT",
    "ENCHANTED_CLOWNFISH",
    "ENCHANTED_GOLD",
    "ENCHANTED_RAW_CHICKEN",
    "ENCHANTED_WATER_LILY",
    "LOG:1",  # spruce
    "CATALYST",
    "LOG:3",  # jungle
    "LOG:2",  # birch
    "ENCHANTED_GLOWSTONE_DUST",
    "ENCHANTED_INK_SACK",
    "ENCHANTED_CACTUS",
    "ENCHANTED_SUGAR_CANE",
    "ENCHANTED_COOKED_SALMON",
    "ENCHANTED_SEEDS",
    "LOG",  # oak
    "GHAST_TEAR",
    "ENCHANTED_ENDER_PEARL",
    "UNSTABLE_FRAGMENT",
    "PURPLE_CANDY",
    "ENCHANTED_FERMENTED_SPIDER_EYE",
    "ENCHANTED_GOLD_BLOCK",
    "ENCHANTED_JUNGLE_LOG",
    "ENCHANTED_FLINT",
    "IRON_INGOT",
    "ENCHANTED_EMERALD_BLOCK",
    "ENCHANTED_CLAY_BALL",
    "GLOWSTONE_DUST",
    "GOLD_INGOT",
    "REVENANT_VISCERA",
    "TARANTULA_SILK",
    "ENCHANTED_MUTTON",
    "SUPER_EGG",
    "SUPER_COMPACTOR_3000",
    "ENCHANTED_IRON",
    "STOCK_OF_STONKS",
    "ENCHANTED_HAY_BLOCK",
    "ENCHANTED_BONE",
    "ENCHANTED_PAPER",
    "ENCHANTED_DIAMOND_BLOCK",
    "SUPERIOR_FRAGMENT",
    "EMERALD",
    "ENCHANTED_RABBIT_FOOT",
    "ENCHANTED_ICE",
    "HOT_POTATO_BOOK",
    "CLAY_BALL",
    "OLD_FRAGMENT",
    "GREEN_GIFT",
    "PACKED_ICE",
    "WATER_LILY",  # lily pad
    "LOG_2",  # acacia
    "HAMSTER_WHEEL",
    "ENCHANTED_OBSIDIAN",
    "ENCHANTED_COAL",
    "ENCHANTED_QUARTZ",
    "COAL",
    "ENDER_PEARL",
    "ENCHANTED_COAL_BLOCK",
    "ENCHANTED_PRISMARINE_CRYSTALS",
    "ENCHANTED_WET_SPONGE",
    "ENDER_STONE",  # end stone
    "ENCHANTED_RAW_FISH",
    "QUARTZ",
    "FOUL_FLESH",
    "RAW_BEEF",
    "ENCHANTED_EYE_OF_ENDER",
    "SUGAR_CANE",
    "MAGMA_CREAM",
    "RED_GIFT",
    "ENCHANTED_RAW_BEEF",
    "ENCHANTED_SLIME_BLOCK",
    "ENCHANTED_FEATHER",
    "ENCHANTED_OAK_LOG",
    "RABBIT_HIDE",
    "WHITE_GIFT",
    "RABBIT",
    "NETHER_STALK",
    "SULPHUR",
    "ENCHANTED_CARROT",
    "ENCHANTED_PUMPKIN",
    "ROTTEN_FLESH",
    "ENCHANTED_COOKED_FISH",
    "OBSIDIAN",
    "ENCHANTED_MAGMA_CREAM",
    "ENCHANTED_FIREWORK_ROCKET",
    "LEATHER",
    "ENCHANTED_COOKED_MUTTON",
    "ENCHANTED_RABBIT",
    "ENCHANTED_BREAD",
    "ENCHANTED_CHARCOAL",
    "ENCHANTED_BLAZE_POWDER",
    "SUMMONING_EYE",
    "SNOW_BLOCK",
    "ENCHANTED_BAKED_POTATO",
    "COMPACTOR",
    "ENCHANTED_DIAMOND"
]


app = Flask(__name__)

f = requests.get(
    "https://api.hypixel.net/skyblock/bazaar?key=[not allowed to show key]").json()


itemName = f["products"]
for x in product:
    buyPrice = f["products"][x]["sell_summary"][0]["pricePerUnit"]


@app.route('/')
def price():
    return render_template("index.html", itemName=itemName, buyPrice=buyPrice)


if __name__ == "__main__":
    app.run(debug=True)

现在我后来看到的 "product" 数组并不是真正需要的,因为如果我只是执行 "itemName = f["products"]["product_id"]" 它仍然会写入所有产品名称,但我还想要价格。我不知何故让它在一行中显示价格的地方工作(不记得如何),但如果我这样做 buyPrice = str(buyPrice) 它在网页上看起来像这样: 4 5 6 . 1

这不是我想要的,它还在每个名字后面都写着完全相同的数字,我想让它说出那个确切产品的价格。

这是我的 HTML:

{% for item in itemName %}
    <h1>{{ item }}</h1>
    {% for price in buyPrice %}
    <h1>{{ price }}</h1>
    {% endfor %} 
{% endfor %}

这里是 JSON API 的链接:https://jsonblob.com/b136acab-9ac0-11ea-add9-a360c1d2e6bd

所以我想要它做的只是取名字,然后在名字下打印买卖价格,以及我可以从 API 获取的一些其他信息。

【问题讨论】:

    标签: python api flask


    【解决方案1】:

    我对您的原始代码进行了一些更改,得到了一个工作版本,该版本显示了每种产品的当前买入/卖出价格及其买入/卖出历史价格。

    # app.py
    import json
    import requests
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def price():
        products_api_endpoint = "https://api.hypixel.net/skyblock/bazaar?key=[not allowed to show key]"
        response = requests.get(products_api_endpoint).json()
    
        # I used a file for local testing because I didn't have access to the API you use
        # response = json.load(open("/tmp/response.json", "r")) 
    
        products = [
            {
                "id": product["product_id"],
                "sell_price": product["quick_status"]["sellPrice"],
                "buy_price": product["quick_status"]["buyPrice"],
                "sell_summary": product["sell_summary"],
                "buy_summary": product["buy_summary"]
            }
            for product in response["products"].values()
        ]
        # let's only send a few of them to the frontend (you can apply your own filtering here)
        # (comment-out next line if you want to show all the data at once)
        products = products[:3]  # filtering
        return render_template("index.html", products=products)
    
    
    if __name__ == "__main__":
        app.run(debug=True)
    
    <!-- templates/index.html -->
    
    {% for product in products %}
        <p>
            <b>ID: {{ product.id }} -- sell price: {{ product.sell_price }} -- buy price: {{ product.buy_price }} </b>
            <p>
                Sell price history: &nbsp
                {% for sell in product.sell_summary %}
                    {{ sell.pricePerUnit }}, &nbsp
                {% endfor %}
            </p>
            <p>
                Buy price history: &nbsp
                {% for buy in product.buy_summary %}
                    {{ buy.pricePerUnit }}, &nbsp
                {% endfor %}
            </p>
        </p>
    {% endfor %}
    

    它呈现如下图所示的结果。当然,你可以应用任何你想让它看起来更漂亮的 CSS 样式。

    【讨论】:

    • 啊啊谢谢!!!快速提问,要删除历史记录,我该怎么做?或者我用什么来删除它?
    • 您可以删除 HTML 文件的第 6-15 行。您还可以从 app.py 中删除第 20 和 21 行,因为它们不再需要了。
    • 我在这里遇到另一个问题,现在“product_id”不存在,API 转到产品 -> 然后这里是产品名称 -> quick_status。这意味着在[“quick_status”]之前,我们需要[“products”]和[每个产品名称],我该如何解决这个@Piero Hernandez?
    • 如果您查看我共享的 python 代码,在列表理解中它会显示 for product in response["products"].values(),它访问响应的 products 字段并获取每个字段的所有 values()。你能以某种方式显示你当前的代码和你看到的错误吗?
    • 这是我的代码:pastebin.com/Fbb8YW9u 我得到的错误是“Keyerror: x”,x 是第一个“product_id”,但我将“product_id”更改为“products”,现在它显示“快速状态”。我认为这是因为它正在寻找“quick_status”,但由于json是产品->产品名称-> quick_status,它无法找到它,因为“产品名称”在路上。有点难以解释,但希望我的代码可以提供帮助!
    【解决方案2】:

    看起来buyPrice 是一个浮点值,对应于您提供给我们的数据中的12.7。然后,在您的模板中,您尝试通过执行 for price in buyPrice 对其进行迭代,这会引发错误。

    根据您想要执行的操作,您应该将 pricePerUnit 值提取到一个数组中,然后可以在模板中使用,或者修改模板以仅期望一个浮点值。

    【讨论】:

    • 好的,是的,我试图将我想要的所有值放入一个数组中,但它并没有真正起作用,因为它只写了第一个,而不仅仅是“停止”了 for 循环,没有花费这么多时间,所以可能应该尝试更多。您会建议我制作一个包含所有内容的数组,还是制作多个数组?例如“buyPrice”“sellPrice”等?然后最后将每个值返回到我的 HTML 中?
    • 好的,所以我试了一下,得到了积极的结果(可能第一次做错了),现在我得到了每一个 buyPrice 值,但它说例如“BROWN_MUSHROOM”然后是每个价格对于每个产品,您如何将其“锁定”到您正在寻找的产品中?我的意思是我只想要 brown_mushroom 上的 15.3 和钻石上的 x 等
    • 不确定你的意思 - 你能澄清一下吗?
    • 让我把我的代码链接给你,这里是html:pastebin.com/ssUxnjN9,这里是python:pastebin.com/2q800y7V,这里是输出:pastebin.com/N7gKG3KF(只取前几个)知道你可以看到它正常打印出产品名称,但它打印每个产品的所有价格,每个产品。我不想在蘑菇(14.7)上打印价格,然后在 ink_sack:3 (5.5) 和 ink_sack:4 (4.2) 上打印价格等等。
    • 您从哪里获得每个值的值?我在您在问题中提供的数据中看不到这些值。如果您只想要第一个(或特定索引的),只需在 buyPrice 数组中填充您要为每个数组显示的值。但是,这现在超出了原始问题的范围,因此我建议在 SO 上搜索类似问题或提出新问题。如果对您有帮助,请务必接受此答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 2021-10-28
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多