news 2026/7/30 10:33:22

Python JSON序列化格式化全解析:从indent参数到性能优化实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python JSON序列化格式化全解析:从indent参数到性能优化实战

1. 从一次数据导出“乱码”说起:JSON换行问题的本质

前几天,我帮一个做数据分析的朋友处理一个数据导出任务。他用Python脚本从数据库里拉了一批用户行为日志,用json.dump写入文件,准备交给前端同事做可视化。结果前端同事打开文件一看就懵了,说文件“坏了”,在编辑器里显示为长长的一行,根本没法看,更别提解析了。朋友的第一反应是编码问题,折腾了半天encoding='utf-8',结果当然无济于事。这其实是一个典型的场景:我们生成了一个语法完全正确、机器可读的JSON文件,但对人眼来说,它却是“不可读”的。

这个问题的根源,就在于JSON的序列化格式化(Pretty-Printing)。默认情况下,Python的json.dumps()json.dump()函数为了追求极致的紧凑性和传输效率,会移除所有不必要的空白字符,包括换行符和缩进。这就导致了一个复杂的、嵌套层级深的JSON对象,被压缩成了一大坨字符串。对于机器,这没问题;但对于需要阅读、调试、版本对比的人类开发者来说,这简直是灾难。

所以,“处理JSON文件写入换行问题”,远不止是加个\n那么简单。它关乎代码的可维护性、团队协作的便利性,以及数据调试的效率。一个格式良好的JSON文件,结构清晰,层次分明,能让你一眼就看出数据的脉络。接下来,我们就深入聊聊,在Python里,如何优雅地控制JSON的输出格式,让它既对机器友好,也对人眼友好。

2.json.dumps()json.dump():格式化参数全解析

Python的json模块提供了两个核心函数用于序列化:dumps()(将对象转为JSON字符串)和dump()(将对象序列化并写入文件)。解决换行和格式化问题的钥匙,就藏在它们的可选参数里。很多人只知道indent,但其实还有几个参数组合使用,效果更佳。

2.1indent:缩进,格式化之魂

indent参数是控制格式化的核心。它指定了缩进使用的空白字符数量。

import json data = { "name": "Alice", "age": 30, "skills": ["Python", "Data Analysis"], "address": { "city": "Shanghai", "zipcode": "200000" } } # 默认紧凑模式 compact_json = json.dumps(data) print("紧凑模式:") print(compact_json) # 输出: {"name": "Alice", "age": 30, "skills": ["Python", "Data Analysis"], "address": {"city": "Shanghai", "zipcode": "200000"}} # 使用缩进(4个空格) pretty_json = json.dumps(data, indent=4) print("\n格式化模式 (indent=4):") print(pretty_json) # 输出: # { # "name": "Alice", # "age": 30, # "skills": [ # "Python", # "Data Analysis" # ], # "address": { # "city": "Shanghai", # "zipcode": "200000" # } # }

关键点

  • indent可以是一个整数(如2, 4),表示缩进的空格数。这是最常用的方式,4个空格是社区常见的约定。
  • indent也可以是一个字符串(如'\t'),表示使用制表符进行缩进。但请注意,JSON规范本身建议使用空格,且不同环境下制表符的显示宽度可能不一致,在团队协作中可能引发格式争议,一般不建议使用
  • 只要设置了indent,对象和数组的元素就会自动换行。

2.2separators:自定义分隔符,微调格式

separators参数是一个元组(item_separator, key_separator),用于控制JSON中不同部分之间的分隔符。

  • item_separator:数组元素之间、对象键值对之间的分隔符。默认是', '(逗号加一个空格)。
  • key_separator:键和值之间的分隔符。默认是': '(冒号加一个空格)。

当你设置了indent,默认的分隔符逻辑会配合缩进,将逗号放在行尾。但你可以通过separators进行微调。

# 使用默认分隔符(逗号后空格) print(json.dumps(data, indent=2)) # 键值对之间是 “: ”(冒号+空格) # 元素之间是 “, ”(逗号+空格),且逗号在行尾 # 自定义分隔符:去掉多余空格,让格式更紧凑(但仍保持换行) custom_sep_json = json.dumps(data, indent=2, separators=(',', ': ')) print("\n自定义分隔符 (',', ': '):") print(custom_sep_json) # 注意观察冒号后的空格被保留,但逗号后不再有空格。

