利用公众号自动回复制作查询学时(Requests)
本帖最后由 xhtdtk 于 2021-12-22 17:59 编辑前因:小型的教育机构想弄一个查询学时的工具,但是又不想搞的太麻烦怎么办呢,突发奇想利用公众号自动回复的功能不就OK了吗,还能让家长关注公众号。
制作流程:先尝试实现功能,后获取学时数据
尝试实现功能:
一、查看提交的表单数据
对表单里的数据进行分析,我一般采用两个步骤。
第一个步骤:表单数据比较,查看表单数据变化的规律
第一次提交:
第二次提交(同一关键字增加回复消息):
第三次提交(新的关键词回复):
分析:
第一次提交和第二次提交比较:ruleid不同,猜测第一次提交ruleid为0,提交后生成ruleid,说明在同一关键字下增加消息要先获取ruleid;多了一组type,field,content,是新增的回复消息。
第一次提交和第三次提交比较:仅新增的规则不同,没有变化的暂时视为常量。
第二个步骤:查找需要获取的数据
我们每一次点击到实现了最终效果,可能都是在向服务器发送请求,所以我们需要查找的数据更有可能出现在最终效果的某一次点击上。
如果是静态的数据,可以直接查找;如果是动态的,可能涉及一些JS逆向。
在开发者模式下直接查找ruleid的值,直接获取
问题1:即使表单数据准备完整,发送POST请求还是失败了
在查看请求头时发现
{’Content-Type‘: 'application/x-www-form-urlencoded; charset=UTF-8'}
说明表单数据要进行url编码再进行请求
data=urllib.parse.urlencode(data)
问题2:一共可以添加200个关键词回复,每个回复只能添加5个文本,每个文本只能限制300字
写代码时注意,每当文本超过270字左右(误差计算在内270字刚刚好),表单数据就要添加第二个文本
二、根据上课记录表,提取收据
表格格式:
获取数据代码:
def data():
wb=openpyxl.load_workbook('学期上课记录表.xlsx',data_only=True)
dict_student_sign={}
for each_wsname in wb.sheetnames:
if each_wsname=='课时':
continue
ws=wb
for wsrow in range(4,ws.max_row):
if not ws.cell(wsrow,2).value in and not ws.cell(wsrow,2).value in list(dict_student_sign.keys()):
dict_student_sign={}
dict_student_sign['考勤']=[]
for each_wsname in wb.sheetnames:
ws=wb
if each_wsname=='课时':
for wsrow in range(2,ws.max_row+1):
dict_student_sign['课时']=ws.cell(wsrow,2).value
wscolumn=3
str_=''
while True:
if ws.cell(wsrow,wscolumn).value==None:
break
else:
str_=str_+str(ws.cell(wsrow,wscolumn).value)+'+'
wscolumn=wscolumn+1
dict_student_sign['考勤'].append('总课时:'+str_[:-1])
continue
for wsrow in range(4,ws.max_row+1):
if ws.cell(wsrow,2).value in list(dict_student_sign.keys()):
for wscolumn in range(3,33):
if ws.cell(wsrow,wscolumn).value in ['出勤','未出勤','补课']:
x=3
while True:
if wsrow-x>7:
x=x+7
else:
break
if ws.cell(wsrow-(wsrow-x),wscolumn).value in :
title=''
else:
title=ws.cell(wsrow-(wsrow-x),wscolumn).value
if ws.cell(wsrow,wscolumn).value in ['未出勤']:
dict_student_sign['考勤'].append(each_wsname+str(ws.cell(1,wscolumn).value)+'日\n'+ws.cell(wsrow,wscolumn).value+title+'☆余'+str(dict_student_sign['课时']-0)+'课时')
else:
dict_student_sign['考勤'].append(each_wsname+str(ws.cell(1,wscolumn).value)+'日\n'+ws.cell(wsrow,wscolumn).value+title+'★余'+str(dict_student_sign['课时']-2)+'课时')
dict_student_sign['课时']=dict_student_sign['课时']-2
#print(dict_student_sign)
return dict_student_sign
效果:
返回了字典
三、完善功能
查询已发信息(token,cookie需要手动修改):
def chat(token):
header={
'Host': 'mp.weixin.qq.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36',
'Cookie': '自己添加'
}
url='https://mp.weixin.qq.com/advanced/autoreply'
param={
'action': 'smartreply',
'token': token,
'lang': 'zh_CN',
'count': 200,
'offset': 0
}
rep=requests.get(url,headers=header,params=param)
soup=BeautifulSoup(rep.text)
for each_script in soup.find_all('script',type='text/javascript'):
if '// 开启了关键词回复' in str(each_script):
text=re.sub('\n|\r| |<.*?>|//.*,//','',str(each_script))
text=re.sub(',func_ban_info:\\[//能力封禁\\]|\\.replace.*?\\)|//用数组是为了兼容appmsg_gray|\\*1','',text)
text=re.findall('list:(\\[.*\\])',text)
text=re.sub(',}','}',text)
text=json.loads(text)
#print(text)
dict_content={}
for each_student in text:
list_content=[]
student_name=each_student['keyword_list']['content']
ruleid=each_student['rule_id']
dict_content={}
dict_content['rule_id']=ruleid
if each_student['keyword_list']['content']!=None:
for each_reply_list in each_student['reply_list']:
for each_content in each_reply_list['content'].split('时\n'):
if each_content!='':
list_content.append(each_content+'时')
dict_content['content']=list_content
#print(dict_content)
return dict_content
效果:
更新自动回复(token,cookie需要手动修改):
def function(excel_data,web_chat,token):
header={
'Referer': 'https://mp.weixin.qq.com/advanced/autoreply?action=smartreply&t=ivr/keywords&token='+str(token)+'&lang=zh_CN',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36',
'Cookie': '自己添加'
}
url='https://mp.weixin.qq.com/advanced/setreplyrule'
param={
'lang': 'zh_CN',
'cgi': 'setreplyrule',
'fun': 'save',
't': 'ajax-response',
'token': token
}
for each_data in excel_data.keys():
data={'token': token,'lang': 'zh_CN','f': 'json','ajax': 1,'replytype': 'smartreply','allreply': 1,'replycnt': 1,'keywordcnt': 1,'matchmode0': 1}
if not each_data in list(web_chat.keys()):
data['ruleid']=0
else:
data['ruleid']=web_chat['rule_id']
if excel_data['考勤']==web_chat['content']:
continue
data['rulename']=each_data+'剩余课时'
data['keyword0']=each_data
num_content=0
str_content=''
for each_content in excel_data['考勤']:
if len(str_content)<=270:
str_content=str_content+each_content+'\n'
data['content'+str(num_content)]=str_content
data['type'+str(num_content)]=1
data['fileid'+str(num_content)]='undefined'
else:
num_content=num_content+1
str_content=''
all_content=0
for content_content in data.keys():
if 'content' in content_content:
all_content=all_content+1
data['replycnt']=all_content
data=urllib.parse.urlencode(data)
print(each_data+'更新成功')
rep=requests.post(url,headers=header,params=param,data=data)
time.sleep(2)
token和cookie在哪里:
最终效果:
只要更新了上课记录的表格,就能更新到公众号
使用建议:
获取学时返回的是字典,无论是哪种记录表,只要返回的字典格式和我的一样,就能使用我的代码了 验证一句话,有需求才有动力 学习了!这个应用挺好。 学习了!看起来不错 不错不错!楼主的行动力太强了{:301_975:}我也想给我的公众号搞一个 这样查方便 不错学习了 emm,微信有对外的api的,直接把微信回复接入过来,用py开个flask不是更适合吗 验证一句话,有需求才有动力
学习了~很有帮助
页:
[1]
2