You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中将自定义对象列表正确转换为JSON并保存至文件的最佳方案

解决自定义对象列表转JSON并正确保存的问题

你的问题出在每次循环单独把单个对象的字典dump到文件里,这样生成的内容是多个独立的JSON对象,而合法的JSON文档只能有一个顶级元素(要么是数组,要么是单个对象),所以解析器会报错。

下面是几种正确的实现方式,按推荐程度排序:

方法1:一次性转换整个列表为字典列表并保存(推荐)

先把所有BountyItem对象转成字典,组成一个列表,然后一次性用json.dump写入文件,这样会自动生成合法的JSON数组格式:

import json
import requests
from bs4 import BeautifulSoup

list1 = []

class BountyItem:
    def __init__(self, heading, price, tickets):
        self.heading = heading
        self.price = price
        self.tickets = tickets

url = 'https://www.bountycompetitions.co.uk/live-competitions/'
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
result = soup.find_all(class_='product')

for item in result:
    item_heading = item.find('a', attrs={'class': 'product-item-heading'})
    item_price = item.find('span', attrs={'class': 'woocommerce-Price-amount amount'})
    item_tickets = item.find('span', attrs={'class': 'status'})
    # 直接创建对象加入列表即可,无需重复实例化
    b_item = BountyItem(item_heading.text, item_price.text[1:], item_tickets.text)
    list1.append(b_item)

# 将对象列表转换为字典列表
dict_list = [item.__dict__ for item in list1]

# 一次性写入整个合法的JSON数组
with open("/home/pr0xibus/Documents/test.txt", 'w') as file:
    json.dump(dict_list, file, indent=4)  # indent=4用于格式化输出,可选

生成的合法JSON内容示例:

[
    {
        "heading": "Highland Park – Valhalla Collection – Odin 16 year old Whisky",
        "price": "1.20",
        "tickets": "249 Left"
    },
    {
        "heading": "Tom Ford Rose Prick Collection",
        "price": "0.99",
        "tickets": "189 Left"
    }
]

方法2:自定义JSON编码器(更优雅的对象转JSON方式)

如果不想手动调用__dict__,可以自定义一个JSON编码器,这样直接dump对象列表也能正确转换:

# 自定义编码器
class BountyItemEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, BountyItem):
            return obj.__dict__
        # 其他类型交给默认逻辑处理
        return super().default(obj)

# 保存时指定编码器
with open("/home/pr0xibus/Documents/test.txt", 'w') as file:
    json.dump(list1, file, cls=BountyItemEncoder, indent=4)

这种方式更适合后续扩展(比如对象有需要特殊处理的属性时),代码可读性也更强。

为什么原来的方法不合法?

你之前的代码每次循环打开文件追加写入单个JSON对象,最终文件内容是多个独立的{...}块,既没有用[]包裹成数组,也没有用逗号分隔。而JSON规范要求整个文档只能有一个顶级值,所以这种内容无法被标准JSON解析器正确解析。

内容的提问来源于stack exchange,提问作者pr0xibus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 05:42:48