一个实用的技巧:如果你想生成极度紧凑但仍带缩进的JSON(例如用于某些对空格敏感的环境),可以设置separators=(',', ':')来移除所有分隔符中的空格。但这样可读性会略微下降。

2.3sort_keys:键排序,保证输出确定性

sort_keys参数是一个布尔值。当设置为True时,字典的输出将按照键的字母顺序排序。

unsorted_data = {"z": 1, "a": 2, "m": 3} print("不排序:") print(json.dumps(unsorted_data, indent=2)) # 输出顺序可能是 “z“, “a“, “m“(Python 3.7+ 保持插入顺序) print("\n按键排序:") print(json.dumps(unsorted_data, indent=2, sort_keys=True)) # 输出顺序永远是 “a“, “m“, “z“

为什么这很重要?虽然Python 3.7以后字典能记住插入顺序,但排序能保证每次运行的输出都是一致的。这在以下场景非常关键:

  1. 版本控制(如Git):如果JSON文件是配置文件,排序后,只有内容变更才会导致diff,键的顺序改变不会产生无关的diff行,让代码审查更清晰。
  2. 生成哈希或签名:需要基于JSON字符串生成MD5、SHA等校验和时,键的顺序不一致会导致完全不同的哈希值。排序可以确保输入稳定。
  3. 自动化测试中的断言:比较两个JSON字符串是否相等时,排序可以避免因键顺序不同导致的误判。

注意sort_keys排序是基于字符串的Unicode码点,对于中文等非ASCII键,排序结果可能不符合语言习惯。

2.4 组合使用:生产环境的最佳实践

在实际项目中,我通常会组合使用这些参数,以达到可读性、一致性和文件大小的平衡。

