def initWebdrive(self): self.loginFlag = False self.initUrl = 'https://passport.tujia.com/PortalSite/LoginPage/' # todo =========写死的谷歌浏览器配置,后续应做成配置化============ chrome_options = Options() # chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 去除浏览器自动测试软件的提示 chrome_options.add_experimental_option("excludeSwitches", ['enable-automation']) chrome_options.add_argument(cf.get("workShop", "userAgent")) if cf.get("workShop", "executablePath"): self.driver = webdriver.Chrome(options=chrome_options, executable_path=cf.get( "workShop", "executablePath")) else: self.driver = webdriver.Chrome(options=chrome_options) # 简单地避免反爬虫对navigator的检验 script = ''' Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) ''' self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": script}) if logging.root.isEnabledFor(logging.DEBUG): logging.debug('worker(%s) 谷歌浏览器初始化完成!' % self.workerNo)
def doLogin(self, waitElemet): try: waitElemet.send_keys(decrypt(cf.get('worker', 'yajubao.userName'))) self.driver.find_element_by_xpath('//input[@type="password"]') \ .send_keys(decrypt(cf.get('worker', 'yajubao.pwd'))) self.driver.find_element_by_xpath( '//*[@id="app"]/div/div/div/div[2]/div[1]/div[2]/div[1]/form/button' ).click() self.loginFlag = True # self.writeLog(self.report.reportNo, '登录成功') except NoSuchElementException as ex: self.logErrorMess(ex, 'doLogin function') return False except Exception as e: self.logErrorMess(e, 'doLogin function') return False return True
def doTask(self, itemQueue): """ 工作台方法(消费者),工作者从此处获得操作单来进行work操作 :param itemQueue: 操作单队列 :return: None """ while 1: if itemQueue.empty(): time.sleep(int(cf.get('workShop', 'worker_work_freq'))) self.work(itemQueue.get()) # 若队列中有待处理的单则取出处理
def work(self, excel_data): if logging.root.isEnabledFor(logging.DEBUG): logging.debug(f"workItem[%s] is on process" % excel_data) itemNo = excel_data[0] channelNo = excel_data[1] report = Report(itemNo, channelNo) userId = excel_data[2] userName = excel_data[3] tel = excel_data[4] sex = excel_data[5] desc = excel_data[6] customer = Customer(userId, tel, userName, sex) customer.setDesc(desc) projectId = excel_data[7] projectName = excel_data[8] project = BuildingProject(projectId, projectName) report.setCustomer(customer) report.setProject(project) # 根据渠道ID来获取配置中指定的员工编号 workerNo = cf.get('api', channelNo) if workerNo is None: logging.debug("channel(%s) map any worker!" % channelNo) bean = beanBuilder.getBeanByWorkerNo(workerNo) if bean is None: logging.debug("worker(%s) 没有配置对应的SOP操作!" % workerNo) # todo 这里需要把调用的worker改成单例模式,不需要每次都进行实例化,使用时只需要每次初始化worker的参数即可 workerModuleObj = importlib.import_module('.' + bean.moduleName, bean.modulePackage) workerObj = getattr(workerModuleObj, bean.moduleName) worker = workerObj() worker.setReport(report) robot = BasicRobot(worker) if logging.root.isEnabledFor(logging.DEBUG): logging.debug("worker({0}) is process the report({1})".format( robot.getWorkerNo(), itemNo)) try: robot.doJob() worker.handleCvs(itemNo, '操作完成') except Exception as e: logging.error("worker({0}) handle report({1}) failed".format( robot.getWorkerNo(), itemNo)) logging.error("error mess:%s" % traceback.format_exc()) worker.handleCvs(itemNo, 'failed')
def doLogin(self, element): try: # super().doLogin() # 进入登录页 # slideblock = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath('//*[@id="nc_1_n1z"]')) # 鼠标点击滑动块不松开 ActionChains(self.driver).click_and_hold(element).perform() # 将圆球滑至相对起点位置的 右边xx ActionChains(self.driver).move_by_offset(xoffset=50, yoffset=0).perform() time.sleep(0.1) ActionChains(self.driver).move_by_offset(xoffset=260, yoffset=0).perform() time.sleep(0.2) # 放开滑动块 ActionChains(self.driver).release(element).perform() time.sleep(0.3) self.driver.find_element_by_xpath( '//*[@id="app"]/section/section[1]/section[3]/section[1]/div[2]/div[1]/div[1]/input' ).send_keys(decrypt(cf.get('worker', 'tj.userName'))) self.driver.find_element_by_xpath( '//*[@id="app"]/section/section[1]/section[3]/section[1]/div[2]/div[1]/div[2]/input' ).send_keys(decrypt(cf.get('worker', 'tj.pwd'))) self.driver.find_element_by_xpath( '//*[@id="app"]/section/section[1]/section[3]/section[1]/div[2]/button' ).click() self.loginFlag = True self.writeLog(self.workerNo, '登录成功') except NoSuchElementException as ex: self.logErrorMess(ex, 'doLogin function') return False except Exception as e: self.logErrorMess(e, 'doLogin function') return False return True
def writeLog(self, itemNo, execLog, logLevel='debug'): if logging.root.isEnabledFor(logging.DEBUG): logging.debug( "logLevel({0}) - itemNo({1}) execute mess:{2}".format( logLevel, itemNo, execLog)) # 是否配置将日志写入文件 if cf.get("worker", "isSaveExecLog") \ or logLevel == 'error': out = open(project_path + '/export/executeLog.csv', 'a', newline='', encoding='utf-8') # 设定写入模式 csv_write = csv.writer(out) # 写入具体内容 csv_write.writerow([ itemNo, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), execLog ]) out.close()
def controller(self, itemQueue): """ 监工方法(生产者),负责获得操作单并放入操作单队列 :param itemQueue: 操作单队列 :return: None """ while 1: if itemQueue.empty(): if logging.root.isEnabledFor(logging.DEBUG): logging.debug(f"读取文件获取执行任务") # todo 这里取操作单的操作应从数据库中获取 with open('export/customer.csv', 'r', encoding='utf-8') as csvfile: csv_reader = csv.reader(csvfile) for excel_data in csv_reader: if len(excel_data) <= 0: continue itemNo = excel_data[0] if self.isDoneItem(itemNo): # 判断该单据是否处理过 continue self.addDoneItem( itemNo) # 将需要处理的单号置为已处理 #todo 这里需要考虑操作失败时的策略 itemQueue.put(excel_data) # 将需要处理的单号丢进队列里 time.sleep(int(cf.get('workShop', 'controller_work_freq')))