需要解决的问题:
单位有个内部管理系统,系统有个电话任务模块,由于我部门服务量较大,当客户有问题需要解决的时候,会有专门人员将客户反应的问题记录到电话任务中,每个电话任务会分配到某个小组,每个电话任务有到期时间(一般是15分钟),如果任务到期没有进行回电会扣绩效(一次10块钱)。
例如2018-10-23 14:10:10登记到我组一个电话任务,超期时间是15分钟,即2018-10-23 14:25:10之前没有回电就会扣钱。但有时候在午休时间会登一个电话任务,然而这时候可能并不会注意到有一个电话任务进来,当到正常上班时间时发现已经晚了,没有在规定时间内进行回电,从而扣了冤枉钱。
思路:
每个任务都有任务ID、到期时间、问题、客户姓名及联系电话等等信息,如下:
可以通过抓包方式,解析网络数据包的url、headers和data,从而使用发送封包的方式模拟手动查询任务、手动回电处理等人工操作。达到我们的目的。模拟人工操作的步骤如下:
- 模拟用户登录
- 登录成功后模拟查询请求的电话任务(电话任务三种状态:请求、处理、结束)
- 将查询到的请求状态的快要超期的电话任务数据集逐个进行自动回电操作
- 将每个自动进行回电操作的任务记录下来并以邮件的方式通知自己
代码:
import requests
from selenium import webdriver
import re
import datetime
import json
import smtplib
from email.mime.text import MIMEText
import time
import os
def send_mail(subject,body):
try:
"""发送邮件"""
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = "example@qq.com"
msg["To"] = "example@qq.com"
s = smtplib.SMTP_SSL("smtp.qq.com", 465)
s.login("example@qq.com","code")#这里的第二个参数为qq邮箱授权码,不要填你的密码
s.sendmail("example@qq.com",["example@qq.com",],msg.as_string())
s.quit()
print("邮件发送成功!")
except Exception as e:
print("邮件发送失败~~"+e.message)
def login_form(url_login,url_login_data,url_login_headers,url_login_cookies):
#请求url
url_login = 'http://www.example.com/ashx/login.ashx?name=name&pwd=pwd'
url_index = 'http://www.example.com/Index.aspx'
#请求标头
url_login_headers = {
'Accept' : 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding' : 'gzip, deflate',
'Accept-Language' : 'zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3',
'Connection' : 'Keep-Alive',
#'Cookie' : 'ASP.NET_SessionId=bwxr35fqkrdh1p2u04dv4jbp',
'Host' : 'rjbm.hyjtkj.com',
'Referer' : 'http://www.example.com/Login.aspx',
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'X-Requested-With' : 'XMLHttpRequest'
}
url_login_cookies = {}
for line in 'ASP.NET_SessionId=bwxr35fqkrdh1p2u04dv4jbp'.split(';'):
key,value = line.split('=',1)
#请求正文
url_login_data = {}
#使用python的requests
url_login_res = requests.get(url_login,data=url_login_data,headers=url_login_headers,cookies=url_login_cookies)
print(url_login_res.text)
return url_login_res.text
def search_phone_task(url_phone_task_ashx,url_phone_task_ashx_headers,url_phone_task_ashx_data):
'''
url_phone_task = 'http://www.example.com/Gzjl/JxzGzjl.aspx?id=3&search=17-%u4e8c%u90e8%u897f%u5357%u7247%u533a%u8f6f%u4ef6-%u738b'
url_phone_task_headers = {
'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding' : 'gzip, deflate',
'Accept-Language' : 'zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3',
'Connection' : 'Keep-Alive',
'Cookie' : 'ASP.NET_SessionId=idumzkql4ckqpy5bbj1uu3mt; gsid=01; xzname=%e4%ba%8c%e9%83%a8%e8%a5%bf%e5%8d%97%e7%89%87%e5%8c%ba%e8%bd%af%e4%bb%b6-%e7%8e%8b; img=IMG_1659.PNG; u_bmjg=41; username=%E5%BC%A0%E4%B8%89; u_groupname=%e8%bd%af%e4%bb%b6%e7%bb%b4%e6%8a%a4; groupid=3; xzid=17; jb=17; usergh=H1078; userid=99',
'Host' : 'rjbm.hyjtkj.com',
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'Upgrade-Insecure-Requests': '1'
}
url_phone_task_data = {
'id' : '3',
'search' : '17-%u4e8c%u90e8%u897f%u5357%u7247%u533a%u8f6f%u4ef6-%u738b'
}
url_phone_task_res = requests.get(url_phone_task,data=url_phone_task_data,headers=url_phone_task_headers)
print(url_phone_task_res.text)
#1.先获取 table>tr>td['Jjzt'].content(datetime)
#2.再获取 datetime.now
#3.判断每个tr的截止时间与现在时间,将要超时的任务 模拟右键回电
#4.自动回电完毕后右键通知自己/组长 -->> 自动开始回电 任务...
#5.如果自动回电开始后10分钟内没有结束回电并右键通知自己/组长 -->>自动结束回电
content = url_phone_task_res.text
pattern = re.compile('<td field="Jjzt"><div class="datagrid-cell " style="width:(.*)px;text-align:center;height:auto;">(.*)</div></td>',re.S)
results = pattern.findall(content);
print(results)
time_now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(time_now)
time_space = (datetime.datetime.now()+datetime.timedelta(minutes=-1)).strftime('%Y-%m-%d %H:%M:%S')
print(time_space)
test_time = '2018/10/22 13:07:38' #测试获取字符串转日期 累加日期
print(datetime.datetime.strptime(test_time, '%Y/%m/%d %H:%M:%S'))
print(datetime.datetime.strptime(test_time, '%Y/%m/%d %H:%M:%S')+datetime.timedelta(minutes=-1))
for item in results:
print(item)
'''
url_phone_task_ashx = 'http://www.example.com/Gzjl/Handler/GetGZJLInfo.ashx'
url_phone_task_ashx_headers = {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'X-Requested-With': 'XMLHttpRequest',
'Accept-Language': 'zh-Hans-CN,zh-Hans;q=0.7,ja;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'Content-Length': '129',
'Host': 'rjbm.hyjtkj.com',
'Connection': 'Keep-Alive',
'Pragma': 'no-cache',
'Cookie': 'ASP.NET_SessionId=d1jdntjbcn2pu4humm4smdsl; groupid=3; username=%E5%BC%A0%E4%B8%89; userid=99; xzid=17; u_bmjg=41; xzname=%e4%ba%8c%e9%83%a8%e8%a5%bf%e5%8d%97%e7%89%87%e5%8c%ba%e8%bd%af%e4%bb%b6-%e7%8e%8b; img=IMG_1659.PNG; usergh=H1078; gsid=01; jb=17; u_groupname=%e8%bd%af%e4%bb%b6%e7%bb%b4%e6%8a%a4'
}
url_phone_task_ashx_data = {
#'fwbm':'17-%E4%BA%8C%E9%83%A8%E8%A5%BF%E5%8D%97%E7%89%87%E5%8C%BA%E8%BD%AF%E4%BB%B6-%E7%8E%8B',
'fwbm':'17-二部西南片区软件-王',
#'Clzt':'%E8%AF%B7%E6%B1%82',
'Clzt':'请求',
'page':'1',
'rows':'20'#一页20条记录
}
print('请求任务url:'+url_phone_task_ashx)
print('请求任务header:')
print(url_phone_task_ashx_headers)
print('请求任务data:')
print(url_phone_task_ashx_data)
url_phone_task_ashx_res = requests.post(url_phone_task_ashx,url_phone_task_ashx_data)
print(url_phone_task_ashx_res.text)
test_json = '{"totalPage":1,"total":1,"pageIndex":1,"rows":[{"GZID":58621,"Clients_id":"冀020016","Jcz_id":"冀A00129","Ht_id":"","JCZMC":"测试-检测有限公司","contract_qk":"0","server_qk":"0","RWSM":"13582815233(武)检测程序打不开","DJTime":"2018/10/22 14:40:04","XZID":17,"Djr":"曹瑞英(工号:H0516)","Jjzt":"30","Lxr":"张胜青","Lxrphone":"13081051666","Fwbm":"17-二部西南片区软件-王","Clzt":"请求","Province":"河北省","AreaName":"石家庄市","YQHD_Date":"2018/10/22 15:10:04","IsChangeRw":0,"THSC":0,"KSHD_Time":null,"JSHD_Time":null,"HD_ManID":null,"HD_Man":null,"HD_BZ":null,"Imgs":"","djType":0,"IsSMS":0,"Openid":null,"Dhzjtype":0,"IsCq":0}]}'
#dict_json = json.loads(test_json)#解码测试json对象
dict_json = json.loads(url_phone_task_ashx_res.text)#解码响应json对象
print(dict_json)
print(type(dict_json))
return dict_json
def auto_replay_phone(task_id,ht_id,jcz_id,jczmc):
'''待处理 自动回电事件'''
'''
print('自动回电事件')
rows = dict_json.get('rows')
print(rows)
print(len(rows))
for row in rows:
print('任务ID:'+row['GZID'])
print('检测站:'+row['JCZMC'])
print('问题:'+row['RWSM'])
print('紧急状态时间:'+row['YQHD_Date'])#打印每个紧急状态时间
print('缓冲时间:'+(datetime.datetime.strptime(row['YQHD_Date'],'%Y/%m/%d %H:%M:%S')+datetime.timedelta(minutes=-1)).strftime('%Y/%m/%d %H:%M:%S'))#打印紧急状态时间前一分钟
print('现在的时间:'+datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'))#打印现在的时间
if (datetime.datetime.strptime(row['YQHD_Date'],'%Y/%m/%d %H:%M:%S')+datetime.timedelta(minutes=-1)) > (datetime.datetime.now()):
print('1 需要自动回电并邮件通知')#需要自动回电并邮件通知
sendMail('【自动回电处理-测试】','测试测试')
else:
print('0 还没有到自动回电的最后时间')#还没有到自动回电的最后时间
#sendMail('【自动回电处理-测试】','测试测试')
'''
#测试时间-开始
#测试时间-结束
#url = 'http://www.example.com/Gzjl/Gzhd.aspx?GZID='+str(task_id)#http://www.example.com/Gzjl/Handler/GZHD.ashx
url = 'http://www.example.com/Gzjl/Handler/GZHD.ashx'#http://www.example.com/Gzjl/Handler/GZHD.ashx
header = {
'Origin': 'http://www.example.com',
'Referer': 'http://www.example.com/Gzjl/Gzhd.aspx?GZID='+task_id,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': '*/*',
'X-Requested-With': 'XMLHttpRequest',
'Accept-Language': 'zh-Hans-CN,zh-Hans;q=0.7,ja;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'Content-Length': '217',
'Host': 'rjbm.hyjtkj.com',
'Connection': 'Keep-Alive',
'Pragma': 'no-cache',
'Cookie': 'ASP.NET_SessionId=o4e3i344yqf5m4qhvlkklopo; gsid=01; xzname=%e4%ba%8c%e9%83%a8%e8%a5%bf%e5%8d%97%e7%89%87%e5%8c%ba%e8%bd%af%e4%bb%b6-%e7%8e%8b; img=IMG_1659.PNG; u_bmjg=41; username=%E5%BC%A0%E4%B8%89; u_groupname=%e8%bd%af%e4%bb%b6%e7%bb%b4%e6%8a%a4; groupid=3; xzid=17; jb=17; usergh=H1078; userid=99'
#'Cookie': 'ASP.NET_SessionId=o4e3i344yqf5m4qhvlkklopo; gsid=01; xzname=%e4%ba%8c%e9%83%a8%e8%a5%bf%e5%8d%97%e7%89%87%e5%8c%ba%e8%bd%af%e4%bb%b6-%e7%8e%8b; username=%E5%BC%A0%E4%B8%89; u_groupname=%e8%bd%af%e4%bb%b6%e7%bb%b4%e6%8a%a4; groupid=3; xzid=17; jb=17; usergh=H1078; userid=99'
#username=%e7%8e%8b%e6%bb%a1%e7%94%9f
}
data = {
'type':'start',
'HD_BZ':'',
'htid':ht_id,
'jczid':jcz_id,
'jcztext':jczmc,
'GZID':task_id
}
print('自动回电事件url:'+url)
print('自动回电事件header:')
print(header)
print('自动回电事件data:')
print(data)
res = requests.get(url,data=data,headers=header)
#res = requests.get(url,data={},headers={})
return res.text
def write_cout_txt(filename):
w_num = 1
if os.path.exists(filename):
with open('./'+filename,'r',encoding='utf-8') as f:
w_num = int(f.read(-1)) + 1
with open('./'+filename,'w+',encoding='utf-8') as f:
f.write(str(w_num))
return w_num
else:
with open('./'+filename,'w+',encoding='utf-8') as f:#打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
f.write(str(w_num))
return w_num
if __name__ == "__main__":
print('程序进入main函数...')
login_res_txt = login_form('http://www.example.com/ashx/login.ashx?name=1078&pwd=m12321',{},{},{})
if '成功' in login_res_txt:
print('登录成功')
cout = 0
while True:
dict_json = search_phone_task('http://www.example.com/Gzjl/Handler/GetGZJLInfo.ashx',{},{})
rows = dict_json.get('rows')
print('打印请求的任务JSON列表 开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print(rows)
print('打印请求的任务JSON列表 完毕<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')
print('列表长度:'+str(len(rows)))
if len(rows)==0:
print('目前无请求任务!无需自动回电处理!')
else:
for row in rows:
print('打印请求的任务列表具体内容 开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
rwid = '任务ID:'+str(row['GZID'])
jcz = '检测站:'+row['JCZMC']
question = '问题:'+row['RWSM']
state = '紧急状态时间:'+row['YQHD_Date']
buffer = '缓冲时间:'+(datetime.datetime.strptime(row['YQHD_Date'],'%Y/%m/%d %H:%M:%S')+datetime.timedelta(minutes=-1)).strftime('%Y/%m/%d %H:%M:%S')
now = '现在的时间:'+datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
lxr = '联系人:'+row['Lxr']
dh = '电话:'+row['Lxrphone']
print(rwid)
print(jcz)
print(question)
print(state)#打印每个紧急状态时间
print(buffer)#打印紧急状态时间前一分钟
print(now)#打印现在的时间
print('打印请求的任务列表具体内容 开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
if (datetime.datetime.strptime(row['YQHD_Date'],'%Y/%m/%d %H:%M:%S')+datetime.timedelta(minutes=-1)) < (datetime.datetime.now()):
print('1-需要自动回电并邮件通知')#需要自动回电并邮件通知
res =auto_replay_phone(str(row['GZID']),str(row['Ht_id']),str(row['Jcz_id']),str(row['JCZMC']))#待处理------>>>>>已处理
print(res)
cout = write_cout_txt('num.txt')
send_mail('【自动回电处理任务ID-'+str(row['GZID'])+' 计数-'+str(cout)+'】',rwid+'\n'+jcz+'\n'+question+'\n'+state+'\n'+buffer+'\n'+now+'\n'+lxr+'\n'+dh)
else:
print('0-还没有到自动回电的最后时间')#还没有到自动回电的最后时间
#send_mail('【自动回电处理-测试】','测试测试')
cout = cout + 1
print('=============已查询'+str(cout)+'次==============')
time.sleep(10)
#测试时间-开始
#测试时间-结束
else:
print('登录失败')
效果:
笔记:
之前想要用selenium库模拟网页运行,然后通过ID或Class选择器或者正则表达式获取html标签的形式查询、处理请求的任务,但是后来发现可能行不通且没有必要,只要抓包时将关键操作的数据包解析出来就可以了(也就是ASPX中的一般处理程序包)。