def write_pretty_json(data, filepath): """ 将数据以美观、稳定的格式写入JSON文件。 这是我在大多数项目中的标准写法。 """ with open(filepath, 'w', encoding='utf-8') as f: json.dump( data, f, ensure_ascii=False, # 允许非ASCII字符(如中文)原样输出 indent=2, # 2空格缩进,比4空格更省空间 sort_keys=True, # 键排序,保证输出一致性 separators=(',', ': ') # 使用标准分隔符 ) print(f"JSON文件已写入: {filepath}") # 使用示例 write_pretty_json(data, 'output_pretty.json')

打开生成的output_pretty.json,你会得到一个结构清晰、键已排序、中文正常显示的文件,非常适合人类阅读和版本管理。

3. 进阶场景:处理自定义对象与复杂结构

简单的字典列表用上面的方法就够了。但现实中的数据往往更复杂:你可能需要序列化自定义类的实例、datetime对象、numpy数组,或者需要处理循环引用。这时就需要用到defaultcls参数。

3.1 使用default参数处理不可序列化对象

当你尝试序列化一个json模块不认识的对象(比如一个自定义的User类实例)时,会直接抛出TypeError: Object of type User is not JSON serializable

default参数允许你指定一个函数,该函数会接收不可序列化的对象,并返回一个可以被json模块序列化的值(通常是字典、列表、字符串或数字)。

import json from datetime import datetime from decimal import Decimal class User: def __init__(self, name, join_date, balance): self.name = name self.join_date = join_date # datetime 对象 self.balance = balance # Decimal 对象,用于精确金融计算 # 创建一个包含复杂对象的字典 user = User("Bob", datetime.now(), Decimal("1234.56")) data_to_dump = {"user_info": user} def complex_encoder(obj): """ 自定义序列化函数。 """ if isinstance(obj, datetime): # 将datetime转换为ISO格式字符串 return obj.isoformat() elif isinstance(obj, Decimal): # 将Decimal转换为字符串(避免浮点精度问题)或浮点数 return float(obj) elif isinstance(obj, User): # 将User对象转换为字典 return { "name": obj.name, "join_date": obj.join_date, # 这里会递归调用,最终被上面的datetime分支处理 "balance": obj.balance } else: # 对于其他无法处理的类型,抛出TypeError raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable") # 使用 default 参数 json_str = json.dumps(data_to_dump, default=complex_encoder, indent=2) print(json_str) # 输出类似: # { # "user_info": { # "name": "Bob", # "join_date": "2023-10-27T10:30:00.123456", # "balance": 1234.56 # } # }

实操心得:在default函数里,一定要记得处理完自定义类型后,最后抛出一个清晰的TypeError。这能帮助你在遇到未预料到的类型时快速定位问题,而不是让json.dumps静默失败或返回一个None

3.2 继承JSONEncoder实现更优雅的序列化

对于需要频繁序列化特定类型对象的项目,定义一个继承自json.JSONEncoder的子类会更整洁。你需要重写它的default(self, obj)方法。

class CustomJSONEncoder(json.JSONEncoder): """自定义JSON编码器,处理datetime、Decimal和User对象。""" def default(self, obj): if isinstance(obj, datetime): return obj.isoformat() elif isinstance(obj, Decimal): return float(obj) elif isinstance(obj, User): return obj.__dict__ # 简单起见,直接使用__dict__。也可手动构造字典。 # 让父类处理其他情况,最终会抛出TypeError return super().default(obj) # 使用方式1:通过cls参数 json_str_with_encoder = json.dumps(data_to_dump, cls=CustomJSONEncoder, indent=2) # 使用方式2:直接实例化编码器 encoder = CustomJSONEncoder(indent=2, sort_keys=True) json_str_direct = encoder.encode(data_to_dump) print(json_str_with_encoder)

使用自定义编码器类的好处是封装性好,可以复用。你可以将这个CustomJSONEncoder类放在项目的工具模块中,然后在任何需要序列化的地方导入使用,保持代码一致性。

3.3 处理循环引用与深度限制

有时,你的数据对象可能存在循环引用(A引用B,B又引用A)。json模块默认无法处理这种情况,会抛出RecursionError

obj_a = {} obj_b = {'ref': obj_a} obj_a['ref'] = obj_b # 循环引用 # 这行会报错: RecursionError # json.dumps(obj_a)

对于循环引用,通常需要在业务逻辑层面避免,或者在序列化前将对象“展平”。json模块本身不提供自动处理循环引用的功能。

另外,json.dumps有一个skipkeys参数(默认为False),当字典的键不是基本类型(str, int, float, bool, None)时,如果skipkeys=True,则会跳过这些键值对而不是报错。但这种情况比较少见。

4. 性能、文件大小与可读性的权衡

美观的格式化是有代价的:文件体积增大序列化性能略有下降。缩进和换行符增加了额外的字节,sort_keys排序也需要计算时间。在处理海量数据(比如GB级别的JSON日志)时,这个代价需要仔细权衡。

4.1 性能对比测试

我们来做个简单的性能测试:

import json import time import sys # 生成一个较大的嵌套数据结构 big_data = {f'key_{i}': {'nested': list(range(100))} for i in range(1000)} formats = [ ("紧凑模式", {"indent": None, "separators": (',', ':')}), ("美化模式 (indent=2)", {"indent": 2}), ("美化并排序 (indent=2, sort_keys=True)", {"indent": 2, "sort_keys": True}), ] for name, params in formats: start = time.perf_counter() json_str = json.dumps(big_data, **params) end = time.perf_counter() time_cost = (end - start) * 1000 # 毫秒 size = sys.getsizeof(json_str) / 1024 # KB print(f"{name:35} | 耗时: {time_cost:6.2f} ms | 大小: {size:7.2f} KB")

在我的机器上,输出可能类似:

紧凑模式 | 耗时: 15.23 ms | 大小: 781.45 KB 美化模式 (indent=2) | 耗时: 18.67 ms | 大小: 1172.18 KB 美化并排序 (indent=2, sort_keys=True) | 耗时: 22.45 ms | 大小: 1172.18 KB

可以看到,美化格式的文件大小增加了约50%,序列化时间也增加了约20%-50%。对于排序,额外的开销取决于数据量。

4.2 不同场景下的策略选择

根据你的需求,可以参考以下策略:

场景推荐配置理由
网络传输/API响应indent=None,separators=(',', ':')最小化数据体积,减少带宽占用和传输时间。
配置文件、本地数据存储indent=2,sort_keys=True极高的可读性和版本控制友好性。文件大小增加可以接受。
日志文件(用于调试)indent=2方便开发人员直接tail查看日志结构。如果日志量巨大,可以考虑只在调试级别启用美化,生产环境用紧凑模式。
超大JSON文件(>100MB)indent=None,或考虑换用更高效的格式(如MessagePack、Parquet)性能和存储空间是首要考虑因素。可以考虑流式处理,而非一次性加载整个JSON。
需要人工审核的数据交换indent=4,ensure_ascii=False提供最佳的可读性,特别是包含非英文字符时。

一个折中的技巧:如果你需要经常查看紧凑的JSON,但又不想保存为美化后的大文件,可以使用命令行工具快速格式化。例如,在Unix系统上,你可以用python -m json.tool < compact.json来漂亮地打印一个JSON文件。在VSCode中,快捷键Alt+Shift+F(或Cmd+Shift+P后输入Format Document)可以自动格式化JSON文件。

5. 实战避坑:编码、解码与文件操作细节

解决了格式化问题,在实际读写文件时,还有一些细节坑点需要注意。

5.1 字符编码:ensure_ascii参数详解

这是中文开发者最常踩的坑之一。json.dumpsensure_ascii参数默认为True

  • ensure_ascii=True(默认):所有非ASCII字符(如中文、日文、表情符号)都会被转义为\uXXXX的Unicode转义序列。

    data = {"city": "上海"} print(json.dumps(data)) # 输出: {"city": "\u4e0a\u6d77"}

    这样做保证了生成的JSON字符串是纯ASCII字符集,在任何环境下都不会有编码问题,但人类完全无法阅读。

  • ensure_ascii=False:非ASCII字符会原样保留在生成的字符串中。

    print(json.dumps(data, ensure_ascii=False)) # 输出: {"city": "上海"}

    可读性极佳。但是,你必须确保在写入文件时指定正确的编码(通常是utf-8),并且在读取该文件的系统上也使用相同的编码。

最佳实践:在写入文件时,总是同时设置ensure_ascii=Falseencoding='utf-8'

with open('data_chinese.json', 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2)

5.2 文件写入模式:'w''wb'

  • 'w'模式:文本模式。需要指定encodingjson.dump()接受一个文件对象,会向其中写入字符串。
  • 'wb'模式:二进制模式。json.dump()不能直接用于二进制文件对象。但你可以先dumps()成字符串,再编码为字节写入。
# 正确:文本模式写入 with open('output.json', 'w', encoding='utf-8') as f: json.dump(data, f, indent=2) # 错误:尝试以二进制模式写入 # with open('output.json', 'wb') as f: # json.dump(data, f) # 会报错:write() argument must be str, not bytes # 变通:先序列化成字符串,再以二进制写入(不常见,但可行) json_str = json.dumps(data, indent=2) with open('output.json', 'wb') as f: f.write(json_str.encode('utf-8'))

除非有特殊需求(如与其他二进制协议混合),否则始终使用文本模式'w'并指定utf-8编码。

5.3 读取与解析:json.load()的注意事项

读取时,同样要注意编码。

# 正确:指定编码读取 with open('output_pretty.json', 'r', encoding='utf-8') as f: loaded_data = json.load(f) # 如果文件是其他编码(如gbk),则需要相应指定 # with open('output_gbk.json', 'r', encoding='gbk') as f: # loaded_data = json.load(f)

一个常见问题:如果JSON文件是用ensure_ascii=False写入的,但读取时没有指定正确的encoding(比如用了系统默认编码,而系统默认不是utf-8),就可能出现乱码或解码错误。

5.4 错误处理:让代码更健壮

文件操作和JSON解析都可能出错,良好的错误处理是必须的。

import json def safe_json_write(data, filepath): """安全地写入JSON文件,包含错误处理。""" try: with open(filepath, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False, sort_keys=True) print(f"成功写入文件: {filepath}") return True except TypeError as e: print(f"序列化失败,可能存在不支持的数据类型: {e}") # 这里可以尝试调用自定义的default处理函数 return False except IOError as e: print(f"文件写入失败(权限、路径问题): {e}") return False except Exception as e: print(f"发生未知错误: {e}") return False def safe_json_read(filepath): """安全地读取JSON文件。""" try: with open(filepath, 'r', encoding='utf-8') as f: return json.load(f) except FileNotFoundError: print(f"文件不存在: {filepath}") return None except json.JSONDecodeError as e: print(f"JSON解析错误,文件可能已损坏或格式不正确: {e}") # 可以尝试打印出错位置 print(f"错误发生在行 {e.lineno},列 {e.colno}") return None except UnicodeDecodeError as e: print(f"文件编码错误,请确认是否为UTF-8: {e}") return None except Exception as e: print(f"读取文件时发生未知错误: {e}") return None # 使用示例 if safe_json_write(data, 'my_data.json'): loaded = safe_json_read('my_data.json') if loaded: print("数据读取成功!")

json.JSONDecodeError异常特别有用,它能告诉你具体是哪一行哪一列出现了语法错误,对于调试手工编辑出错的大型JSON文件非常有帮助。

6. 超越标准库:第三方库与替代方案

Python标准库的json模块已经非常强大,但在某些特定场景下,第三方库能提供更好的性能或更便捷的功能。

6.1ujson/orjson:极致的性能

如果你处理的是海量小JSON对象(例如微服务间的通信、实时日志处理),序列化/反序列化的性能可能成为瓶颈。ujson(UltraJSON)和orjson是用C实现的库,速度远超标准库。

# 安装 pip install ujson # 或 pip install orjson
import ujson import orjson data = {...} # 你的数据 # ujson 用法几乎与标准库一致,但参数名可能略有不同 # 注意:ujson的 indent 参数接受的是空格数,不接受字符串 fast_json_str = ujson.dumps(data, indent=2) # orjson 用法不同,它返回的是bytes,而不是str # orjson 的选项通过参数传递,且非常注重性能,默认就是最优化输出 orjson_bytes = orjson.dumps(data, option=orjson.OPT_INDENT_2) # 如果需要字符串,需要解码 orjson_str = orjson_bytes.decode('utf-8')

性能对比:在序列化一个中等复杂度的字典时,orjsonujson通常比标准库快3-10倍。但需要注意:

  1. API差异:它们不一定100%兼容标准库的API,参数和默认行为可能有细微差别(例如orjson默认对非ASCII字符不转义,且返回bytes)。
  2. 功能取舍:为了性能,它们可能不支持标准库的所有功能(比如自定义JSONEncoder的某些高级用法)。
  3. 依赖问题:在部署环境(尤其是受限环境)中,引入C扩展可能增加复杂度。

建议:在性能瓶颈被证实是JSON序列化,且你的数据结构相对标准时,再考虑使用这些库。对于绝大多数应用,标准库的json已经完全够用。

6.2json.tool:命令行格式化工具

Python标准库自带了一个命令行工具json.tool,它对于快速检查和格式化JSON字符串或文件非常有用。

# 格式化一个文件并输出到屏幕 python -m json.tool messy.json # 格式化一个文件并写入新文件 python -m json.tool messy.json > pretty.json # 从管道接收JSON字符串并格式化 echo '{"name": "Alice", "active": true}' | python -m json.tool

这是一个被严重低估的实用工具,尤其是在服务器上快速查看API返回的JSON或者检查配置文件时。

6.3 何时考虑其他数据格式?

JSON并非银弹。当遇到以下情况时,可以考虑其他序列化格式:

  • 文件巨大(GB级别),需要快速查询部分数据:考虑列式存储格式,如ParquetApache Arrow。它们支持高效的压缩和“剪枝”,可以只读取需要的列。
  • 需要极高的序列化性能和极小的消息体积:考虑二进制格式,如MessagePackProtocol BuffersApache Avro。它们序列化后的体积比JSON小得多,速度也快得多,常用于微服务通信或持久化存储。
  • 数据模式(Schema)频繁变化,且需要向前/向后兼容Protocol BuffersAvro有强大的模式演化能力。
  • 需要存储复杂的数值类型(如复数、矩阵):可以考虑结合NumPy.npy格式,或者使用HDF5

对于大多数配置存储、API通信和中小型数据交换场景,格式良好的JSON凭借其无与伦比的通用性和可读性,依然是首选。

7. 集成开发环境(IDE)与编辑器的助力

好的工具能让你事半功倍。现代IDE和编辑器对JSON的支持已经非常完善。

  • 语法高亮与折叠:VSCode、PyCharm、Sublime Text等都能对JSON进行语法高亮,并支持通过点击行号旁的箭头折叠/展开对象和数组,这对于浏览大型JSON文件至关重要。
  • 自动格式化
    • VSCode:打开JSON文件,按Alt+Shift+F(Windows/Linux) 或Option+Shift+F(Mac),或右键选择“格式化文档”。你可以配置editor.formatOnSavetrue实现保存时自动格式化。
    • PyCharmCtrl+Alt+L(Windows/Linux) 或Cmd+Option+L(Mac) 可以格式化当前文件。也可以在设置中配置保存时执行。
  • Schema验证与智能提示:如果你为JSON文件定义了Schema(模式),编辑器可以提供字段自动补全、类型检查和错误提示。这对于编写配置文件(如tsconfig.json,.eslintrc.json)体验提升巨大。通常通过在JSON文件中添加"$schema"属性来关联模式文件。
  • 插件扩展
    • VSCode有 “JSON Tools” 等插件,提供更丰富的格式化、压缩(Minify)、转义/去转义等功能。
    • PyCharm的 “JSON Helper” 插件也提供类似功能。

善用这些工具,可以让你彻底告别手动调整JSON格式的烦恼,把精力集中在数据内容本身。

处理JSON文件的换行与格式化,看似是一个小问题,却贯穿了数据生产、消费、调试和协作的整个流程。从理解indent,separators,sort_keys这些核心参数,到处理自定义对象、权衡性能与可读性,再到规避文件操作中的编码陷阱,每一步都需要清晰的认知。记住,没有一种配置是万能的,关键是理解其背后的原理,然后根据你的具体场景——是网络传输、配置文件、还是调试日志——做出最合适的选择。当你能熟练运用这些技巧,并搭配好用的工具时,JSON这个数据交换的“世界语”,在你手中就会变得既强大又温顺。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/30 10:32:32

千笔与Checkjie论文写作工具深度对比与实战评测

1. 工具定位与核心价值解析 这两款专业写作工具在学术圈已经形成明显的口碑分化。千笔专业论文写作工具最近半年在高校研究生群体中的使用率增长了217%&#xff0c;而Checkjie则持续领跑企业市场调研报告领域。作为每天需要处理大量文献的研究员&#xff0c;我完整测试了两款工…

作者头像 李华
网站建设 2026/7/30 10:32:19

3分钟极速解锁:ncmdump让你的网易云音乐重获自由播放权

3分钟极速解锁&#xff1a;ncmdump让你的网易云音乐重获自由播放权 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的歌曲只能在特定APP里播放而烦恼吗&#xff1f;ncmdump这个开源神器能够帮你轻松解决NCM格式…

作者头像 李华
网站建设 2026/7/30 10:30:18

USB 3.0与USB 2.0识别机制全解析:从物理接口到系统驱动的完整链路

1. 项目概述&#xff1a;从“盲插”到“慧眼识珠”每次把U盘、移动硬盘或者摄像头插到电脑上&#xff0c;你有没有那么一瞬间好奇过&#xff0c;电脑是怎么知道它插在了一个USB 3.0的蓝色接口上&#xff0c;还是一个USB 2.0的黑色或白色接口上&#xff1f;这背后可不是简单的“…

作者头像 李华
网站建设 2026/7/30 10:27:33

晶体谐振器与振荡器:原理、设计与应用指南

1. 晶体谐振器与晶体振荡器概述在电子电路设计中&#xff0c;频率控制元件扮演着至关重要的角色。晶体谐振器&#xff08;Crystal Resonator&#xff09;和晶体振荡器&#xff08;Crystal Oscillator&#xff09;是两种最常用的频率控制器件&#xff0c;它们为数字系统提供精确…

作者头像 李华
网站建设 2026/7/30 10:27:18

Windows Cleaner:3大核心功能彻底解决C盘空间焦虑

Windows Cleaner&#xff1a;3大核心功能彻底解决C盘空间焦虑 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服&#xff01; 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你是否经历过这样的场景&#xff1a;电脑运行越来越…

作者头像 李华
网站建设 2026/7/30 10:27:09

如何高效批量下载微博图片:简单三步实现自动化收集

如何高效批量下载微博图片&#xff1a;简单三步实现自动化收集 【免费下载链接】weibo-image-spider 微博图片爬虫&#xff0c;极速下载、高清原图、多种命令、简单实用。 项目地址: https://gitcode.com/gh_mirrors/we/weibo-image-spider 还在为手动保存微博图片而烦恼…

作者头像 李华