曾经在刷《小马宝莉》同人社区的时候,经常会看到类似“Can I get a kiss, sunset?”这样一句话。如果你不了解余晖烁烁(Sunset Shimmer)这个角色,可能会觉得这只是一句粉丝玩笑;但如果你追过《小马宝莉:小马国女孩》系列,就会明白这句话背后其实承载了角色从叛逆到温柔的巨大转变,也承载了粉丝对“救赎型角色”天然的偏爱。
这篇文章不打算只停留在角色解读层面。既然你点进来了,我会用一套可复用的“数据采集 + 情感分析 + 词云生成 + AI 绘图 + 短视频制作”工作流,带你从技术角度拆解“余晖烁烁 / MLP”这类同人创作主题:为什么粉丝会对“Can I get a kiss, sunset?”产生共鸣,以及当你想围绕这个主题做图、做视频、做内容分析时,应该怎么一步步落地。
无论你是《小马宝莉》的老粉,还是对同人文化感兴趣的内容创作新手,又或者只是想把 Python 数据分析能力用在有趣的题材上,这篇文章都适合你。整个流程不需要太高的编程门槛,代码部分我会尽量完整给出,你只需要按步骤复制运行即可。
2. 角色背景:余晖烁烁为什么让人想“给一个吻”
在开始动手技术操作之前,有必要先把这个角色讲清楚,因为后续所有数据分析和内容创作都是围绕角色特质展开的。如果不懂角色,做出来的内容就容易流于表面。
2.1 余晖烁烁是谁
余晖烁烁(Sunset Shimmer)是《小马宝莉》系列中的一个重要配角,最初也是一位代表性角色。在《小马宝莉:小马国女孩》的时间线里,她曾是塞拉斯蒂亚公主的学生,因为渴望力量试图夺取 Twilight Sparkle 的王冠,被水晶之镜传送到了人类世界。在人类世界里,她一度是坎特洛特高中的“校霸”,用控制人心的方式维持自己的地位。
但随着 Twilight 来到人类世界并和她对抗,余晖烁烁经历了从反派到盟友的转变。后来她凭借自己对人类世界和魔法世界的了解,多次帮助主角团化解危机,成为团队中不可或缺的一员。她的成长线非常清晰:从“我要控制一切”变成“我愿意为朋友留下”,从害怕被抛弃变成主动保护别人。
2.2 为什么“Can I get a kiss, sunset?”会让粉丝兴奋
这句话听起来像一句轻浮的搭讪,但在同人社区语境里,它远远不是字面意思那么简单。粉丝喜欢用这句话表达的是:
- 对余晖烁烁形象转变的认可;
- 对角色“外表强势、内心柔软”这种反差感的喜爱;
- 对同人情感关系的想象与延伸;
- 对角色从孤独走向被接纳的一种温柔回应。
在粉丝文化里,“Can I get a kiss”也可以是一句亲昵的互动梗。它不代表低俗,更多是一种同人创作中常见的情感表达。理解了这一点,我们后面做的数据分析、AI 绘图、视频脚本,才会更贴近粉丝的真实感受。
2.3 这篇文章的技术挑战
我们要做的事情,本质上是一条完整的“同人主题内容生产流水线”:
- 用 Python 获取同人社区中与余晖烁烁相关的公开文本数据;
- 对文本做情感分析,了解粉丝情绪倾向;
- 生成词云与高频词表,提炼创作关键词;
- 用 AI 绘图工具生成余晖烁烁同人画面;
- 用 MoviePy 或剪映把图片和文字串成一条短视频。
这套流程本身不限于“余晖烁烁”这个角色,你完全可以把它替换成任何你喜欢的 IP 或角色。这也是我写这篇文章想真正教给你的东西:一个可以复用的同人内容分析框架。
3. 环境准备与工具清单
在开始写代码之前,先确认环境。本文示例以 Windows + Python 3.9 为基础,其他操作系统大同小异。
3.1 本地环境
我使用的是:
- Windows 10 / 11;
- Python 3.9+;
- VS Code 或 PyCharm;
- Chrome 浏览器(用于查看公开页面结构)。
版本不需要完全一致,重点是 Python 版本不要低于 3.8,因为部分依赖库对旧版本支持不好。
3.2 Python 依赖库
在命令行中执行:
pip install requests parsel pandas snownlp jieba wordcloud matplotlib moviepy各库的作用如下:
| 库名 | 作用 |
|---|---|
| requests | 发送 HTTP 请求,获取网页内容 |
| parsel | 解析 HTML,提取需要的文本 |
| pandas | 数据清洗与整理 |
| snownlp | 中文情感分析 |
| jieba | 中文分词 |
| wordcloud | 生成词云图 |
| matplotlib | 绘制图表或显示词云 |
| moviepy | 视频合成 |
如果安装速度慢,可以换成清华镜像源:
pip install requests parsel pandas snownlp jieba wordcloud matplotlib moviepy -i https://pypi.tuna.tsinghua.edu.cn/simple3.3 AI 绘图与视频工具
- AI 绘图:Stable Diffusion WebUI、Midjourney、即梦、LiblibAI 都可以。
- 视频剪辑:剪映、必剪、MoviePy 都可以。
- 语音合成:剪映自带文字转语音,也可以用 Edge-TTS 脚本生成配音。
不同工具的参数差异比较大,本文会更侧重提示词写法和视频合成逻辑,具体界面操作以你使用的工具为准。
4. 第一步:用 Python 获取同人社区文本数据
要做内容分析,得有数据。同人社区的数据来源很多,包括贴吧、微博、B 站评论区、Lofter、AO3 等。实际工作中需要根据目标平台写不同的解析规则。
我在这里给出的方案,是一种通用思路:只采集公开可访问的页面,不涉及登录、验证码、付费内容。
4.1 采集前必读
这里必须先说清楚合规问题:
- 只能采集公开可见的数据,不能突破登录权限;
- 必须遵守目标网站的 robots.txt;
- 控制请求频率,不要给对方服务器造成压力;
- 采集到的数据仅用于个人学习与分析,不能用于任何商业用途;
- 如果涉及用户原创内容,引用时要尽量避免大段转载,只做数据统计和关键词提炼。
我们在学习阶段,可以用静态 HTML 页面做示例,不绑定任何具体平台。
4.2 用 requests 获取页面内容
先来看一个最简单的请求示例:
import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } url = "你的目标页面地址" resp = requests.get(url, headers=headers, timeout=10) resp.encoding = resp.apparent_encoding print(resp.status_code) print(resp.text[:500])这里有几个细节需要注意:
resp.encoding如果不设置,中文页面容易出现乱码;timeout必须设置,防止请求卡死;User-Agent务必设置,部分网站会拦截没有 UA 的请求。
4.3 解析 HTML 提取文本
拿到页面 HTML 后,就可以用 parsel 提取目标内容。假设页面结构中有多个包含文章的<div class="post-content">,可以用下面的代码提取:
from parsel import Selector def parse_page(html): sel = Selector(text=html) results = [] # 以 CSS 选择器为例,需要根据实际页面结构调整 contents = sel.css("div.post-content::text").getall() for content in contents: content = content.strip() if content: results.append(content) return results在实际项目中,页面结构往往没有这么简单。你需要先在浏览器里按 F12,找到正文内容对应的 HTML 标签和 class 名称,再替换上方的 CSS 选择器。
4.4 保存为结构化数据
把多条内容保存到 CSV 文件,方便后续分析:
import pandas as pd def save_to_csv(texts, filename="mlp_sunset_data.csv"): df = pd.DataFrame({"text": texts}) df = df.dropna().drop_duplicates() df.to_csv(filename, index=False, encoding="utf-8-sig") print(f"共保存 {len(df)} 条数据到 {filename}") if __name__ == "__main__": # 模拟几条数据,实际使用时替换为 parse_page 的结果 sample_texts = [ "Can I get a kiss, sunset?", "余晖烁烁真的很适合救赎向的故事。", "从反派到主角团的伙伴,她的成长让人感动。", "喜欢 Sunset Shimmer 和 Twilight 之间的互动。", "这个角色真的太有魅力了。" ] save_to_csv(sample_texts)encoding="utf-8-sig"可以保证 Excel 打开 CSV 时中文不乱码。
5. 第二步:用 SnowNLP 做情感分析
有了文本数据之后,我们要回答一个问题:粉丝表达的情感到底是偏向正面、中立,还是负面?
5.1 为什么选择 SnowNLP
SnowNLP 是一个 Python 中文文本处理库,内置情感分析模型,使用简单。虽然它的模型在特定领域下不如大模型精准,但对于“粉丝对角色评价”这种场景,已经足够作为参考。
如果你处理的是英文数据,可以直接使用 NLTK 中的VADER,或者在 SnowNLP 内部先翻译成中文再分析。本文以中文数据为例。
5.2 情感分析代码
import pandas as pd from snownlp import SnowNLP df = pd.read_csv("mlp_sunset_data.csv") def get_sentiment(text): if not isinstance(text, str) or len(text.strip()) == 0: return None s = SnowNLP(text) return s.sentiments df["sentiment"] = df["text"].apply(get_sentiment) # 划分情感倾向 def classify(score): if score is None: return "未知" if score >= 0.6: return "正面" elif score <= 0.4: return "负面" else: return "中性" df["label"] = df["sentiment"].apply(classify) print(df.head(10))输出结果中,sentiment是 0 到 1 之间的数值,越接近 1 越正面,越接近 0 越负面。
5.3 如何解读结果
假设你最后得到的结果是:正面占比 72%,中性占比 20%,负面占比 8%,这说明社区整体对“余晖烁烁”这个角色的接受度很高。你可以进一步提取正面的样本,看看大家高频提到的是哪些词汇,比如“成长”“救赎”“友情”“温柔”“帅气”。
这就告诉我们,在做同人创作时,把这些关键词放进画面、文案、视频脚本里,更容易触发粉丝共鸣。
5.4 一个完整的分析脚本
把采集、清洗、情感分析合并到一个脚本中:
import pandas as pd from snownlp import SnowNLP def analyze_csv(input_file="mlp_sunset_data.csv", output_file="mlp_sunset_sentiment.csv"): df = pd.read_csv(input_file) df["sentiment"] = df["text"].apply( lambda x: SnowNLP(x).sentiments if isinstance(x, str) and x.strip() else None ) df["label"] = df["sentiment"].apply( lambda s: "正面" if s and s >= 0.6 else ("负面" if s and s <= 0.4 else "中性") ) df.to_csv(output_file, index=False, encoding="utf-8-sig") print(df["label"].value_counts()) if __name__ == "__main__": analyze_csv()6. 第三步:用 jieba + wordcloud 生成词云
要让分析结果更直观,我强烈建议生成一张词云图。词云的核心逻辑是:先分词,再统计词频,最后绘图。
6.1 中文分词
直接用整段文本画词云效果很差,因为中文没有天然空格。所以需要先用 jieba 分词:
import jieba import pandas as pd df = pd.read_csv("mlp_sunset_sentiment.csv") stopwords = set() with open("stopwords.txt", "r", encoding="utf-8") as f: for line in f: stopwords.add(line.strip()) words = [] for text in df["text"].dropna(): for w in jieba.cut(text): w = w.strip() if len(w) < 2: continue if w in stopwords: continue words.append(w) word_str = " ".join(words) print(word_str[:200])stopwords.txt是停用词表,需要你自己准备,通常包含“的”“了”“是”“在”这类无意义词。你可以从网上下载通用中文停用词表,也可以手动维护。
6.2 绘制词云
from wordcloud import WordCloud import matplotlib.pyplot as plt wc = WordCloud( font_path="C:/Windows/Fonts/simhei.ttf", # Windows 中文字体路径 width=800, height=600, background_color="white", max_words=200 ).generate(word_str) plt.figure(figsize=(10, 8)) plt.imshow(wc, interpolation="bilinear") plt.axis("off") plt.savefig("sunset_wordcloud.png", dpi=150) plt.show()注意:font_path必须指定一个中文字体,否则词云会出现乱码方框。Windows 常用字体路径是C:/Windows/Fonts/simhei.ttf。
6.3 从词云结果反推创作方向
词云图里越大的词,说明在粉丝文本里出现频率越高。如果出现“救赎”“成长”“友谊”“魔法”“温柔”这些词,你在做 AI 绘图和视频时就可以围绕这些关键词设计画面和文案。比如“救赎”对应余晖烁烁放下执念的瞬间,“友谊”对应她与主角团并肩作战的场景。
这一步本质上是在做“主题关键词提取”,它是连接数据分析和内容创作的关键桥梁。
7. 第四步:用 AI 绘图生成同人画面
数据分析和词云已经帮我们定好了创作方向。下面来看如何把这些关键词变成实际画面。
7.1 AI 绘图的提示词结构
一个稳定的 AI 绘图提示词通常包含四个部分:主体、动作、环境、画风。以“余晖烁烁主题”为例:
Sunset Shimmer, humanized style, long red and yellow gradient hair, confident smile, standing on the school rooftop at sunset, warm lighting, friendship atmosphere, anime style, high quality, clean background中文提示词示例(用于部分国产工具):
余晖烁烁拟人化,红黄渐变长发,自信微笑,站在学校天台,黄昏暖光,伙伴们站在身后,治愈系氛围,唯美插画风格,高清,背景干净几点建议:
- 把词云里的高频词融入提示词,但不要堆砌太多;
- 角色特征描述越具体越好,包括发色、瞳色、服装状态;
- 画风关键词建议放在提示词末尾;
- 如果生成结果不理想,先调整“环境”和“画风”部分。
7.2 用 Python 批量生成“提示词变体”
如果你希望一次生成多张图做对比,可以用 Python 脚本自动组合提示词。以最基础的模板拼接为例:
base = "Sunset Shimmer, humanized, {hair}, {emotion}, {scene}, anime style, high quality" hair_list = ["long red and yellow gradient hair", "wavy golden hair", "twin-tailed flame hair"] emotion_list = ["soft smile", "confident smirk", "gentle look"] scene_list = ["sunset school rooftop", "crystal mirror gate", "friendship ballroom"] for hair in hair_list: for emotion in emotion_list: for scene in scene_list: prompt = base.format(hair=hair, emotion=emotion, scene=scene) print(prompt) print("---")这个脚本会把不同发色、神态、场景组合起来,生成本文写作时“从关键词到画面”的中间素材。
需要说明的是:AI 绘图工具的型号和 Prompt 语法各有差异,以上只是通用思路,具体参数需要依据你用的平台调整。如果你使用 Stable Diffusion,建议同时指定负向提示词,例如:
lowres, bad anatomy, bad hands, extra fingers, blurry, watermark7.3 生成短视频素材包
AI 绘图一般一次生成一张图。做短视频通常需要 4 到 6 张图,建议图片风格保持一致。操作方法是:固定画风关键词,只改变动作或场景关键词;或者直接在图生图模式下,导入第一张图作为参考图,再微调 Prompt。
图片准备好后,把它们统一放到一个文件夹里:
./sunset_video/images/0001.png ./sunset_video/images/0002.png ./sunset_video/images/0003.png ./sunset_video/images/0004.png下一步就可以合成视频了。
8. 第五步:用 MoviePy 把图片串成同人短片
有了图片,接下来要解决的问题是:怎么把这些图片变成一条带字幕、带配音的视频。
8.1 用 MoviePy 合成基础短视频
下面是一段可以直接运行的 MoviePy 示例代码,作用是把图片序列按时间顺序拼成视频,并在每张图上叠加文本。
from moviepy.editor import ImageClip, CompositeVideoClip, TextClip, concatenate_videoclips from PIL import Image, ImageDraw, ImageFont import os image_folder = "sunset_video/images" image_files = sorted([f for f in os.listdir(image_folder) if f.endswith(('.png', '.jpg'))]) clips = [] for img_file in image_files: img_path = os.path.join(image_folder, img_file) # 每张图展示 4 秒 clip = ImageClip(img_path, duration=4) # 统一缩放宽度为 1080 clip = clip.resize(width=1080) clips.append(clip) if not clips: raise ValueError("图片文件夹中没有找到可用图片") video = concatenate_videoclips(clips, method="compose") video.write_videofile( "sunset_video/output.mp4", fps=24, codec="libx264", audio_codec="aac" ) print("视频生成完成")MoviePy 在合成前需要安装 FFmpeg。如果你在旧版本 MoviePy 中遇到ImageClip或TextClip不兼容问题,也可以改用 2.x 版本的写法:
from moviepy import ImageClip, concatenate_videoclips clip = ImageClip(img_path, duration=4)8.2 添加字幕
MoviePy 的TextClip对字体要求比较严格,Windows 上需要指定字体路径:
from moviepy.editor import TextClip text_clip = TextClip( "Can I get a kiss, sunset?", fontsize=80, font="C:/Windows/Fonts/msyh.ttc", color="white", stroke_color="black", stroke_width=2, duration=4 ).set_position(("center", "bottom"))然后把文字片段放在图片片段上方:
composite = CompositeVideoClip([clip, text_clip])建议把每张图对应的文字单独做一条 TextClip,这样就能形成“一张图 + 一句文案”的节奏感。
8.3 添加背景音乐或配音
MoviePy 支持音频合成。最简单的做法是准备一段背景音乐:
from moviepy.editor import AudioFileClip audio = AudioFileClip("bgm.mp3").subclip(0, video.duration) video = video.set_audio(audio) video.write_videofile("sunset_video/output_with_audio.mp4", fps=24)如果你需要把文案生成配音,推荐使用 Edge-TTS,生成非常自然的中文或英文语音。Edge-TTS 是一个命令行工具,安装方式:
pip install edge-tts生成语音:
edge-tts --text "Can I get a kiss, sunset?" --voice en-US-AriaNeural --write-media sunset_voice.mp3这样你就有了一条完整结构的短视频:图片画面、字幕文案、配音或背景音乐。
9. 常见问题与排查清单
在实践过程中,下面几个问题出现频率最高。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 中文乱码 | 网页编码识别失败 | 使用resp.apparent_encoding或手动指定编码 |
| 词云全是方框 | 未指定中文字体 | 下载或指定系统黑体字体文件 |
| SnowNLP 评分不准确 | 短文本情绪表达不完整 | 合并同主题文本后再分析 |
| MoviePy 找不到 FFmpeg | 未安装 FFmpeg 或版本过低 | 下载 FFmpeg 并配置到系统 PATH |
| 视频画面比例不一致 | 图片尺寸不同 | 先统一 resize 再拼接 |
| AI 绘图人物手部崩坏 | 模型对复杂手部结构不擅长 | 使用负向提示词或控制生成区域 |
| 请求被目标网站拦截 | 请求频率过高或缺失 UA | 降低频率,设置随机休眠 |
| CSV 打不开乱码 | 编码不是 UTF-8-sig | 保存时使用encoding="utf-8-sig" |
另外说明一下:如果你不是专业做爬虫的,建议优先使用目标平台官方提供的导出功能,或者直接复制公开文本内容做少量标注,不要写大规模爬虫脚本。重点放在分析思路和内容创作上,而不是绕过平台限制。
10. 最佳实践与工程建议
整个流程走通不难,但要做得好,还是有不少细节值得沉淀。
10.1 数据采集遵守最小化原则
只采集你真正需要的数据,不要把所有页面都爬下来。比如做“余晖烁烁”主题分析,就从公开评论、公开帖子中采集标题和正文,不采集用户隐私信息。请求间隔建议至少 1 到 3 秒,最好在代码里加上随机等待:
import time import random time.sleep(random.uniform(1, 3))10.2 数据处理保持可追溯
把原始文本和情感分析结果分开保存。我习惯用三个文件:
raw_data.csv:原始文本;cleaned_data.csv:清洗后的数据;analysis_result.csv:情感分析、词频统计结果。
这样每一步都能回溯,也和数据分析工程的思路保持一致。
10.3 提示词版本管理
AI 绘图提示词不要只存在脑子里。每次生成后,把提示词、参数、生成结果文件路径保存到一个prompt_log.csv里,方便后续复盘。示例格式:
prompt,negative_prompt,steps,cfg,seed,image_path "Sunset Shimmer, humanized...","lowres,bad anatomy",25,7,12345,images/0001.png10.4 视频项目目录规范化
建议按下面的目录结构组织视频项目:
sunset_video/ ├── images/ ├── audio/ ├── output/ ├── scripts/ └── prompt_log.csv把脚本和素材分开,保证项目可维护。剪辑软件如果崩溃了,也能快速恢复。
10.5 版权边界要清晰
这一点很重要。请记住:
- 官方宣传图和动画截图可以用于个人学习、同人讨论,但不要直接用于商业宣传;
- AI 绘图引用角色形象时,尽量使用“同人风格”描述,而不是生成官图风格的高精度仿图去侵权;
- 粉丝二创作品应遵守具体平台的同人创作规则;
- 视频背景音乐需要选用无版权音乐或有授权音乐,不要直接使用商业歌曲;
- 如果需要发布到公共平台,请在简介中明确标注“非官方同人作品”。
同人文化是建立在热爱与尊重之上的。技术可以帮我们更快做出内容,但守住界限才能走得更远。
11. 总结与下一步学习方向
这条工作流走完之后,你会发现一件事:一句“Can I get a kiss, sunset?”背后,其实是角色、粉丝情感、创作工具和数据分析组合在一起的结果。
再往后,如果你想继续深入,可以从这几个方向发力:
- 学习更完整的数据分析流程,比如用 scikit-learn 做文本分类,把正面、中性、负面判断变成可评估的模型;
- 学习 Stable Diffusion 的细节参数控制,了解 ControlNet、LoRA、提示词权重,让同人画面更贴近你的构想;
- 学习 MoviePy 的进阶合成能力,比如关键帧动画、转场特效、字幕动态效果;
- 学习短视频平台的推荐逻辑,把你做好的同人短片在合规前提下发布出去,观察数据表现。
如果你是为了写一篇关于《小马宝莉》或余晖烁烁的同人分析文章,前面 1 到 6 章的内容已经足够支撑一篇有数据、有观点、有素材的创作笔记;如果你是想做一条视频,那 7 到 8 章的代码和流程可以直接拿来用。
希望这篇笔记能帮你更顺地完成自己的余晖烁烁主题创作。如果你在跑通流程时遇到问题,欢迎把自己的报错信息整理好,按章节和步骤去排查,大部分问题都能在日志里找到线索。