博客 / 詳情

返回

有趣的便籤網站-使用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 並點上 Star ,ZyPLJ/NoteWeb: 便籤牆帶後端版本,可以隨心所欲(注意文明用語)的發送便籤~。

這個項目也就到這裏結束了,後續不會更新內容,網站會一直存在,除非服務器到期和其他不可避免因素導致網站關閉。

總的來説,這是一個很有趣的項目,希望能一直存在下去~

參考鏈接

  • 一次小而美的重構:使用 C# 在 Avalonia 中生成真正好看的詞雲
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.