有趣的便签网站-使用Sdcb.WordCloud生成词云图

有趣的便签网站-使用Sdcb.WordCloud生成词云图

前言

最近也是忙着面试、背题,终于闲下来,也是来更新下网站顺便写一篇文章~

上周在网上看到一个静态的便签网站,我也是拿来用并发布了一篇文章,找到一个有趣的便签墙网站 - ZY知识库,后续也是制作了一个可以提交内容的便签网站,也发布了一篇文章,可以提交内容的便签墙来了 - ZY知识库

这两篇文章都比较火,特别是可以提交内容的便签网站,截止今日,已经有4000千多条评论,去除重复的也有3000多条,保守估计,网站搭建至今,访问人数和使用人数应该总和有100+

大部分人提交的内容都是表白、鼓励、吐槽之类的内容,也有一些人发布了恶意评论,当然已经被我删除掉了。

需要注意的是,网站默认只会展示最新的150条信息,如果你发现你之前的信息找不到了,刷新网页好多次还是没看到,那么可能排序到最新的第150条数据后面去了。

下面是网站发布以来更新的内容

  • 2025/11/04 限制内容长度不能超过30字
  • 2025/11/05 限制 xss 攻击
  • 2025/11/06 高估互联网的素质了,还是加上了关键词过滤
  • 2025/11/07 被恶意刷屏,无奈添加接口限流

那么也是为了看看大家都发布的什么内容,也是心血来潮想着用词云图实现一下,通过数据清洗、筛选来看看出现频率最高的词语有哪些,并用 词云图 的形式展示出来,话不多说开始操作。

便签网站直达地址:https://pljzy.top/noteweb

前端设计

前端页面就很简单的设计了一个词云图跳转按钮,通过点击这个按钮可以查看词云图。

1

后端设计

后端采用的是.Net框架,那么生成词云图必然也是.Net框架下的包,我这里使用的是 Sdcb.WordCloud 包。

dotnet add package Sdcb.WordCloud

这个包Star数比较少,可能因为词云图本身不是很知名吧,之前绘制词云图还是学校时期用 python 绘制过。不得不说 python 的包是又多又方便~

sdcb/Sdcb.WordCloud: Generate WordCloud image from .NET/.NET Core

踩坑指南

我在本地 windows 环境下生成词云图是没问题的,当我部署到 Liunx 系统下时,会提示缺少依赖,后面发现需要手动导入 SkiaSharp.NativeAssets.Linux.NoDependencies 包。

dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies

关键代码

public async Task GenerateWordCloud()
{
    try
    {
        using var scope = _serviceProvider.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<MyDbContext>();

        var allNotes = await db.Notes.Select(n => n.Content).ToListAsync();
        var text = string.Join(" ", allNotes);

        // 处理文本并生成词频统计
        var words = ProcessText(text)
            .GroupBy(word => word)
            .ToDictionary(g => g.Key, g => g.Count())
            .OrderByDescending(kv => kv.Value) // 按词频降序排序
            .Take(150) // 取前150个高频词
            .ToDictionary(kv => kv.Key, kv => kv.Value)
            .Select(kv => new WordScore(kv.Key, kv.Value));	// 转换为WordScore对象集合

        // 创建词云实例,设置画布大小为1000x1000
        WordCloud wc = WordCloud.Create(new WordCloudOptions(1000, 1000, words));
        byte[] pngBytes = wc.ToSKBitmap().Encode(SKEncodedImageFormat.Png, 100).AsSpan().ToArray();

        string filePath = "wwwroot/wordcloud.png";

        // 将PNG图片保存到文件
        await File.WriteAllBytesAsync(filePath, pngBytes);

        _logger.LogInformation($"词云图已更新: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "生成词云图时发生错误");
    }
}

这里由于各方面因素影响,只获取了词频出现最多的前 150 条数据。

定时任务

由于词云图生成比较慢,我试了一下150条数据,生成大概要 20~30s ,如果做成接口的话响应很慢,用户体验也不好。

那么我也是采用后台定时任务去执行,我使用的是 Hangfire ,每隔4小时重新绘制一次图像。

dotnet add package Hangfire
dotnet add package Hangfire.MemoryStorage

关键代码

builder.Services.AddHangfire(config =>
    config.UseMemoryStorage());
builder.Services.AddHangfireServer();

// 每天0:00, 4:00, 8:00, 12:00, 16:00, 20:00执行
RecurringJob.AddOrUpdate<WordCloudService>(
    "generate-wordcloud",
    service => service.GenerateWordCloud(),
    "0 0,4,8,12,16,20 * * *");

多提一嘴

Hangfire 可以选择是否开启仪表板,仪表板截图如下,用来查看任务执行情况还是挺方便的。

2

词云图效果

好像大家都有喜欢的人呀,词云图每隔4小时更新一次,如果发现自己发的文字没有在里面可能是出现频率不高,不过不建议大家刷留言~

3

结尾

如果对项目源代码感兴趣的可以访问 Github 并点上 StarZyPLJ/NoteWeb: 便签墙带后端版本,可以随心所欲(注意文明用语)的发送便签~

这个项目也就到这里结束了,后续不会更新内容,网站会一直存在,除非服务器到期和其他不可避免因素导致网站关闭。

总的来说,这是一个很有趣的项目,希望能一直存在下去~

参考链接

posted @ 2025-11-17 13:47  妙妙屋(zy)  阅读(88)  评论(2)    收藏  举报