WeChatMsg/wxManager/parser/link_parser.py
2025-03-28 21:43:32 +08:00

1233 lines
43 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2025/1/10 2:02
@Author : SiYuan
@Email : 863909694@qq.com
@File : wxManager-link_parser.py
@Description :
"""
import html
import traceback
from datetime import datetime, timedelta
import xml.etree.ElementTree as ET
from typing import List
import xmltodict
from wxManager.log import logger
from wxManager.model import *
def parser_link(xml_content):
result = {
'title': '',
'desc': '',
'url': '',
'appname': '',
'appid': '',
'cover_url': '',
'sourcedisplayname': '',
'sourceusername': ''
}
xml_content = xml_content.strip()
try:
xml_dict = xmltodict.parse(xml_content)
dic = xml_dict.get('msg', {})
cover_url = dic.get('appmsg', {}).get('thumburl', '')
if not cover_url:
cover_url = dic.get('appmsg', {}).get('songalbumurl', '')
result = {
'title': dic.get('appmsg', {}).get('title', ''),
'desc': dic.get('appmsg', {}).get('des', ''),
'url': dic.get('appmsg', {}).get('url', ''),
'cover_url': cover_url,
'sourcedisplayname': dic.get('appmsg', {}).get('sourcedisplayname', ''),
'appname': dic.get('appinfo', {}).get('appname', ''),
'appid': dic.get('appmsg', {}).get('@appid', ''),
'sourceusername': dic.get('appmsg', {}).get('sourceusername', ''),
}
except:
logger.error(traceback.format_exc())
finally:
return result
def parser_voip(xml_content):
result = {
'invite_type': 0,
'duration': 0,
'display_content': ''
}
if not xml_content:
return result
try:
xml_content = xml_content.strip()
xml_dict = xmltodict.parse(f'<voipdata>{xml_content}</voipdata>')
dic = xml_dict.get('voipdata', {})
type_ = dic.get('voipmsg', {}).get('@type')
duration = 0
if type_ == 'VoIPBubbleMsg':
invite_type = -1
display_content = dic.get('voipmsg', {}).get('VoIPBubbleMsg', {}).get('msg', '')
else:
invite_type = dic.get('voipinvitemsg', {}).get('invite_type', '0')
duration = dic.get('voiplocalinfo', {}).get('duration', '0')
display_content = dic.get('voiplocalinfo', {}).get('diaplay_content', '')
result = {
'invite_type': int(invite_type),
'duration': duration,
'display_content': display_content
}
except:
logger.error(traceback.format_exc())
finally:
return result
def parser_applet(xml_content):
result = {
'title': '',
'desc': '',
'url': '',
'app_icon': ''
}
xml_content = xml_content.strip()
try:
xml_dict = xmltodict.parse(xml_content)
dic = xml_dict.get('msg', {})
weappinfo = dic.get('appmsg', {}).get('weappinfo', {})
cover_url = weappinfo.get('weapppagethumbrawurl', '')
if not cover_url:
cover_url = weappinfo.get('weapppagethumbrawurl', '')
if not cover_url:
page_path = weappinfo.get('pagepath', '')
# 按 '&' 分割字符串
parts = page_path.split('&')
# 遍历每个部分,找到以 'cover=' 开头的部分
for part in parts:
if part.startswith('cover='):
# 提取 cover 后面的连接
cover_url = part.split('=')[1]
result = {
'title': dic.get('appmsg', {}).get('title', ''),
'desc': dic.get('appmsg', {}).get('des', ''),
'url': dic.get('appmsg', {}).get('url', ''),
'appname': dic.get('appmsg', {}).get('sourcedisplayname', ''),
'appid': weappinfo.get('@appid', ''),
'app_icon': weappinfo.get('weappiconurl', ''),
'cover_url': cover_url,
}
except:
logger.error(traceback.format_exc())
finally:
return result
def parser_music(xml_content):
if not xml_content:
return {"type": 3, "title": "发生错误", "is_error": True}
try:
root = ET.XML(xml_content)
appmsg = root.find("appmsg")
msg_type = int(appmsg.find("type").text)
title = appmsg.find("title").text
if len(title) >= 39:
title = title[:38] + "..."
artist = appmsg.find("des").text
link_url = appmsg.find("url").text # 链接地址
try:
songalbumurl = appmsg.find('songalbumurl').text # 封面地址
except:
songalbumurl = ''
try:
website_name = root.find('appinfo').find('appname').text
except:
website_name = 'QQ音乐'
return {
"type": msg_type,
"title": title,
"artist": artist,
"url": link_url,
"songalbumurl": songalbumurl,
"appname": website_name,
"is_error": False,
}
except Exception as e:
logger.error(f'音乐分享解析失败\n{traceback.format_exc()}')
print(f"Music Share Error: {e}")
return {"type": 3, "title": "发生错误", "is_error": True}
def parser_business(xml_content):
result = {
'bigheadimgurl': '', # 头像原图
'smallheadimgurl': '', # 小头像
'username': '', # wxid
'nickname': '', # 昵称
'alias': '', # 微信号
'province': '', # 省份
'city': '', # 城市
'sex': 1, # int :性别 0未知12
'sign': '', # 签名
'openimdesc': '', # 公司名
'openimdescicon': '', # 公司名前面的图标
}
xml_content = xml_content.strip()
try:
data = xmltodict.parse(xml_content.replace('&', '&amp;'))
if data and data.get('msg'):
data = data['msg']
result['bigheadimgurl'] = data.get('@bigheadimgurl')
result['smallheadimgurl'] = data.get('@smallheadimgurl')
result['username'] = data.get('@username')
result['nickname'] = data.get('@nickname')
result['alias'] = data.get('@alias')
result['province'] = data.get('@province')
result['city'] = data.get('@city')
result['sign'] = data.get('@sign')
result['sex'] = int(data.get('@sex', ''))
result['openimdesc'] = data.get('@openimdesc')
result['openimdescicon'] = data.get('@openimdescicon')
return result
except:
logger.error(f'名片解析错误\n{traceback.format_exc()}\n{xml_content}')
result.update(
{
'type': 1,
'text': '【名片解析错误】'
}
)
finally:
return result
def parser_record_item(recorditem, output_dir, wxid, msg_time, level=0):
xml_string = recorditem
if isinstance(xml_string, dict):
recorditem_dic = xml_string
else:
recorditem_dic = xmltodict.parse(xml_string)
# logger.error(recorditem_dic)
datalist = recorditem_dic.get('recordinfo', {}).get('datalist', {})
count = datalist.get('@count', 0)
dataitem = datalist.get('dataitem', [])
result = []
if isinstance(dataitem, dict):
# 转发单条消息
dataitem = [dataitem]
# logger.info(dataitem)
for item in dataitem:
# logger.info(item)
type_ = item.get('@datatype')
timestamp = item.get('srcMsgCreateTime')
if timestamp:
timestamp = int(timestamp)
else:
timestamp = 0
str_time = item.get('sourcetime')
if not timestamp:
try:
# 将字符串转换为datetime对象
dt = datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
except:
if '上午' in str_time:
str_time = str_time.replace('上午 ', '上午')
time_format = '%Y-%m-%d 上午%H:%M'
dt = datetime.strptime(str_time, time_format) + timedelta(hours=12)
elif '下午' in str_time:
str_time = str_time.replace('下午 ', '下午')
time_format = '%Y-%m-%d 下午%H:%M'
# 解析后需要加12小时来转换成24小时制
dt = datetime.strptime(str_time, time_format) + timedelta(hours=12)
else:
try:
import dateparser
str_time = str_time.replace('&#x20;', ' ')
dt = dateparser.parse(str_time)
if dt is None:
raise ValueError("无法解析时间字符串")
timestamp = dt.timestamp()
except:
logger.error(f'未知的时间格式:{str_time}')
dt = datetime.strptime('1970-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
try:
# 将datetime对象转换为时间戳
timestamp = int(dt.timestamp())
except:
logger.error(f'未知的时间格式:{str_time}')
dt = datetime.strptime('1970-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
if type_ == '1':
# 纯文本
content = item.get('datadesc')
if item.get('refermsgitem'):
refermsg = item.get('refermsgitem', {}).get('referdesc', '')
content = f"{content}\n{refermsg}"
result.append(
TextMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.Text,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
content=content
)
)
elif type_ == '2':
"""
合并转发的聊天记录
"""
# 图片 & 表情包
md5 = item.get('fullmd5', '')
msg = ImageMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.Image,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
md5=md5,
path='',
thumb_path='',
file_size=0,
file_name='',
file_type='png'
)
result.append(
msg
)
elif type_ == '37':
"""
合并转发的聊天记录
"""
#表情包
md5 = item.get('fullmd5', '')
msg = EmojiMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.Emoji,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
md5=md5,
path='',
thumb_path='',
file_size=0,
file_name='',
file_type='png',
url='',
thumb_url='',
description=''
)
emoji_item = item.get('emojiitem', {})
msg.url = emoji_item.get('cdnurlstring', '')
msg.thumb_url = emoji_item.get('cdnurlstring', '')
result.append(
msg
)
elif type_ == '3':
# 语音
result.append(
TextMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.Audio,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
content='【转发语音不可播放】'
)
)
elif type_ == '4':
# 视频
md5 = item.get('fullmd5', '')
path = item.get('datasourcepath', '')
result.append(
VideoMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.Video,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
md5=md5,
path=path,
file_size=0,
file_name='',
file_type='mp4',
thumb_path='',
duration=0,
raw_md5=md5
)
)
elif type_ == '5':
# 链接
web_item = item.get('weburlitem', {})
result.append(
LinkMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.LinkMessage,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
href=web_item.get('url', ''),
title=web_item.get('title', ''),
description=web_item.get('desc', ''),
cover_path='',
cover_url='',
app_name=web_item.get('appmsgshareitem', {}).get('srcdisplayname'),
app_icon='',
app_id=''
)
)
elif type_ == '6':
# 位置分享
locitem = item.get('locitem', {})
label = locitem.get('label', '')
poiname = locitem.get('poiname', '')
try:
x = float(locitem.get('lng', '0'))
y = float(locitem.get('lat', '0'))
scale = float(locitem.get('scale', '0'))
except:
x, y, scale = 0, 0, 0
result.append(
PositionMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.Position,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
x=x,
y=y,
label=label,
poiname=poiname,
scale=scale
)
)
elif type_ == '8':
# 文件
md5 = item.get('fullmd5', '')
datasize = item.get('datasize')
if datasize:
datasize = int(datasize)
else:
datasize = 0
result.append(
FileMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.File,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
path='',
md5=md5,
file_type=item.get('datafmt', ''),
file_name=item.get('datatitle', ''),
file_size=datasize
)
)
elif type_ == '17':
# 嵌套的消息
result.append(
MergedMessage(
local_id=0,
server_id=0,
sort_seq=0,
timestamp=timestamp,
str_time=str_time,
type=MessageType.MergedMessages,
talker_id='',
is_sender=False,
sender_id='',
display_name=item.get('sourcename'),
avatar_src=item.get('sourceheadurl'),
status=0,
xml_content='',
title=item.get('datatitle'),
description=item.get('datadesc'),
messages=parser_record_item(item.get('recordxml'), output_dir, wxid,
msg_time, level + 1),
level=level
)
)
return result
def parser_merged_messages(xml, output_dir, wxid, msg_time, level=0):
try:
try:
data_dic = xmltodict.parse(xml).get('msg', {})
except:
new_xml1 = html.unescape(xml)
new_xml2 = new_xml1.replace('&', '&amp;')
# xml = xml.replace('&#x20;', ' ').replace('&#15;', '').replace('&#x0A;', '\n').replace('\xa0',' ') # 搞不懂这帮人在干嘛,有些转义,有些不转义
# html.unescape(xml)
data_dic = xmltodict.parse(new_xml2).get('msg', {})
app_msg_dic = data_dic.get('appmsg', {})
desc = app_msg_dic.get('des', '')
title = app_msg_dic.get('title', '')
recorditem = app_msg_dic.get('recorditem', '')
return {
'title': title, # 标题
'desc': desc, # 描述
'messages': parser_record_item(recorditem, output_dir, wxid, msg_time, level), # List[dict] 消息内容
}
except:
logger.error(xml)
logger.error(new_xml1)
logger.error(new_xml2)
logger.error(traceback.format_exc())
# raise ValueError('合并转发的消息解析失败')
return {
'title': '解析失败', # 标题
'desc': '合并转发的消息解析失败', # 描述
'messages': []
}
def parser_wechat_video(xml_content):
result = {
'appid': '', # 暂时不用
'title': '', # 标题
'sourcedisplayname': '', # 视频号名称
'weappiconurl': '', # 视频号logo
'authIconUrl': '', # 视频号认证URL昵称后缀
'cover': '', # 封面url
'duration': 0
}
xml_content = xml_content.strip()
try:
dic_data = xmltodict.parse(xml_content).get('msg', {}).get('appmsg', {}).get('finderFeed', {})
sourcedisplayname = dic_data.get('nickname', '')
weappiconurl = dic_data.get('avatar', '')
authIconUrl = dic_data.get('authIconUrl', '')
title = dic_data.get('desc', '')
media_count = dic_data.get('mediaCount', '0')
if media_count > '1':
cover = dic_data.get('mediaList', {}).get('media', [])[0].get('thumbUrl', '')
duration = 0
else:
cover = dic_data.get('mediaList', {}).get('media', {}).get('coverUrl', '')
duration = dic_data.get('mediaList', {}).get('media', {}).get('videoPlayDuration', 0)
result = {
'title': title,
'url': '',
'sourcedisplayname': sourcedisplayname,
'weappiconurl': weappiconurl,
'cover': cover,
'authIconUrl': authIconUrl,
'duration': duration
}
except:
logger.error(traceback.format_exc())
finally:
return result
def parser_position(xml_content):
result = {
'x': '0', # 经度
'y': '0', # 维度
'label': '', # 详细标签
'poiname': '', # 位置点标记名
'scale': '0', # 缩放率
}
try:
data = xmltodict.parse(xml_content)
if data and data.get('msg'):
data = data['msg']
result['x'] = data['location']['@x']
result['y'] = data['location']['@y']
result['label'] = data['location'].get('@label')
result['poiname'] = data['location'].get('@poiname')
result['scale'] = data['location'].get('@scale')
except:
logger.error(f'位置分享解析错误\n{traceback.format_exc()} \n{xml_content}')
result.update(
{
'type': 1,
'text': '【位置分享解析错误】'
}
)
finally:
return result
def parser_reply(xml_content):
"""
@param data:
@return: {
"text": '发生错误', 发送内容
'svrid': '', 引用消息id
'refermsg_type': -1, 引用消息类型
"refer_text": '引用错误', 引用内容
}
"""
if not xml_content:
return {
# "type": msg_type,
"text": '发生错误',
'svrid': '',
'refermsg_type': -1,
"refer_text": '引用错误',
}
xml_content = xml_content.replace("&#01;", "").replace('&#20;', '')
try:
data = xmltodict.parse(xml_content).get('msg', {}).get('appmsg', {})
refermsg_type = int(data.get('refermsg', {}).get('type', '1'))
title = data.get('title', '')
displayname = data.get('refermsg', {}).get('displayname', '')
svrid = data.get('refermsg', {}).get('svrid', 0)
return {
"text": title,
'svrid': svrid,
'refermsg_type': refermsg_type,
}
# if refermsg_type == 1:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{refermsg_displayname}{refermsg_content}",
# }
# elif refermsg_type == 3:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}:【图片消息】",
# }
# elif refermsg_type == 34:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}:【语音消息】",
# }
# elif refermsg_type == 43:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}:【视频消息】",
# }
# elif refermsg_type == 47:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}:【表情包】",
# }
# elif refermsg_type == 49:
# content = data.get('refermsg', {}).get('content', '')
# content = xmltodict.parse(content).get('msg', {}).get('appmsg', {})
# refermsg_content = content.get('title', '')
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}{refermsg_content}",
# "url": content.get('url', ''),
# }
# elif refermsg_type == 0:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": data.get('refermsg', {}).get('ref_msg_text', ''),
# }
# elif refermsg_type == 66:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}:【名片分享】",
# }
# elif refermsg_type == 42:
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}:【名片分享】",
# }
# elif refermsg_type == 48:
# position_dict = xmltodict.parse(data.get('refermsg', {}).get('content', '')).get('msg')
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}{position_dict['location'].get('@poiname')}",
# }
# else:
# logger.info(f'发现未知的引用消息\n{data}')
# return {
# # "type": msg_type,
# "text": title,
# 'svrid': data.get('refermsg', {}).get('svrid', 0),
# 'refermsg_type': refermsg_type,
# "refer_text": f"{displayname}:【其他消息】",
# }
except:
logger.error(f'{xml_content}\n\n引用消息解析错误\n{traceback.format_exc()}')
return {
# "type": msg_type,
"text": '发生错误',
'svrid': '',
'refermsg_type': -1,
"refer_text": '引用错误',
}
def parser_transfer(xml_content):
result = {
'pay_subtype': 0,
'pay_memo': '',
'fee_desc': '',
'receiver_username': ''
}
try:
data = xmltodict.parse(xml_content).get('msg', {}).get('appmsg', {})
result = {
'pay_subtype': int(data.get('wcpayinfo', {}).get('paysubtype', '-1')),
'pay_memo': data.get('wcpayinfo', {}).get('pay_memo', ''),
'fee_desc': data.get('wcpayinfo', {}).get('feedesc', ''),
'receiver_username': data.get('wcpayinfo', {}).get('receiver_username', ''),
}
except:
logger.error(f'转账解析错误\n{traceback.format_exc()}')
result.update(
{
'type': 1,
'text': '【位置分享解析错误】'
}
)
finally:
return result
def parser_red_envelop(xml_content):
result = {
'icon_url': '',
'title': '',
'inner_type': 0
}
try:
data = xmltodict.parse(xml_content).get('msg', {}).get('appmsg', {})
result = {
'icon_url': data.get('wcpayinfo', {}).get('iconurl', ''),
'title': data.get('wcpayinfo', {}).get('receivertitle', ''),
'inner_type': int(data.get('wcpayinfo', {}).get('innertype', '0')),
}
except:
logger.error(f'红包解析错误\n{traceback.format_exc()}')
result.update(
{
'type': 1,
'text': '【位置分享解析错误】'
}
)
finally:
return result
def parser_file(xml_content):
result = {
'file_name': '',
'file_size': 0,
'md5': '',
'file_type': '',
'app_name': ''
}
try:
data0 = xmltodict.parse(xml_content).get('msg', {})
data = data0.get('appmsg', {})
totallen = data.get('appattach', {}).get('totallen')
if isinstance(totallen, list):
totallen = totallen[0]
if not totallen:
totallen = '0'
result = {
'file_name': data.get('title', ''),
'file_size': int(totallen),
'md5': data.get('md5', ''),
'file_type': data.get('appattach', {}).get('fileext', ''),
'app_name': data.get('appinfo', {}).get('appname', ''),
}
except:
logger.error(f'文件解析错误\n{traceback.format_exc()}\n{xml_content}')
finally:
return result
def parser_favorite_note(xml_content):
result = {
'title': '',
'desc': '',
'recorditem': '',
}
try:
data = xmltodict.parse(xml_content).get('msg', {}).get('appmsg', {})
recorditem = data.get('recorditem', '')
xml_string = recorditem
if isinstance(xml_string, dict):
recorditem_dic = xml_string
else:
recorditem_dic = xmltodict.parse(xml_string)
result = {
'title': data.get('title', ''),
'desc': data.get('des', ''),
'recorditem': recorditem_dic,
}
except:
logger.error(f'笔记解析错误\n{traceback.format_exc()}')
finally:
return result
def parser_pat(xml_content):
result = {
'title': '',
'from_username': '',
'patted_username': '',
'chat_username': '',
'template': ''
}
try:
data = xmltodict.parse(xml_content).get('msg', {}).get('appmsg', {})
patinfo = data.get('patinfo', {})
result = {
'title': data.get('title', ''),
'from_username': patinfo.get('fromusername', ''),
'patted_username': patinfo.get('pattedusername', ''),
'chat_username': patinfo.get('chatusername', ''),
'template': patinfo.get('template', ''),
}
except:
logger.error(f'拍一拍解析错误\n{traceback.format_exc()}\n{xml_content}')
finally:
return result
if __name__ == '__main__':
pass
def wx_sport(xml):
dic_data = {}
more = ''
try:
dic_data = xmltodict.parse(xml).get('msg', {}).get('appmsg', {})
hardwareinfo = dic_data.get('hardwareinfo', {})
rankinfo = hardwareinfo.get('messagenodeinfo', {}).get('rankinfo', {})
rank = rankinfo.get('rank', {}).get('rankdisplay', '')
score = rankinfo.get('score', {}).get('scoredisplay', '')
rankinfolist = hardwareinfo.get('rankview', {}).get('rankinfolist', {}).get('rankinfo', [])
rank_list = []
for rank_info in rankinfolist:
username = rank_info.get('username', '')
rank1 = rank_info.get('rank', {}).get('rankdisplay', '')
score1 = rank_info.get('score', {}).get('scoredisplay', '')
rank_list.append(
{
'rank': rank1,
'score': score1,
'username': username
}
)
return {
'rank': rank,
'score': score,
'rank_list': rank_list,
'data': f'{dic_data}'
}
except:
logger.error(traceback.format_exc())
logger.error(dic_data)
return []
def wx_EMS_data(bytesExtra, compress_content_):
dic_data = {}
send_city = ''
send_name = ''
express_id = ''
send_time = ''
send_address = ''
courier = ''
courier_phone = ''
expect_handle = ''
sign_time = ''
sign_result = ''
remark = ''
update_time = ''
try:
if isinstance(compress_content_, bytes):
xml = decompress_CompressContent(compress_content_)
else:
xml = compress_content_
dic_data = xmltodict.parse(xml).get('msg', {}).get('appmsg', {})
mmreader = dic_data.get('mmreader', {})
template_header = mmreader.get('template_header', {})
template_detail = mmreader.get('template_detail', {})
if not template_header or not template_detail:
return {}
title = template_header.get('title', '')
digest = template_header.get('first_data', '')
display_name = template_header.get('display_name', '')
if not title:
title = dic_data.get('title', '')
if not display_name:
display_name = dic_data.get('title')
line_content = template_detail.get('line_content', {})
lines = line_content.get('lines', {}).get('line')
if isinstance(lines, List):
for line in lines:
key = line.get('key').get('word')
value = line.get('value').get('word')
if key.startswith('寄件城市'):
send_city += value
elif key.startswith('寄件人'):
send_name += value
elif key.startswith('快递单号') or key == '运单号':
express_id += value
elif key.startswith('寄件时间'):
send_time += value
elif key.startswith('派送地址'):
send_address += value
elif key.startswith('快递员'):
courier += value
elif key.startswith('快递员电话'):
courier_phone += value
elif key.startswith('预计派送处理'):
expect_handle += value
elif key.startswith('签收时间'):
sign_time += value
elif key.startswith('签收结果'):
sign_result += value
elif key == '备注:':
remark += value
elif key == '更新时间:':
update_time += value
else:
return {}
return {
'title': title,
'digest': digest,
'display_name': display_name,
'send_city': send_city,
'send_name': send_name,
'express_id': express_id,
'send_time': send_time,
'send_address': send_address,
'courier': courier,
'courier_phone': courier_phone,
'expect_handle': expect_handle,
'sign_time': sign_time,
'sign_result': sign_result,
'remark': remark,
'update_time': update_time,
'data': f'{dic_data}',
}
except:
logger.error(traceback.format_exc())
logger.error(dic_data)
return {}
def wx_pdd_data(bytesExtra, compress_content_):
title = ''
display_name = ''
dic_data = {}
product = ''
order_id = ''
express = ''
express_id = ''
sign_time = ''
product_num = ''
pdd_member = ''
order_status = ''
refund_money = ''
refund_status = ''
audit_explain = ''
problem_type = ''
submit_time = ''
handle_result = ''
phone_number = ''
recharge_money = ''
refund_method = ''
user_name = ''
order_money = ''
try:
if isinstance(compress_content_, bytes):
xml = decompress_CompressContent(compress_content_)
else:
xml = compress_content_
dic_data = xmltodict.parse(xml).get('msg', {}).get('appmsg', {})
mmreader = dic_data.get('mmreader', {})
template_header = mmreader.get('template_header', {})
template_detail = mmreader.get('template_detail', {})
if not template_header or not template_detail:
return {}
title = template_header.get('title', '')
display_name = template_header.get('display_name', '')
if not title:
title = dic_data.get('title', '')
if not display_name:
display_name = dic_data.get('title')
line_content = template_detail.get('line_content', {})
lines = line_content.get('lines', {}).get('line')
if isinstance(lines, List):
for line in lines:
key = line.get('key').get('word')
value = line.get('value').get('word')
if key == '商品名称:' or key == '商品信息:' or key == '商品:' or key == '商品详情:' or key.startswith(
'商品名'):
product += value
elif key == '订单编号:' or key == '订单号:':
order_id += value
elif key == '物流服务:' or key == '快递公司:':
express += value
elif key == '快递单号:':
express_id += value
elif key == '签收时间:':
sign_time += value
elif key == '商品数量:':
product_num += value
elif key == '拼单成员:':
pdd_member += value
elif key == '订单状态:':
order_status += value
elif key == '退款金额:':
refund_money += value
elif key == '退款状态:':
refund_status += value
elif key == '审核说明:':
audit_explain += value
elif key == '问题类型:':
problem_type += value
elif key == '提交时间:':
submit_time += value
elif key == '处理结果:':
handle_result += value
elif key == '充值号码:':
phone_number += value
elif key == '充值金额:':
recharge_money += value
elif key == '退款方式:':
refund_method += value
elif key == '用户名:':
user_name += value
elif key == '订单金额:':
order_money += value
except:
logger.error(traceback.format_exc())
logger.error(dic_data)
finally:
return {
'title': title,
'display_name': display_name,
'product': product,
'order_id': order_id,
'express': express,
'express_id': express_id,
'sign_time': sign_time,
'product_num': product_num,
'pdd_member': pdd_member,
'order_status': order_status,
'refund_money': refund_money,
'refund_status': refund_status,
'audit_explain': audit_explain,
'problem_type': problem_type,
'submit_time': submit_time,
'handle_result': handle_result,
'phone_number': phone_number,
'recharge_money': recharge_money,
'refund_method': refund_method,
'user_name': user_name,
'order_money': order_money,
'data': f'{dic_data}',
}
def wx_collection_data(xml):
dic_data = {}
summary = ''
more = ''
try:
dic_data = xmltodict.parse(xml).get('msg', {}).get('appmsg', {})
# logger.error(dic_data)
mmreader = dic_data.get('mmreader', {})
template_header = mmreader.get('template_header', {})
template_detail = mmreader.get('template_detail', {})
title = template_header.get('title', '')
display_name = template_header.get('display_name', '')
if not title:
title = dic_data.get('title', '')
if not display_name:
display_name = dic_data.get('title')
template_id = dic_data.get('template_id', '')
line_content = template_detail.get('line_content', {})
money = line_content.get('topline', {}).get('value', {}).get('word', '').strip('')
lines = line_content.get('lines', {}).get('line')
if isinstance(lines, List):
for line in lines:
key = line.get('key').get('word')
value = line.get('value').get('word')
if key == '汇总':
summary += value
elif key == '备注':
more += value
return {
'title': title,
'display_name': display_name,
'template_id': template_id,
'money': money,
'summary': summary,
'data': f'{dic_data}',
'more': more
}
except:
logger.error(traceback.format_exc())
logger.error(dic_data)
return {}
def wx_pay_data(xml):
dic_data = {}
more = ''
try:
dic_data = xmltodict.parse(xml).get('msg', {}).get('appmsg', {})
# logger.error(dic_data)
mmreader = dic_data.get('mmreader', {})
template_header = mmreader.get('template_header', {})
template_detail = mmreader.get('template_detail', {})
title = template_header.get('title', '')
display_name = template_header.get('display_name', '')
if not title:
title = dic_data.get('title', '')
if not display_name:
display_name = dic_data.get('title')
template_id = dic_data.get('template_id', '')
line_content = template_detail.get('line_content', {})
money = line_content.get('topline', {}).get('value', {}).get('word', '').strip('')
lines = line_content.get('lines', {}).get('line')
payment_type = ''
acquiring_institution = ''
if isinstance(lines, List):
for line in lines:
key = line.get('key').get('word')
value = line.get('value').get('word')
if key == '付款方式' or key == '支付方式' or key == '收款账户' or key == '退款方式':
payment_type = value
elif key == '收单机构' or key == '收款方':
acquiring_institution = value
elif key == '退款方式':
payment_type = value
elif key == '退款原因':
acquiring_institution = value
elif key == '备注' or key == '退款原因':
more += value
else:
payment_type = line_content.get('topline', {}).get('key', {}).get('word', '')
acquiring_institution = '个体商户'
return {
'title': title,
'display_name': display_name,
'template_id': template_id,
'money': money,
'payment_type': payment_type,
'acquiring_institution': acquiring_institution,
'data': f'{dic_data}',
'more': more
}
except:
logger.error(traceback.format_exc())
logger.error(dic_data)
return {}