如何用Python编辑复杂的Json数据?

h43kikqp  于 2023-03-04  发布在  Python
关注(0)|答案(1)|浏览(147)

我有一个json产品,如下所示,在这个json对象里面,有一个单元名的json数组,这个数组里面有多个对象,但是数量不固定,键和值 已知Json数组命名单元中第一个Json对象的值。这些值 包含在first_keys =[]和first_values中 =[]。
我现在要做的是:例如,要计算第二个json对象的"碳水化合物"值,第二个json对象中的amount值将乘以第一个json对象中的"碳水化合物"值,然后除以第一个json对象中的amount值。3.要计算json对象内部的"蛋白质"值,请将第三个json对象中的"量"变量乘以第一个json对象中的蛋白质值,然后除以第一个json对象内部的"量"变量。

{
    "food_id": 0,
    "food_name": "NAME",
    "food_image": "IMAGE",
    "food_kcal": "KCAL",
    "food_url": "FOOD_URL",
    "food_description": "DESC",
    "meal_time": "null",
    "food_category": "",
    "food_first_unit": "Yemek Kaşığı",
    "carb_percent": "72",
    "protein_percent": "23",
    "fat_percent": "4",
    "units": [
        {
            "unit": "100 Gram",
            "amount": "100",
            "kcal": "505 kcal",
            "carb": "65 g",
            "fiber": "3 g",
            "protein": "5 g",
            "fat": "24 g",
            "saturated_fat": "10 g",
            "salt": "0.7 g",
            "sugar": "34 g"
        },
        {
            "unit": "1 Adet",
            "amount": "5",
            "kcal": "",
            "carb": "",
            "fiber": "",
            "protein": "",
            "fat": "",
            "saturated_fat": "",
            "salt": "",
            "sugar": ""
        },
        {
            "unit": "1 Porsiyon",
            "amount": "30",
            "kcal": "",
            "carb": "",
            "fiber": "",
            "protein": "",
            "fat": "",
            "saturated_fat": "",
            "salt": "",
            "sugar": ""
        },
        {
            "unit": "1 Paket",
            "amount": "90",
            "kcal": "",
            "carb": "",
            "fiber": "",
            "protein": "",
            "fat": "",
            "saturated_fat": "",
            "salt": "",
            "sugar": ""
        }
    ]
}

我的代码:

url = 'www.example.com'
response = requests.get(url)
response.encoding = 'utf-8'
html = response.text

soup = BeautifulSoup(html, 'html.parser')
items = soup.find_all('li')

units = []
first_key = []
first_values = []
names = []
grams = []

for item in items:
    name = item.get('data-ntr-srvname-param')
    if(str(name) not in "None"):
        names.append(str(name).replace("Gramda", "Gram"))

items = soup.find_all("li", {"data-ntr-gram-param": True})
for item in items:
    grams.append(float(item["data-ntr-gram-param"]))

for row in soup.select('table[data-ntr-target="facts"] tr'):
    name = row.select_one('td:nth-of-type(1)')
    value = row.select_one('td:nth-of-type(2)')

    if name is not None and value is not None:
        first_key.append(name.text.strip())
        first_values.append(value.text.strip())

for index, gram in enumerate(grams):
    replacedGram=str(gram).replace(".0", "")
    units.append({
        "unit": f"{names[index]}",
        "amount": f"{replacedGram}"
    })


data_dict = dict(zip(first_key, first_values))
for index, gram in enumerate(grams):
    units[index].update(data_dict)

json_obj = {
    "food_id": 0,
    "food_name": "NAME",
    "food_image": "IMAGE",
    "food_kcal": "KCAL",
    "food_url": "FOOD_URL",
    "food_description": "DESC",
    "meal_time": "null",
    "food_category":"",
    "food_first_unit": "FIRST",
    "carb_percent": "72",
    "protein_percent": "23",
    "fat_percent": "4",
    "units": units
}

print("***************")

print(json.dumps(json_obj, indent=4, ensure_ascii=False))

print("***************")
x8diyxa7

x8diyxa71#

为此,我们需要跟踪参考量,并将单位中的值拆分为参考单位。
json_obj更改为data,下面的代码将获得结果。

import pprint

reference = data["units"][0]
results = [reference]

for each in data["units"][1:]:
    results.append(
        dict(unit=each['unit'], amount=each['amount'], **{
            key: f"{float(each['amount']) / float(reference['amount']) * float(reference[key].split(' ')[0]):.2f} {reference[key].split(' ')[-1]}"
            for key, val in each.items()
            if key not in ["unit", "amount"]
        })
    )

for result in results:
    print(result)

输出:

{'unit': '100 Gram', 'amount': '100', 'kcal': '505 kcal', 'carb': '65 g', 'fiber': '3 g', 'protein': '5 g', 'fat': '24 g', 'saturated_fat': '10 g', 'salt': '0.7 g', 'sugar': '34 g'}
{'unit': '1 Adet', 'amount': '5', 'kcal': '25.25 kcal', 'carb': '3.25 g', 'fiber': '0.15 g', 'protein': '0.25 g', 'fat': '1.20 g', 'saturated_fat': '0.50 g', 'salt': '0.03 g', 'sugar': '1.70 g'}
{'unit': '1 Porsiyon', 'amount': '30', 'kcal': '151.50 kcal', 'carb': '19.50 g', 'fiber': '0.90 g', 'protein': '1.50 g', 'fat': '7.20 g', 'saturated_fat': '3.00 g', 'salt': '0.21 g', 'sugar': '10.20 g'}
{'unit': '1 Paket', 'amount': '90', 'kcal': '454.50 kcal', 'carb': '58.50 g', 'fiber': '2.70 g', 'protein': '4.50 g', 'fat': '21.60 g', 'saturated_fat': '9.00 g', 'salt': '0.63 g', 'sugar': '30.60 g'}

我们使用data["units"][0]data["units"][1:]将引用json从其他数据中分离出来,这仅在至少有1个units对象时有效。
然后为了乘以正确的数值,我们将它们转换为floats,并使用.2f的f-string方法将值舍入到两位小数(使其再次成为字符串)。如果我们在这里不使用舍入,我们将遇到浮点精度错误。

相关问题