Files
2025-11-20 11:30:32 +08:00

597 lines
24 KiB
Python

from tkinter import N, NO
from DrissionPage._base.chromium import Chromium
from DrissionPage._configs.chromium_options import ChromiumOptions
from DrissionPage._pages.mix_tab import MixTab
from applog import logger
import time
import datetime
class Sinopec_ewcc(object):
tab:MixTab
# browser:Chromium
def __init__(self):
self.url = 'https://ewcc.sinopec.com'
self.url_info= 'ewcc.sinopec'
self.browser_path= r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
self.co = ChromiumOptions().set_browser_path(self.browser_path)
# self.co.headless(True)
self.co.ignore_certificate_errors(True)
self.browser=Chromium(self.co)
self.tab=self.browser.latest_tab
#判断对应的任务是否完成
self.export_date=datetime.date.today()
self.is_query_member=False
self.is_query_oil_fw_tj=False
self.is_query_oil_current_month_lj=False
self.is_query_client_emp_tj=False
def reset(self):
# 关闭当前浏览器
self.browser.quit()
self.browser=Chromium(self.co)
self.tab=self.browser.latest_tab
def quit(self):
self.browser.quit()
logger.info(f"浏览器已退出")
def init_cookies(self, cookies):
"""设置传入的cookies到浏览器
Args:
cookies: 要设置的cookies(可以是列表、字典或JSON字符串)
Returns:
bool: 设置成功返回True,失败返回False
"""
logger.info('使用传入的cookies登录')
# 处理字符串类型的cookies
if isinstance(cookies, str):
try:
import json
# 尝试将字符串解析为JSON对象
parsed_cookies = json.loads(cookies)
logger.info(f"成功将字符串cookies解析为JSON对象,共 {len(parsed_cookies)} 条")
# 递归调用,使用解析后的数据
return self.init_cookies(parsed_cookies)
except json.JSONDecodeError as e:
logger.error('字符串cookies解析失败: {str(e)}')
return False
# 处理字典类型的cookies
elif isinstance(cookies, dict):
try:
self.browser.set.cookies(cookies)
logger.info('成功设置字典类型的cookies')
return True
except Exception as e:
logger.info(f'设置字典类型的cookies失败: {str(e)}')
return False
# 处理列表类型的cookies
elif isinstance(cookies, list):
try:
for cookie in cookies:
self.browser.set.cookies(cookie)
logger.info('成功设置列表类型的cookies')
return True
except Exception as e:
logger.info(f'设置列表类型的cookies失败: {str(e)}')
return False
# 处理未知类型
else:
logger.info(f'传入的cookies格式不正确,类型为: {type(cookies)},应为列表、字典或JSON字符串')
return False
def save_cookies(self):
"""获取并返回当前浏览器tab的cookies
Returns:
list: 当前浏览器tab的cookies列表
"""
# 保存当前 cookie
self.tab.refresh()
cookies = self.tab.cookies()
return cookies
def open_web(self,url=None):
if url is None:
url=self.url
self.browser.get_tab(url)
def new_tab(self,url=None):
if url is None:
url=self.url
self.tab=self.browser.new_tab(url)
def find_tab(self,url=None,title=None):
find_tab=None
if url is None:
url=self.url
if title is None:
title=self.url_info
try:
find_tab = self.browser.get_tab(url=url)
logger.info(f"根据 {url} 找到标签")
except:
logger.error(f"根据 {url} 没有找到标签")
if not find_tab:
try:
find_tab=self.browser.get_tab(title=title)
logger.info(f"根据 标题名{title} 找到 标签")
except :
logger.exception(f"根据 标题名: {title} 没有找到标签")
find_tab=None
return find_tab
def is_login(self):
logger.info(f"判断是否登录")
try:
e=self.tab.ele("#userName")
if e:
logger.info(f"找到登录成功的标志: {e.text}")
cur_login=True
else:
logger.info('没有找到登录成功的标志')
cur_login=False
except Exception as e:
cur_login = False
return cur_login
def login(self,username=None,userpass=None,otp=None):
self.browser.set.cookies.clear
self.tab.get(self.url)
self.tab.wait.eles_loaded('xpath://*[@id="authen1Form"]/button')
time.sleep(5)
try:
ele_div=self.tab.ele('#tab3Con')
ele_div.ele('#fs3_username').set.value(username)
time.sleep(1)
ele_div.ele('#fs3_password').set.value(userpass)
time.sleep(1)
ele_div.ele('#fs3_otpOrSms').set.value(otp)
time.sleep(1)
ele_div.ele('@type=submit').click()
except Exception as e:
logger.info(f'登录表单填写异常: {e}')
time.sleep(3)
### 判断是否有仍然发生的界面
try:
ele_process=None
ele_process = self.tab.ele('#proceed-button')
time.sleep(2)
if ele_process:
ele_process.click(by_js=True)
logger.info("继续发送按钮存在并已点击")
except Exception as e:
logger.error(f'继续发送按钮处理异常: {e}')
time.sleep(3)
return True
def Autologin(self,username=None,userpass=None,otp=None,cookies=None):
# 2 如果没有登录 ,则使用cookie登录
if not self.is_login():
logger.info('使用cookies尝试登录')
self.browser.set.cookies.clear
self.init_cookies(cookies)
self.tab.get(self.url)
self.tab.refresh()
time.sleep(3)
### 判断是否有仍然发生的界面
try:
ele_process=None
ele_process = self.tab.ele('#proceed-button')
if ele_process:
time.sleep(5)
ele_process.click(by_js=True)
logger.info({"ele_process":ele_process})
logger.info("继续发送按钮存在并已点击")
except Exception as e:
logger.info(f'继续发送按钮处理异常: {e}')
# 3 判断是否登录,如果登录不成功,则使用帐号和密码登录
if not self.is_login():
logger.info('<2> 使用帐号密码登录')
# 这里显示登录界面,并等待输入一分钟
self.login(username=username,userpass=userpass,otp=otp)
# 4 判断是否登录 ,如果失败,则发送信息到微信上
if self.is_login():
self.tab.refresh()
self.save_cookies()
logger.info(" 保存cookies")
return True
else:
self.send_message()
return False
def send_message(self):
pass
def today_is_export_date(self):
cur_date=datetime.date.today()
if self.export_date!=cur_date:
self.export_date=cur_date
self.is_query_client_emp_tj=False
self.is_query_oil_fw_tj=False
self.is_query_member=False
self.is_query_oil_current_month_lj=False
def query_car_info(self, plate_number=None, phone_number=None, result_list=None):
"""查询车辆信息
Args:
plate_number: 车牌号
phone_number: 手机号
result_list: 用于存储查询结果的列表(通过参数返回)
Returns:
bool: 查询是否成功,成功返回True,失败返回False
"""
# 参数校验
if not plate_number and not phone_number:
logger.warning("车牌号和手机号至少需要提供一个")
return False
# 初始化结果列表
if result_list is None:
result_list = []
logger.info(f"查询车牌号: {plate_number} 电话:{phone_number}")
try:
# 切换到订单中心
self.tab.ele("@@tag()=li@@title=订单中心").click()
time.sleep(2) # 可以考虑替换为条件等待
# 点击客户信息查询
self.tab.ele("@@tag()=a@@name=客户信息查询").click()
time.sleep(2) # 可以考虑替换为条件等待
# 获取iframe
myframe = self.tab.get_frame("iframeSOC_CSR_DETAIL")
time.sleep(2) # 可以考虑替换为条件等待
# 根据输入参数选择查询类型
search_type_ele = myframe.ele("@@tag()=select@@id=searchType")
search_value_ele = myframe.ele('#searchValue')
if plate_number:
search_type_ele.select.by_text("车牌号")
search_value_ele.input(plate_number, clear=True)
elif phone_number:
search_type_ele.select.by_text("手机号")
search_value_ele.input(phone_number, clear=True)
# 执行查询
myframe.listen.start('acc/getAccCsrInfo')
myframe.ele("@text()=查询").click()
try:
DataPacket = myframe.listen.wait(timeout=10) # 添加超时参数
except Exception as e:
logger.error(f"等待查询响应超时: {str(e)}")
return False
finally:
myframe.listen.stop()
if DataPacket and hasattr(DataPacket, 'response') and hasattr(DataPacket.response, 'body'):
if DataPacket.response.body.get('success'):
total_num = DataPacket.response.body['data'].get('total', 0)
logger.info(f"查询到 {total_num} 条记录")
# 获取详情
detail_eles = myframe.eles("@@name=客户信息详情界面@@text()=详情")
for ele in detail_eles:
# 执行详情点击操作并获取数据
self.tab.listen.start('getAccCsrInfoByCsrid')
ele.click(by_js=True)
try:
detail_packet = self.tab.listen.wait(timeout=10)
if detail_packet and hasattr(detail_packet, 'response') and hasattr(detail_packet.response, 'body'):
if detail_packet.response.body.get('success'):
result_list.append(detail_packet.response.body['data'])
except Exception as e:
logger.error(f"获取详情失败: {str(e)}")
finally:
self.tab.listen.stop()
return True
except Exception as e:
logger.error(f"查询车辆信息时发生异常: {str(e)}")
return False
def reopen_browse(self):
self.tab.get(self.url)
self.tab.refresh()
logger.info("重新打开浏览器")
time.sleep(2) # 可以考虑替换为条件等待
def query_memeber(self):
try:
# 切换到积分中心
self.tab.ele("@@tag()=li@@title=积分中心").click()
logger.info("点击积分中心")
topele=self.tab.ele("#childMenu")
aele=topele.ele("@@tag()=li@@onclick:综合管理")
aele.click(by_js=True)
logger.info("点击综合管理")
#time.sleep(2) # 可以考虑替换为条件等待
# 点击客户信息查询
self.tab.ele("@@tag()=a@@name=员工拉新权益会员明细").click()
logger.info("点击客户拉新权益会员明细")
time.sleep(2) # 可以考虑替换为条件等待
# 获取iframe
myframe = self.tab.get_frame("iframeemp_rec_sw")
time.sleep(2) # 可以考虑替换为条件等待
# 根据输入参数选择查询类型
search_type_ele = myframe.eles("@@tag()=input@@type=text")
#取得开始日期,并获得焦点
ele=search_type_ele[1]
# logger.info(f"元素信息:{ele}")
ele.focus()
#查找 弹出的日期窗体
data_ele=myframe.ele("@@tag()=div@@class=el-picker-panel__body-wrapper")
ele_date_head=data_ele.ele("@@tag()=div@@class=el-picker-panel__header")
ele_date_content=data_ele.ele("@@tag()=div@@class=el-picker-panel__content")
# logger.info(f"日期元素信息:{ele_date_head}")
# logger.info(f"日期元素信息:{ele_date_content}")
ele_date_day=ele_date_content.eles("@@tag()=td")
for a in ele_date_day:
day=a.text
if day.isdigit() and int(day)==1:
a.click(by_js=True)
ele=myframe.eles("@@tag()=div@@class=el-form-item__content")
ele[1].click(by_js=True)
# logger.info(f"myframe元素信息 :{ele[1]}")
#logger.info(f"日期选择器元素信息:{ele[0]}")
time.sleep(5) # 可以考虑替换为条件等待
search_type_ele = myframe.ele("@@tag()=span@@text():导出")
if search_type_ele:
self.tab.listen.start('exportUcRcodeSw')
search_type_ele.click(by_js=True)
export_packet = self.tab.listen.wait(timeout=10)
if export_packet and hasattr(export_packet, 'response') and hasattr(export_packet.response, 'body'):
if export_packet.response.body.get('success'):
logger.info("成功导出 员工拉新权益会员明细 ")
time.sleep(3) # 等待后台数据导出
#logger.info(export_packet.request.postData)
self.tab.listen.stop()
logger.info("导出客户评价与员工关联统计查询完成")
return True
logger.info("客户评价与员工关联统计查询完成")
except Exception as e:
logger.exception(f"员工拉新权益会员明细查询异常: {str(e)}")
return False
def query_oil_fw_tj(self):
try:
self.reopen_browse()
# 切换到积分中心
self.tab.ele("@@tag()=li@@title=评价中心").click()
logger.info("点击评价中心")
topele=self.tab.ele("#childMenu")
aele=topele.ele("@@tag()=li@@onclick:综合管理")
aele.click(by_js=True)
logger.info("点击综合管理")
#time.sleep(2) # 可以考虑替换为条件等待
# 点击客户信息查询
self.tab.ele("@@tag()=a@@name=油站服务号应用统计").click()
logger.info("点击 油站服务号应用统计")
time.sleep(2) # 可以考虑替换为条件等待
# 获取iframe
myframe = self.tab.get_frame("iframeservice_no_apply_static")
# 根据输入参数选择查询类型
search_type_ele = myframe.eles("@@tag()=input@@type=text")
# for a in search_type_ele:
# logger.info(f"元素信息:{a.html}")
#a.focus()
#time.sleep(2) # 可以考虑替换为条件等待
#按油站汇总
ele=search_type_ele[2]
elep=ele.next()
#elep.focus()
elep.click()
logger.info("选择 按油站汇总")
ele=myframe.ele("@@tag()=li@@text():按油站汇总")
ele.click()
time.sleep(2) # 可以考虑替换为条件等待
#取得开始日期,并获得焦点
ele=search_type_ele[3]
# logger.info(f"元素信息:{ele}")
ele.focus()
#查找 弹出的日期窗体
data_ele=myframe.ele("@@tag()=div@@class=el-picker-panel__body-wrapper")
ele_date_head=data_ele.ele("@@tag()=div@@class=el-picker-panel__header")
ele_date_content=data_ele.ele("@@tag()=div@@class=el-picker-panel__content")
# logger.info(f"日期元素信息:{ele_date_head}")
# logger.info(f"日期元素信息:{ele_date_content}")
ele_date_day=ele_date_content.eles("@@tag()=td")
for a in ele_date_day:
day=a.text
if day.isdigit() and int(day)==1:
a.click(by_js=True)
ele=myframe.eles("@@tag()=div@@class=el-form-item__content")
ele[1].click(by_js=True)
# logger.info(f"myframe元素信息 :{ele[1]}")
#logger.info(f"日期选择器元素信息:{ele[0]}")
time.sleep(5) # 可以考虑替换为条件等待
search_type_ele = myframe.ele("@@tag()=span@@text():导出")
if search_type_ele:
self.tab.listen.start('getExportTask')
search_type_ele.click(by_js=True)
export_packet = self.tab.listen.wait(timeout=10)
if export_packet and hasattr(export_packet, 'response') and hasattr(export_packet.response, 'body'):
if export_packet.response.body.get('success'):
logger.info("成功导出 油站服务号应用统计 ")
time.sleep(3) # 等待后台数据导出
#logger.info(export_packet.request.postData)
self.tab.listen.stop()
return True
except Exception as e:
logger.exception(f"评价中心 员工拉新权益会员明细查询异常: {str(e)}")
return False
def query_oil_current_month_lj(self):
try:
self.reopen_browse()
# 切换到积分中心
self.tab.ele("@@tag()=li@@title=评价中心").click()
logger.info("点击评价中心")
topele=self.tab.ele("#childMenu")
aele=topele.ele("@@tag()=li@@onclick:统一客户服务评价")
aele.click(by_js=True)
logger.info("统一客户服务评价")
#time.sleep(2) # 可以考虑替换为条件等待
# 点击客户信息查询
self.tab.ele("@@tag()=a@@name=按油站汇总本月累计").click()
logger.info("点击 油站汇总本月累计")
time.sleep(3) # 可以考虑替换为条件等待
# 获取iframe
myframe = self.tab.get_frame("iframestation_refueling_total")
logger.info(f"iframe元素信息:{myframe}")
time.sleep(2) # 可以考虑替换为条件等待
search_type_ele = myframe.ele("@@tag()=span@@text():查询")
search_type_ele.click(by_js=True)
logger.info("点击 查询")
time.sleep(5) # 可以考虑替换为条件等待
search_type_ele = myframe.ele("@@tag()=span@@text():导出")
if search_type_ele:
self.tab.listen.start('getExportTask')
search_type_ele.click(by_js=True)
export_packet = self.tab.listen.wait(timeout=10)
logger.info(f"导出包信息:{export_packet}")
if export_packet and hasattr(export_packet, 'response') and hasattr(export_packet.response, 'body'):
if export_packet.response.body.get('success'):
logger.info("成功导出 油站汇总本月累计 ")
time.sleep(3) # 等待后台数据导出
#logger.info(export_packet.request.postData)
self.tab.listen.stop()
return True
except Exception as e:
logger.exception(f"评价中心 油站汇总本月累计查询异常: {str(e)}")
return False
def query_client_emp_tj(self):
try:
self.reopen_browse()
# 切换到积分中心
self.tab.ele("@@tag()=li@@title=评价中心").click()
logger.info("点击评价中心")
topele=self.tab.ele("#childMenu")
aele=topele.ele("@@tag()=li@@onclick:统一客户服务评价")
aele.click(by_js=True)
logger.info("点击 统一客户服务评价")
# 点击客户信息查询
self.tab.ele("@@tag()=a@@name=客户评价与员工关联统计").click()
logger.info("点击 客户评价与员工关联统计")
time.sleep(2) # 可以考虑替换为条件等待
# 获取iframe
myframe = self.tab.get_frame("iframereview_relate_emple_static")
time.sleep(2) # 可以考虑替换为条件等待
# 根据输入参数选择查询类型
search_type_ele = myframe.eles("@@tag()=input@@type=text")
# for a in search_type_ele:
# logger.info(f"元素信息:{a}")
#按油站汇总
ele=search_type_ele[1]
elep=ele.next()
#elep.focus()
elep.click()
logger.info("选择 按油站汇总")
ele=myframe.ele("@@tag()=li@@text():按油站汇总")
ele.click()
time.sleep(2) # 可以考虑替换为条件等待
#取得开始日期,并获得焦点
ele=search_type_ele[2]
# logger.info(f"元素信息:{ele}")
ele.focus()
#查找 弹出的日期窗体
data_ele=myframe.ele("@@tag()=div@@class=el-picker-panel__body-wrapper")
ele_date_head=data_ele.ele("@@tag()=div@@class=el-picker-panel__header")
ele_date_content=data_ele.ele("@@tag()=div@@class=el-picker-panel__content")
# logger.info(f"日期元素信息:{ele_date_head}")
# logger.info(f"日期元素信息:{ele_date_content}")
ele_date_day=ele_date_content.eles("@@tag()=td")
for a in ele_date_day:
day=a.text
if day.isdigit() and int(day)==1:
a.click(by_js=True)
ele=myframe.eles("@@tag()=div@@class=el-form-item__content")
ele[1].click(by_js=True)
logger.info(f"myframe元素信息 :{ele[1]}")
#logger.info(f"日期选择器元素信息:{ele[0]}")
time.sleep(5) # 可以考虑替换为条件等待
search_type_ele = myframe.ele("@@tag()=span@@text():导出")
if search_type_ele:
self.tab.listen.start('getExportTask')
search_type_ele.click(by_js=True)
export_packet = self.tab.listen.wait(timeout=10)
if export_packet and hasattr(export_packet, 'response') and hasattr(export_packet.response, 'body'):
if export_packet.response.body.get('success'):
logger.info("成功导出 客户评价与员工关联统计 ")
time.sleep(3) # 等待后台数据导出
#logger.info(export_packet.request.postData)
self.tab.listen.stop()
return True
except Exception as e:
logger.exception(f"评价中心 客户评价与员工关联统计查询异常: {str(e)}")
return False