在使用《获取企业微信聊天记录》指令的时候,每条消息是有具体的时间标识的。

而使用《获取个人微信聊天内容》的时候,却缺少这样的时间标志,在需要进行聊天记录去重的时候是非常不方便的。因此我们要把他转换有带有时间标识的形式,跟企业微信一样,每一条都加上send_time。


1、微信的系统消息时间是有规律的,大致分为几种,"上午 10:07","下午 14:07","晚上 20:07","昨天 16:07","星期天 19:27","星期二 19:27","2025年1月10日 17:43","15:21",可以根据规律把他们转换成类似于“2025/02/02 17:10:00”的样式。
2、每条系统消息后面的第一条消息发送时间是已知的,因为微信上没有显示具体的秒数,因此我们都默认成00秒,后面每新增一条信息,在默认的时间基础上+1秒,直到遇到下一条系统消息为止。
3、有一种极端的情况,如果两条系统消息之间相差1分钟,而这1分钟内有多与60条的消息,例如有70条消息,那么第60-70条消息对应的秒数都是59秒。也就是当消息条数大于两条系统消息之间相差的秒数,多出来的消息对应的秒数都是59。
4、也要考虑“消息撤回”的情况。
#-*- coding:utf-8-*
from datetime import datetime, timedelta
import re
def addSendTime(list_content):
def format_time(time_str):
# 解析时间字符串为datetime对象
dt = datetime.strptime(time_str, '%Y/%m/%d %H:%M')
# 格式化datetime对象为所需格式的字符串
formatted_time_str = dt.strftime('%Y/%m/%d %H:%M:%S')
return formatted_time_str
def get_weekdays_dict_from_last_sunday_to_today():
# 假设今天是2025年1月26日(可以根据实际情况动态获取)
today = datetime.today().date()
#获取上周周日日期
last_sunday=""
if today.weekday() == 6: # 注意weekday()方法中周日返回的是6
last_sunday = today - timedelta(days=7)
else:
days_since_last_sunday = (today.weekday() + 1) % 7
last_sunday = today - timedelta(days=days_since_last_sunday)
# print(last_sunday.strftime("%Y-%m-%d"))
# 起始日期和结束日期
start_date = last_sunday
end_date = today
time_periods_of_week = {
"Sunday":"星期天",
"Monday": "星期一",
"Tuesday": "星期二",
"Wednesday": "星期三",
"Thursday": "星期四",
"Friday": "星期五",
"Saturday": "星期六"
}
# 创建一个字典来保存结果
dates_dict = {}
# 开始循环的日期
current_date = start_date
while current_date <= end_date:
dates_dict[time_periods_of_week[current_date.strftime("%A")]] = current_date.strftime("%Y/%m/%d")
# 增加一天
current_date += timedelta(days=1)
return dates_dict
def convertToStandardTime(date_list):
week_dates_dict=get_weekdays_dict_from_last_sunday_to_today()
today = datetime.now()
# 定义时间段映射
time_periods = {
"上午": "AM",
"下午": "PM",
"晚上": "PM"
}
for idx,item in enumerate(date_list):
# 处理时间段
for period, replacement in time_periods.items():
if period in item:
item=item.replace(period,"").strip()
item=item+f" {replacement}"
break
# 处理昨天
if "昨天" in item:
yesterday = today - timedelta(days=1)
item = item.replace("昨天", yesterday.strftime("%Y/%m/%d"))
date_list[idx] = format_time(item)
elif "星期" in item:
for key,value in week_dates_dict.items():
if key in item:
item = item.replace(key,value)
date_list[idx] = format_time(item)
break
# 处理具体日期
elif re.match(r"\d{4}年\d{1,2}月\d{1,2}日", item):
date_time = datetime.strptime(item, "%Y年%m月%d日 %H:%M")
date_list[idx] = date_time.strftime("%Y/%m/%d %H:%M:%S")
# 处理时间
else:
# 处理24小时制时间
if re.match(r"^\d{1,2}:\d{2}$",item):
#只有时间
date_time = datetime.strptime(item, "%H:%M")
else:
#带有AM或者PM的日期和时间
date_time = datetime.strptime(item.strip(), "%I:%M %p")
date_time = date_time.replace(year=today.year, month=today.month, day=today.day)
date_list[idx]=date_time.strftime("%Y/%m/%d %H:%M:%S")
return date_list
for idx,loop_item in enumerate(list_content):
if loop_item["id"]==0 and "撤回了一条消息" not in loop_item["content"]:
list_content[idx]["content"]=convertToStandardTime([loop_item["content"]])[0]
result_list = []
last_system_time = None
increment_seconds = 0
for i, item in enumerate(list_content):
if item['id'] == 0 and "撤回了一条消息" not in item['content']: # 系统消息
last_system_time = datetime.strptime(item['content'], '%Y/%m/%d %H:%M:%S')
increment_seconds = 0
end_time=None
limited_seconds=0
#获取系统消息之间的间隔秒数
for item in list_content[i+1:len(list_content)]:
if item['id'] == 0 and "撤回了一条消息" not in item['content']:
end_time=datetime.strptime(item['content'],'%Y/%m/%d %H:%M:%S')
break
if end_time != None:
time_difference=end_time-last_system_time
# 获取间隔秒数
limited_seconds = time_difference.total_seconds()
# print(f"{last_system_time} 到 {end_time} 之间有 {limited_seconds} 秒")
else:
new_item = item.copy()
if end_time != None:
if increment_seconds < limited_seconds:
new_item['send_time'] = (last_system_time + timedelta(seconds=increment_seconds)).strftime('%Y/%m/%d %H:%M:%S')
else:
new_item['send_time'] = (last_system_time + timedelta(seconds=limited_seconds-1)).strftime('%Y/%m/%d %H:%M:%S')
else:
new_item['send_time'] = (last_system_time + timedelta(seconds=increment_seconds)).strftime('%Y/%m/%d %H:%M:%S')
increment_seconds += 1
result_list.append(new_item)
return result_list
list_content=[{'id': 0, 'name': '系统消息', 'content': '星期天 17:10'}, {'id': 2, 'name': '九思班班', 'content': '[视频号]'}, {'id': 2, 'name': '九思班班', 'content': '蛇年新春福运绕,初五财神把门敲![呲牙]\n\nBT 教育祝大家新岁鸿运当头,存款狂飙,机遇不断,万事皆顺意!\n\n新的一年跟着彬哥一起拿下 CPA,左手知识,右手财富,考证、赚钱两不误[加油]'}, {'id': 0, 'name': '系统消息', 'content': '14:08'}, {'id': 2, 'name': '九思班班', 'content': 'CPAer全体班会,1小时重回备考状态,新春囤课季优惠倒计时1天,还没有上车的同学抓紧时间[机智]'}, {'id': 2, 'name': '九思班班', 'content': '[图片]'}]
print(addSendTime(list_content))
获取到的聊天内容必须以带有时间的系统消息开头,否则会报错。如果第一条是具体的消息内容,那么需要写循环、上滑的指令,直到获取的列表第一条消息符合条件为止,再使用上述代码。
