简体   繁体   English

如何从 API 中获取信息?

[英]How do I grab information from an API?

So I ran into some problem when I tried to get information from an API, I can grab the names of each product, but well for one: When I try to return the "float" value (the price of the product) I get this error: TypeError: 'float' object is not iterable因此,当我尝试从 API 获取信息时遇到了一些问题,我可以获取每个产品的名称,但对于一个来说很好:当我尝试返回“浮动”值(产品的价格)时,我得到了这个错误:TypeError:'float' object 不可迭代

This is my Python code:这是我的 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)

Now the "product" array I later saw was not really needed, because if I just do "itemName = f["products"]["product_id"]" it still writes all the product names, but I also want the prices.现在我后来看到的“产品”数组并不是真正需要的,因为如果我只是执行“itemName = f[“products”][“product_id”]”,它仍然会写入所有产品名称,但我还想要价格。 I somehow got it to work where it says the prices in one line (don't remember how), but if I do buyPrice = str(buyPrice) it looks like this on the webpage: 4 5 6. 1我不知何故让它在一行中显示价格的地方工作(不记得如何),但如果我这样做了 buyPrice = str(buyPrice) 它在网页上看起来像这样:4 5 6. 1

Which is not what I want, it also says the exact same numbers after every name, I want it to say the price of that exact product.这不是我想要的,它还在每个名字后面都写着完全相同的数字,我想让它说出那个确切产品的价格。

here is my HTML:这是我的 HTML:

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

And here is a link to the JSON API: https://jsonblob.com/b136acab-9ac0-11ea-add9-a360c1d2e6bd这里是 JSON API 的链接: https://jsonblob.com/b136acab-9ac0-12ea-bd-add-9

So what I want it to do is just take the first name, then under the name print the sell and buy price, and some other information I can grab from the API.所以我想要它做的只是取名字,然后在名称下打印买卖价格,以及我可以从 API 获取的一些其他信息。

I did some changes to your original code and got a working version that shows both the current buy/sell price of each product and its buy/sell historical prices.我对您的原始代码进行了一些更改,并获得了一个工作版本,该版本显示了每种产品的当前买入/卖出价格及其买入/卖出历史价格。

# 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 %}

It renders the results as shown in the following image.它呈现如下图所示的结果。 You can apply any CSS styles you wish to make it look prettier of course.当然,您可以应用任何 CSS styles 让它看起来更漂亮。

结果

It looks like buyPrice is a single float value, corresponding to 12.7 in the data you give us.看起来buyPrice是一个浮点值,对应于您提供给我们的数据中的12.7 Then, in your template, you're trying to iterate over it by doing for price in buyPrice , which throws the error.然后,在您的模板中,您尝试通过for price in buyPrice来迭代它,这会引发错误。

Depending on what you want to do, you should either extract the pricePerUnit values into an array that you can then use in the template, or modify the template to expect only a single float value.根据您想要执行的操作,您应该将pricePerUnit值提取到一个数组中,然后您可以在模板中使用该数组,或者修改模板以仅期望一个浮点值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM