资讯动态

用Python打造猫猫颜文字生成器:从零件库到CLI工具

发布时间:2026/9/2 23:47:57 来源:尧图企业网站定制
有时打开聊天框想发一只可爱的猫猫表情却找不到一张合适的图有时写代码注释、写 README想加点轻松氛围又不想插入体积很大的图片有时在终端里部署完服务想皮一下打一个“^ω^”在日志旁边。这时候“颜文字”就是性价比最高的解决方案。颜文字又叫 kaomoji核心是用 ASCII 或 Unicode 字符拼出表情尤其擅长表达“可可爱爱”的情绪。本文就用 Python 写一个“猫猫字符生成器”输入一个偏好设置输出一串原创猫猫颜文字并演示如何把它扩展成一个命令行小工具。无论你是刚开始学 Python 的初学者还是想在业务项目里加一点“工具人快乐水”这套代码都能直接用。读完这篇文章你将掌握颜文字的常见组合规律用 Python 字典维护“猫猫零件库”随机组合、去重、控制生成数量的完整逻辑如何把这个小功能封装成 CLI 工具常见编码、乱码、随机结果不合预期的排查方案将“生成器”思想复用到其他颜文字类型的方法。先来看效果通过我们自己写的脚本可以生成类似下面的猫猫字符( ^ω^ ) ( ^ω^ )~ (^^) ( ^‥^ )ฅ如果你也想要一个这样的“猫猫生产工厂”我们开始动手。1. 背景与核心概念1.1 什么是颜文字颜文字日文称为“顔文字”かおもじ是一种用字符组合模拟人脸表情的文本形式。早期多见于日本网络论坛后来随着即时通讯软件流行变成了一种跨平台的“轻量表情包”。与图片表情包相比颜文字有几个明显优势特点说明体积小只是一段文本不占用图片存储跨平台在任何支持 Unicode 的环境都能显示可复制不需要保存图片直接使用文本风格统一不依赖某个 App 的贴纸资源可编程能用代码动态生成适合做工具猫猫颜文字则是颜文字中的一个热门分支。典型的猫猫颜文字会在脸部两侧加入耳朵例如^_^猫猫的精髓在于耳朵两个类似^或^的字符表示猫耳朵中间的字符区域表示眼睛和嘴巴。1.2 为什么要写一个“猫猫字符生成器”乍看之下猫猫颜文字可以直接手打为什么要写代码生成原因有三个第一每个人的审美不一样。有人喜欢圆脸猫猫( ^ω^ )有人喜欢小耳朵猫猫^_^有人喜欢带胡须的猫猫(^^)ฅ。手动拼接字符容易受到输入法、字符集、排版习惯的影响而用代码来管理“零件库”可以让每个零件单独调整组合结果更丰富。第二重复劳动没有意义。如果你经常需要猫猫字符来装饰日志、注释、邮件签名每次手动复制粘贴不仅低效还容易出错。脚本化之后一条命令就能生成一整套。第三它是一道很好的 Python 练手题。这个项目虽然小但涉及了“数据结构设计、随机算法、字符串处理、用户输入解析、异常处理、命令行封装”等完整的工程链路。学完这个小项目你就能把同样的思路迁移到“emoji 生成器”“随机头像字符生成器”“命令行问候语工具”等场景中。1.3 本文技术点预览本文核心代码使用 Python 3 编写主要涉及以下知识点字典用于维护猫猫零件的“分类表”列表用于存储每种零件的候选字符random 模块用于随机选择零件argparse用于构建命令行参数接口文件写入将生成的猫猫字符保存到文本文件单元测试对核心生成逻辑进行校验。整个项目不依赖任何第三方库拿到就能跑。2. 环境准备与版本说明2.1 开发环境本文示例代码在以下环境中验证通过项目说明操作系统Windows 10 / macOS 13 / Ubuntu 22.04Python 版本Python 3.9构建工具无直接使用标准库IDEVisual Studio Code / PyCharm / 终端均可字符编码UTF-8Python 版本不必完全一致只要确保是 Python 3 即可。如果你还在使用 Python 2建议先升级到 Python 3因为本文代码中的 f-string 和类型注解都以 Python 3.6 为基准。2.2 创建虚拟环境虽然这个项目不依赖第三方库但创建虚拟环境依然是一个好习惯。在项目目录下执行mkdir cat-kaomoji cd cat-kaomoji python -m venv venvWindows 下激活虚拟环境venv\Scripts\activatemacOS / Linux 下激活虚拟环境source venv/bin/activate激活之后终端提示符前面会出现(venv)说明当前已经进入虚拟环境。后续运行 python 命令都会在这个隔离环境里执行。2.3 版本需要根据实际环境调整如果你使用的是 Anaconda 或者其他 Python 发行版版本号可能略有差异。这不影响本文代码的运行重点演示的是配置思路和代码实现。遇到版本相关的问题优先检查以下两个命令python --version pip --version只要 Python 版本大于等于 3.9本文代码就可以正常运行。3. 核心语法、配置或原理拆解3.1 颜文字的组合规律猫猫颜文字虽然没有严格语法但仔细观察之后可以总结出一个通用模板[左侧装饰][左耳][左眼][嘴巴][右眼][右耳][右侧装饰]左右耳通常是^、^、^、^等字符组合。眼睛常用的候选字符有^表示普通圆眼表示小圆点眼ω表示开心眯眼◕表示大眼睛表示小眼睛表示线状眼_风格的和表示夸张的眼睛。嘴巴常用候选字符有ω表示猫嘴非常经典_表示普通横线嘴o表示圆形嘴∀表示张大嘴3表示歪嘴^表示微笑嘴Д表示惊讶嘴。有了这个模板我们就能把猫猫颜文字细分成若干“零件位置”每个位置维护一份字符候选列表。生成时从每个位置随机取一个字符再拼接起来就能得到一个全新的猫猫颜文字。3.2 用字典维护“猫猫零件库”在 Python 中可以用字典来维护所有零件。为什么要用字典因为字典可以清晰地把“位置名称”和“候选字符列表”关联起来后续扩展新零件时只需要往字典里增加一个键值对不需要修改生成逻辑。下面是一个最小示例# 代码文件cat_parts.py cat_parts { left_ear: [^, ^, ^, ^], right_ear: [^, ^, ^, ^], left_eye: [^, , ◕, , ], right_eye: [^, , ◕, , ], mouth: [ω, _, o, ∀, 3, ^], }这个字典的每个键都对应一个“零件位置”每个值都是一个候选字符列表。生成猫猫时只要从每个列表中随机选一个然后按照“左耳 左眼 嘴巴 右眼 右耳”的顺序拼接就能得到类似下面的输出^ω^是不是已经有猫猫那味儿了3.3 随机组合的设计思路随机组合中最核心的模块是random.choice它可以从列表中随机选取一个元素。例如import random left_ear random.choice(cat_parts[left_ear]) left_eye random.choice(cat_parts[left_eye]) mouth random.choice(cat_parts[mouth]) right_eye random.choice(cat_parts[right_eye]) right_ear random.choice(cat_parts[right_ear]) cat left_ear left_eye mouth right_eye right_ear print(cat)运行几次输出可能分别是^ω^ ^◕∀◕^ ^3^到这里我们已经能够生成随机猫猫字符了。但只有随机还不够还需要考虑几个工程问题如何避免重复如何控制生成数量如何加入用户偏好如何保证每次运行结果可复现这些就是我们后续实战部分要解决的完整问题。3.4 常见误区不要“手写拼接”所有组合初学者很容易陷入一个误区手动把所有猫猫组合写成一个超长的列表然后从列表里随机取一个。这种做法的缺点是显而易见的组合数量很多时维护成本极高新增一个眼睛候选字符需要重新写很多组合代码里大量重复字符串可读性差。正确做法是“数据与逻辑分离”用字典维护零件用代码组合零件。这样新增候选字符时只需要在字典中增加一项生成逻辑完全不需要变动。4. 完整实战案例4.1 创建项目结构我们按照一个标准的小型 Python 项目来组织文件cat-kaomoji/ ├── cat_parts.py # 零件库 ├── kaomoji_generator.py # 生成器主逻辑 ├── cli.py # 命令行入口 ├── test_kaomoji.py # 单元测试 └── output/ └── .gitkeep # 占位文件创建目录mkdir -p output4.2 编写零件库 cat_parts.py文件路径cat_parts.py# -*- coding: utf-8 -*- 猫猫颜文字零件库。 每个键代表一个零件位置每个值代表该位置的所有候选字符。 CAT_PARTS { left_ear: [ ^, ^, ^, ^, (, (, ^, , ], right_ear: [ ^, ^, ^, ^, ), , ^, ^, ], left_eye: [ ^, , ◕, , , ●, ♥, , ], right_eye: [ ^, , ◕, , , ●, ♥, , ], mouth: [ ω, _, o, ∀, 3, ^, Д, ∇, ], left_decorator: [ , , , (, ᗒ, ฅ, ~, ♡, ], right_decorator: [ , , , ), ᗕ, ฅ, ~, ♡, ], } # 支持的手动装饰符映射 DECORATOR_MAP { none: , paw: ฅ, heart: ♡, tear: ᗒ, }这里有一个细节左耳和右耳候选字符里面我故意加入了一些“半括号”字符例如(和)。这样组合出来的猫猫可能变成带圆脸的猫猫比如( ^ω^ )装饰符字段left_decorator和right_decorator默认包含空字符串表示很多时候我们不需要额外装饰。随机选择时会经常选中空字符串控制装饰出现的概率。4.3 编写核心生成器 kaomoji_generator.py文件路径kaomoji_generator.py# -*- coding: utf-8 -*- 猫猫颜文字生成器核心逻辑。 import random from cat_parts import CAT_PARTS, DECORATOR_MAP def generate_one(partsNone, rngNone): 生成单个猫猫颜文字。 Args: parts: 零件字典默认使用 CAT_PARTS。 rng: random.Random 实例用于控制随机种子。 Returns: str: 生成的猫猫颜文字。 if parts is None: parts CAT_PARTS if rng is None: rng random left_ear rng.choice(parts[left_ear]) left_eye rng.choice(parts[left_eye]) mouth rng.choice(parts[mouth]) right_eye rng.choice(parts[right_eye]) right_ear rng.choice(parts[right_ear]) left_decorator rng.choice(parts[left_decorator]) right_decorator rng.choice(parts[right_decorator]) body left_ear left_eye mouth right_eye right_ear return left_decorator body right_decorator def generate_many(count10, partsNone, seedNone): 生成多个不重复的猫猫颜文字。 Args: count: 生成数量。 parts: 零件字典。 seed: 随机种子便于生成结果可复现。 Returns: list: 猫猫颜文字列表。 if parts is None: parts CAT_PARTS if seed is not None: rng random.Random(seed) else: rng random.Random() seen set() results [] # 为了防止死循环设定最大尝试次数 max_attempts count * 20 100 attempts 0 while len(results) count and attempts max_attempts: cat generate_one(partsparts, rngrng) attempts 1 if cat not in seen: seen.add(cat) results.append(cat) return results def apply_preference(parts, eyeNone, mouthNone, decoratorNone): 根据用户偏好调整零件库。 Args: parts: 原始零件字典。 eye: 眼睛样式例如 big、dot、heart。 mouth: 嘴巴样式例如 cat、smile。 decorator: 装饰符例如 paw、heart。 Returns: dict: 调整后的零件字典。 new_parts {key: list(value) for key, value in parts.items()} eye_map { normal: [^, ], big: [◕, ●], dot: [, ], heart: [♥, ♥], } mouth_map { cat: [ω, ω], smile: [^, ∀], flat: [_, _], open: [Д, o], } if eye in eye_map: new_parts[left_eye] eye_map[eye] new_parts[right_eye] eye_map[eye] if mouth in mouth_map: new_parts[mouth] mouth_map[mouth] if decorator in DECORATOR_MAP: deco DECORATOR_MAP[decorator] if deco: new_parts[left_decorator] [deco] new_parts[right_decorator] [deco] else: new_parts[left_decorator] [] new_parts[right_decorator] [] return new_parts代码要点rng参数支持传入random.Random(seed)方便做结果复现seen集合用于去重避免生成大量重复猫猫max_attempts防止零件组合空间过小时出现死循环apply_preference返回一个新的零件字典不会修改原始数据符合函数式编程习惯。4.4 编写命令行入口 cli.py文件路径cli.py# -*- coding: utf-8 -*- 猫猫颜文字命令行工具。 import argparse import sys from cat_parts import CAT_PARTS from kaomoji_generator import generate_many, apply_preference def parse_args(argvNone): parser argparse.ArgumentParser( description生成可爱的猫猫颜文字 ) parser.add_argument( -n, --number, typeint, default5, help生成数量默认 5, ) parser.add_argument( --eye, choices[normal, big, dot, heart], defaultNone, help眼睛样式, ) parser.add_argument( --mouth, choices[cat, smile, flat, open], defaultNone, help嘴巴样式, ) parser.add_argument( --decorator, choices[none, paw, heart, tear], defaultNone, help装饰符样式, ) parser.add_argument( --seed, typeint, defaultNone, help随机种子便于复现结果, ) parser.add_argument( --output, typestr, defaultNone, help结果输出到指定文件, ) parser.add_argument( --simple, actionstore_true, help只输出颜文字本身不输出辅助信息, ) return parser.parse_args(argv) def main(argvNone): args parse_args(argv) if args.number 0: print(生成数量必须大于 0, filesys.stderr) return 1 parts CAT_PARTS parts apply_preference( parts, eyeargs.eye, mouthargs.mouth, decoratorargs.decorator, ) cats generate_many( countargs.number, partsparts, seedargs.seed, ) lines [] for idx, cat in enumerate(cats, start1): if args.simple: lines.append(cat) else: lines.append(f{idx}: {cat}) text \n.join(lines) if args.output: with open(args.output, w, encodingutf-8) as f: f.write(text \n) if not args.simple: print(f已保存 {len(cats)} 个猫猫字符到 {args.output}) else: print(text) return 0 if __name__ __main__: sys.exit(main())这个 CLI 工具支持以下参数参数作用-n/--number指定生成数量--eye指定眼睛样式--mouth指定嘴巴样式--decorator指定装饰符样式--seed设置随机种子--output将结果写入文件--simple只输出颜文字不输出序号4.5 编写单元测试 test_kaomoji.py文件路径test_kaomoji.py# -*- coding: utf-8 -*- 核心逻辑单元测试。 import unittest from cat_parts import CAT_PARTS from kaomoji_generator import generate_one, generate_many, apply_preference class TestKaomojiGenerator(unittest.TestCase): def test_generate_one_returns_string(self): cat generate_one() self.assertIsInstance(cat, str) self.assertGreater(len(cat), 0) def test_generate_many_unique(self): cats generate_many(count20, seed42) self.assertEqual(len(cats), 20) self.assertEqual(len(set(cats)), 20) def test_generate_many_respects_seed(self): cats1 generate_many(count5, seed100) cats2 generate_many(count5, seed100) self.assertEqual(cats1, cats2) def test_apply_preference_eye(self): parts apply_preference(CAT_PARTS, eyeheart) self.assertEqual(parts[left_eye], [♥, ♥]) def test_apply_preference_mouth(self): parts apply_preference(CAT_PARTS, mouthcat) self.assertEqual(parts[mouth], [ω, ω]) if __name__ __main__: unittest.main()运行测试python -m unittest test_kaomoji.py -v预期输出test_apply_preference_eye (test_kaomoji.TestKaomojiGenerator) ... ok test_apply_preference_mouth (test_kaomoji.TestKaomojiGenerator) ... ok test_generate_many_respects_seed (test_kaomoji.TestKaomojiGenerator) ... ok test_generate_many_unique (test_kaomoji.TestKaomojiGenerator) ... ok test_generate_one_returns_string (test_kaomoji.TestKaomojiGenerator) ... ok ---------------------------------------------------------------------- Ran 5 tests in 0.002s OK4.6 运行与验证在终端执行python cli.py -n 10输出示例1: (^ω^) 2: ^●Д●^ 3: ^◕∀◕^ 4: ᗒ^3^ᗕ 5: ^∇^ 6: (^ω^) 7: ^♥∀♥^ ฅ 8: ~^◕Д◕^~ 9: (^ω^) 10: ♡^●ω●^♡如果你想要固定复现某组结果可以加上--seedpython cli.py -n 5 --seed 42如果你想要大眼睛猫猫并且加上“爪爪”装饰python cli.py -n 5 --eye big --decorator paw输出示例1: ฅ^◕ω◕^ฅ 2: ฅ^◕Д◕^ฅ 3: ฅ^◕∀◕^ฅ 4: ฅ^◕∇◕^ฅ 5: ฅ^◕ω◕^ฅ如果你想把结果保存到文件中python cli.py -n 20 --output output/cats.txt --simple然后查看文件cat output/cats.txtWindows 用户如果是在 CMD 中查看可以执行type output\cats.txt4.7 结果说明从输出结果可以看到猫猫字符已经具备“随机性 可复现性 可定制性”三个特点随机性来自random.choice每次运行大概率不同可复现性来自--seed固定种子后生成结果完全一致方便测试和分享可定制性来自apply_preference可以按眼睛、嘴巴、装饰符分类生成。如果你发现某些输出组合“不够猫”比如两个耳朵字符不对称或者装饰符位置很怪这其实是正常的。颜文字本身就是一种“抽象到不能再抽象”的表情表达。我们可以在后续优化中增加候选字符过滤规则但作为初版生成器这种随机组合的“乱中有序”反而会增加趣味性。5. 常见问题与排查思路5.1 终端输出乱码或方块问题现象常见原因解决思路字符显示为方块终端字体不支持 Unicode 特殊字符更换终端字体为支持中日韩字符的字体Windows CMD 乱码CMD 默认编码不是 UTF-8执行chcp 65001切换编码Python 报 UnicodeEncodeError输出重定向时编码不一致设置环境变量PYTHONIOENCODINGutf-8在 Windows 上最推荐的方案是使用 Windows Terminal并设置字体为“微软雅黑”或“Cascadia Mono”基本可以避免显示问题。如果需要在 Python 中强制指定编码可以在脚本顶部添加import sys import io sys.stdout io.TextIOWrapper(sys.stdout.buffer, encodingutf-8)但更推荐的方式是修改终端编码chcp 650015.2 随机生成结果重复率过高问题现象常见原因解决思路连续生成大量猫猫重复很多零件库候选太少组合空间有限扩充候选字符或者缩小生成数量固定 seed 后仍重复seed 相同但每次调用顺序不一致在主函数中只创建一次random.Random实例生成数量接近组合总数组合空间已经用完降低数量或增加新零件默认零件库的组合数量是左耳 8 × 右耳 8 × 左眼 8 × 右眼 8 × 嘴巴 8 × 左装饰 8 × 右装饰 8理论组合超过 26 万种实际因为左右眼对称关系会少一些但依然足够使用。如果生成 500 个以上重复概率会逐渐上升这是正常的。5.3 模块导入失败问题现象常见原因解决思路ModuleNotFoundError: No module named cat_parts当前目录不在 Python 搜索路径中在项目根目录运行或在文件头部添加sys.path.insert(0, os.path.dirname(__file__))确保你在项目根目录cat-kaomoji下运行命令而不是在output目录或其他位置。5.4 用户偏好不生效问题现象常见原因解决思路指定--eye big后输出仍不是大眼睛apply_preference返回新字典但主函数没有覆盖原变量检查parts apply_preference(...)赋值指定--decorator paw后没有出现爪爪装饰符字段候选被覆盖后仍含有空字符串确认apply_preference中装饰符分支正确且在生成前调用5.5 生成猫猫字符不对称颜文字的魅力在于“不对称也是一种风格”例如( ^ω^ )其实左右并不完全对称但仍然可爱。如果你希望强制对称可以在generate_one中增加一个逻辑右眼直接使用左眼值或者在零件字典中让左右眼候选完全一致。def generate_one_symmetric(partsNone, rngNone): if parts is None: parts CAT_PARTS if rng is None: rng random left_ear rng.choice(parts[left_ear]) left_eye rng.choice(parts[left_eye]) mouth rng.choice(parts[mouth]) right_eye left_eye right_ear rng.choice(parts[right_ear]) left_decorator rng.choice(parts[left_decorator]) right_decorator rng.choice(parts[right_decorator]) body left_ear left_eye mouth right_eye right_ear return left_decorator body right_decorator6. 最佳实践与工程建议6.1 数据与逻辑分离这个项目虽然很小但已经体现了很好的数据与逻辑分离思想。零件库是“数据”生成逻辑是“算法”。后续如果想把项目扩展成“通用颜文字生成器”比如增加兔子、仓鼠、狗狗等类型只需要扩展零件库结构ANIMAL_PARTS { cat: CAT_PARTS, rabbit: { left_ear: [, |, (/], right_ear: [, |, \\)], # ... }, }而生成逻辑完全不需要改动。这就是“开闭原则”在小型项目中的体现——对扩展开放对修改关闭。6.2 使用随机种子在涉及随机结果的工具中务必保留seed参数。这样带来的好处是测试时结果可复现分享给同事时可以精确复现同一个 bug生成特定批次的结果后如果需要补充生成可以基于同一个 seed 继续扩展。6.3 考虑编码问题只要涉及中文、日文、特殊符号Python 文件的编码尽量统一定为 UTF-8并且在使用open()写入文件时显式指定encodingutf-8。在团队协作中还应该在项目根目录添加.editorconfig文件root true [*] charset utf-8 end_of_line lf insert_final_newline true6.4 单元测试要覆盖核心逻辑即使是一个小工具单元测试也能带来长期收益。本文的test_kaomoji.py覆盖了生成结果是字符串多个生成结果不重复同样的种子产生同样的结果偏好设置正确修改零件库。这些测试在后续重构或扩展时能快速暴露问题。6.5 安全与文件写入注意事项当--output指定路径时要确认目标目录存在并且有写入权限。生产环境中绝不要将输出文件写入系统关键目录也不要接受不受信任的路径参数。对于本文这样的小工具限制输出路径到项目output/目录内是比较安全的选择。如果要把这个工具发布给团队内部使用建议增加以下边界检查from pathlib import Path def safe_output_path(path): p Path(path) if p.parent.exists() is False: raise ValueError(f目录不存在: {p.parent}) return p6.6 扩展思路有了这套代码你可以继续扩展很多有趣的功能增加“动物类型”参数让同一套生成器支持猫猫、兔兔、熊熊增加“风格”参数一键切换简约风、可爱风、夸张风增加“批量导出为 Markdown 表格”的功能方便直接粘贴到文档中增加“复制到剪贴板”功能调用pyperclip库实现一键复制增加 Web 页面把生成器封装成浏览器小工具。6.7 将生成器用于实际项目猫猫颜文字生成器不仅能当玩具还可以在以下场景中使用在测试数据中生成随机字符串避免使用重复的固定数据在命令行工具的--version输出中增加一段趣味文本在 CI 脚本的构建成功提示中输出一只猫猫缓解监控焦虑在邮件签名或群机器人消息中动态生成一条猫猫祝福语。只要你愿意这个“字符生成工厂”可以成为你项目里最可爱的彩蛋。7. 总结与学习路线7.1 本文掌握的关键点本文实现了一个完整的猫猫颜文字生成器。核心收获有三点第一理解了颜文字的模板化结构。表面自由的颜文字其实可以拆分为“耳、眼、嘴、装饰”等独立的零件位置这是能用程序生成的前提。第二掌握了数据与逻辑分离的设计。用字典保存零件库用生成函数负责组合用偏好函数负责定制核心代码不到 100 行却具备了随机、去重、复现、扩展等工程能力。第三学会了从命令行工具的角度完善一个小项目。通过argparse封装参数、通过unittest测试核心逻辑、通过--seed支持结果复现这些都是真实项目中会反复用到的技能。7.2 后续可以继续学习的方向如果你对字符串处理和文本创意生成感兴趣可以继续学习正则表达式从文本中提取或校验颜文字自然语言生成基于 n-gram 模型生成更多样化的表情tkinter 或 Web 前端为生成器做一个图形界面Python 打包使用 PyInstaller 把工具打包成 exe单元测试进阶使用 pytest 精简测试代码使用参数化测试覆盖更多边界条件。7.3 实际项目中优先关注的风险在把这个小工具推向实际项目之前建议重点关注三个风险编码风险特殊字符在不同平台的显示效果不一致需要提前做好终端测试随机质量风险随机组合虽然有趣但如果零件库设计不当可能出现大量无意义输出维护风险零件库会越来越大建议为每种动物、每种风格建立独立的配置模块避免单个文件膨胀。动手改一改cat_parts.py里的候选字符你会发现即使只改一个字符生成的猫猫也会完全不同于默认风格。这大概就是字符创作最有魅力的地方——限制极少但创意无限。如果本文对你有帮助可以收藏备用之后想生成猫猫字符时随时拿出来跑一跑。也欢迎在评论区分享你生成的“最奇怪猫猫”看看谁的猫猫最具灵魂。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价