用Python打造微信聊天年鉴:从数据清洗到情感分析的全自动方案

微信聊天记录里藏着无数珍贵记忆,但原始导出的CSV文件往往混杂着系统消息、群聊通知和各种无效内容。本文将带你用Python构建一套自动化数据处理流程,不仅能高效清洗数据,还能生成可视化年鉴和情感分析报告——整个过程无需手动筛选,代码可直接复用。

1. 原始数据痛点分析与预处理策略

刚导出的微信CSV文件通常包含十几个字段,其中最有价值的是createTime(时间戳)、talker(对话人ID)、isSend(发送方向)和content(消息内容)。但原始数据存在三大典型问题:

  • 时间格式不友好:存储为Unix时间戳需要转换
  • 内容混杂:包含红包通知、撤回提示等系统消息
  • 多人群聊干扰:需要按联系人分离对话

先看一个典型的数据结构示例:

import pandas as pd

raw_data = pd.read_csv('message.csv', 
                      usecols=['createTime', 'talker', 'isSend', 'content'],
                      encoding='utf-8-sig')
print(raw_data.head(3))

输出可能显示:

   createTime            talker  isSend                     content
0  1590123456   wxid_abcdefghij       1              你好呀!
1  1590123457   wxid_klmnopqrst       0   [微信红包]恭喜发财
2  1590123458   wxid_abcdefghij       1  https://example.com

关键清洗步骤清单

  • 转换Unix时间戳为可读格式
  • 过滤系统消息(含特定关键词)
  • 移除纯URL链接
  • 按联系人分组对话
  • 处理特殊字符和编码问题

提示:微信导出的CSV常使用GB2312编码,但在Python中建议统一转为UTF-8处理,避免乱码

2. 构建自动化清洗流水线

下面这个增强版清洗脚本增加了正则过滤和异常处理:

import re
from datetime import datetime

def clean_wechat_data(input_file, output_file, target_user=None):
    # 定义需要过滤的系统消息关键词
    SYSTEM_MSG_KEYWORDS = [
        '撤回了一条消息',
        '微信红包',
        '拍了拍'
    ]
    
    def is_valid_message(content):
        if not content or str(content).strip() == '':
            return False
        if any(keyword in str(content) for keyword in SYSTEM_MSG_KEYWORDS):
            return False
        if re.match(r'^https?://', str(content).strip()):
            return False
        return True

    try:
        df = pd.read_csv(input_file, encoding='utf-8-sig')
        # 基础字段选择
        df = df[['createTime', 'talker', 'isSend', 'content']].copy()
        
        # 按联系人筛选
        if target_user:
            df = df[df['talker'] == target_user]
        
        # 时间格式转换
        df['datetime'] = df['createTime'].apply(
            lambda x: datetime.fromtimestamp(x//1000).strftime('%Y-%m-%d %H:%M:%S'))
        
        # 内容清洗
        df = df[df['content'].apply(is_valid_message)]
        
        # 保存结果
        df[['datetime', 'talker', 'isSend', 'content']].to_csv(
            output_file, index=False, encoding='utf-8-sig')
        return True
    except Exception as e:
        print(f"处理失败: {str(e)}")
        return False

这个脚本的增强功能包括:

  1. 使用正则表达式识别URL链接
  2. 可选的特定联系人过滤
  3. 更健壮的错误处理机制
  4. 保留原始数据结构的同时增加格式化日期

3. 高级数据分析技巧

清洗后的数据可以产出多种分析视角。以下是三个典型分析方向及其实现方法:

3.1 对话时间分布热力图

使用seaborn绘制对话时间分布:

import seaborn as sns
import matplotlib.pyplot as plt

def plot_activity_heatmap(df):
    # 提取小时和周几信息
    df['hour'] = pd.to_datetime(df['datetime']).dt.hour
    df['weekday'] = pd.to_datetime(df['datetime']).dt.day_name()
    
    # 创建透视表
    pivot = df.pivot_table(index='weekday', 
                          columns='hour', 
                          values='content', 
                          aggfunc='count', 
                          fill_value=0)
    
    # 按星期顺序排序
    weekdays = ['Monday', 'Tuesday', 'Wednesday', 
               'Thursday', 'Friday', 'Saturday', 'Sunday']
    pivot = pivot.reindex(weekdays)
    
    plt.figure(figsize=(16, 6))
    sns.heatmap(pivot, cmap='YlOrRd', linewidths=.5)
    plt.title('Weekly Chat Activity Heatmap')
    plt.show()

3.2 关键词词云生成

使用wordcloudjieba生成中文词云:

from wordcloud import WordCloud
import jieba

def generate_wordcloud(texts, output_image):
    # 中文分词
    word_list = [" ".join(jieba.cut(text)) for text in texts if isinstance(text, str)]
    all_words = " ".join(word_list)
    
    # 生成词云
    wc = WordCloud(font_path='simhei.ttf',
                  background_color='white',
                  max_words=200,
                  width=800,
                  height=600)
    wc.generate(all_words)
    
    wc.to_file(output_image)

3.3 情感趋势分析

使用snownlp进行简单情感分析:

from snownlp import SnowNLP

def sentiment_analysis(df):
    df['sentiment'] = df['content'].apply(
        lambda x: SnowNLP(x).sentiments if isinstance(x, str) else 0.5)
    
    # 按周计算平均情感值
    df['date'] = pd.to_datetime(df['datetime']).dt.date
    weekly = df.groupby(pd.to_datetime(df['date']).dt.to_period('W'))['sentiment'].mean()
    
    weekly.plot(figsize=(12, 4), title='Weekly Sentiment Trend')

4. 制作交互式聊天年鉴

将上述分析整合成一个HTML年鉴报告:

from jinja2 import Template

def generate_yearbook(data, template_path, output_html):
    # 准备数据
    stats = {
        'total_messages': len(data),
        'top_days': data['date'].value_counts().head(5).to_dict(),
        'active_hours': data['hour'].value_counts().head(3).index.tolist()
    }
    
    # 读取模板
    with open(template_path, 'r', encoding='utf-8') as f:
        template = Template(f.read())
    
    # 渲染输出
    html = template.render(
        stats=stats,
        heatmap_image='heatmap.png',
        wordcloud_image='wordcloud.png'
    )
    
    with open(output_html, 'w', encoding='utf-8') as f:
        f.write(html)

配套的HTML模板可以包含:

  • 对话统计摘要
  • 活动热力图
  • 关键词词云
  • 情感趋势图表
  • 精选对话片段

注意:完整实现需要提前保存可视化图片到指定路径

5. 工程化部署建议

要让这个方案真正实现"全自动",可以考虑以下增强措施:

  1. 自动化触发

    • 使用watchdog监控CSV文件变化
    • 设置定时任务定期运行分析
  2. 配置化管理

    # config.yaml
    input_path: ./message.csv
    output_dir: ./reports
    target_users:
      - wxid_abcdefghij
      - wxid_klmnopqrst
    exclude_keywords:
      - "撤回"
      - "红包"
    
  3. 异常通知

    • 添加邮件/Slack通知功能
    • 使用logging记录处理历史
  4. 性能优化

    • 对大型CSV使用chunksize分块读取
    • 考虑使用polars替代pandas处理超大数据集

这套方案在我处理超过2GB的微信导出数据时表现良好,平均处理时间在10分钟左右。最关键的是清洗规则的持续优化——建议定期审查过滤结果,调整关键词列表以适应微信的新消息类型。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