import os import json import time from mytools.tools import load_json, save_json # 先读取缓存文件 while True: cache_dir = os.path.join(os.path.dirname(__file__), 'data') if not os.path.exists(cache_dir): os.mkdir(cache_dir) _cache_file = cache_dir + '/' + 'new_cart_tasks.json' cache_task_list = load_json(_cache_file, default={"task_list": []})["task_list"] task_infos = {'1': 'xxx', '2': 'xxx', '3': 'xxx', '4': 'xxx', '5': 'xxx'} task_id_str_list = [] for task_id_str in task_infos: if task_id_str not in cache_task_list: task_id_str_list.append(task_id_str) # 当task_id_str_list为空时,休眠2分钟,避免频繁请求任务接口 if len(task_id_str_list) == 0: print('任务列表为空,程序休眠30分钟...') time.sleep(30) else: print('成功获取到%d条待刷单的数据!' % len(task_id_str_list)) print('将创建%d个线程来分别执行刷单任务!' % len(task_id_str_list)) cache_dir = os.path.join(os.path.dirname(__file__), 'data') if not os.path.exists(cache_dir): os.mkdir(cache_dir)
def run(self): try: self.driver.get('http://www.aliexpress.com/') self.driver.execute_script( '''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''' ) self.driver.execute_script( '''() =>{ window.navigator.chrome = { runtime: {}, }; }''') self.driver.execute_script( '''() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }''' ) self.driver.execute_script( '''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''' ) #过滤弹窗 try: WebDriverWait(self.driver, 15).until( EC.element_to_be_clickable((By.CLASS_NAME, 'close-layer'))) self.driver.find_element_by_class_name('close-layer').click() except TimeoutException: pass WebDriverWait(self.driver, 40).until( EC.element_to_be_clickable( (By.XPATH, '//span[@class="register-btn"]/a'))) #点击登录 self.driver.find_element_by_xpath( '//span[@class="register-btn"]/a').click() # WebDriverWait(self.driver, 40).until( # EC.frame_to_be_available_and_switch_to_it # ) time.sleep(10) #切换到子iframe self.driver.switch_to.frame('alibaba-login-box') #输入登录信息 WebDriverWait(self.driver, 40).until( EC.element_to_be_clickable( (By.XPATH, '//input[@id="fm-login-id"]'))) time.sleep(random.uniform(4, 8)) self.driver.find_element_by_id('fm-login-id').send_keys( self.task_infos[str( self.task_id)]["account"]["login_aliexpress_email"]) time.sleep(random.uniform(4, 8)) self.driver.find_element_by_id('fm-login-password').send_keys( self.task_infos[str( self.task_id)]["account"]["login_aliexpress_password"]) time.sleep(random.uniform(4, 8)) # self.driver.find_element_by_id('fm-login-submit').click() js = 'document.getElementById("fm-login-submit").click();' self.driver.execute_script(js) time.sleep(1) # 此处判断登录过程中是否有滑块验证码,有则终止程序 if 'display: block' in self.driver.find_element_by_id( 'fm-login-checkcode-title').get_attribute('style'): logger.info('登录时发现滑块验证码,程序退出!') self.driver.quit() sys.exit(0) #弹窗处理 try: WebDriverWait(self.driver, 15).until( EC.element_to_be_clickable((By.CLASS_NAME, 'close-layer'))) self.driver.find_element_by_class_name('close-layer').click() except TimeoutException: pass if self.driver.current_url == 'https://www.aliexpress.com/': #插入账号登录日志 login_log_data = { 'data': { "account_id": self.task_infos[str( self.task_id)]["account"]["account_id"], "header": self.task_infos[str( self.task_id)]['account']['header'], "cookies": json.dumps(self.driver.get_cookies()), "login_status": "1", "note": "登录成功" } } self.insert_account_login_log(json.dumps(login_log_data)) #当账户成功登录时, 把登录的header和cookie修改对应账户表的字段 login_success_info_data = { 'data': { "account_id": self.task_infos[str( self.task_id)]["account"]["account_id"], "header": self.task_infos[str( self.task_id)]['account']['header'], "cookies": json.dumps(self.driver.get_cookies()) } } self.update_account_login_success_info( json.dumps(login_success_info_data)) elif 'passport.aliexpress.com' in self.driver.current_url: logger.info('登录后发现验证码,账户已被封!') #账户被封,也更新刷单状态 brushing_data = { str(self.task_id): { "task_id": self.task_id, "status": 10, } } self.update_brushing_status(json.dumps(brushing_data)) self.driver.quit() logger.info('程序退出!') sys.exit(0) #先检查cofirm_pay_file文件夹下,是否存在一个taskid_xx.txt文件,xx为本次任务id。 # 若存在,则进入个人订单中心,获取订单号和定价总价等信息,更新刷单状态。并删除该文件。 #若不存在,则正常走流程。 confirm_pay_dir = os.path.join(os.path.dirname(__file__), 'confirm_pay_files') confirm_pay_filename = confirm_pay_dir + '/' + 'taskid_' + str( self.task_id) + '.txt' if os.path.exists(confirm_pay_filename): logger.info( '发现任务id: %d之前已支付过,准备进入个人订单中心,确认订单支付状态,并进行相应的处理...' % self.task_id) ## 点击首页中的"My Orders",进入个人订单页面 WebDriverWait(self.driver, 40).until( EC.element_to_be_clickable( (By.XPATH, '//div[@id="user-benefits"]//ul/li[2]/a'))) self.driver.find_element_by_xpath( '//div[@id="user-benefits"]//ul/li[2]/a').click() time.sleep(5) #若未能获取指定元素,表明未成功下单! try: self.driver.find_element_by_xpath( '//*[@id="buyer-ordertable"]/tbody[1]/tr[2]/td[4]/button[1]' ) except NoSuchElementException: logger.info('[task_di: %s]未成功下单,删除缓存文件!' % self.task_id) os.remove(confirm_pay_filename) #订单支付成功 if self.driver.find_element_by_xpath( '//*[@id="buyer-ordertable"]/tbody[1]/tr[2]/td[4]/button[1]' ).text.strip() != 'Pay Now': self.do_after_place_order_success(confirm_pay_filename) # 订单支付失败,则读取缓存文件confirm_pay_files/taskid_xx.txt中的再支付次数; # 当再支付次数小于3次时,执行再支付流程;否则停止刷单,避免死循环。 elif self.driver.find_element_by_xpath( '//*[@id="buyer-ordertable"]/tbody[1]/tr[2]/td[4]/button[1]' ).text.strip() == 'Pay Now': confirm_pay_dir = os.path.join(os.path.dirname(__file__), 'confirm_pay_files') confirm_pay_filename = confirm_pay_dir + '/' + 'taskid_' + str( self.task_id) + '.txt' times = load_json(confirm_pay_filename, default={"times": 0})['times'] if times == 3: logger.info('再支付次数已达3次,终止刷单!') self.do_when_good_off_shelf() self.driver.quit() sys.exit(0) logger.info('确认订单未成功支付,正在尝试继续支付订单!') WebDriverWait(driver=self.driver, timeout=40).until( EC.element_to_be_clickable(( By.XPATH, '//*[@id="buyer-ordertable"]/tbody[1]/tr[2]/td[4]/button[1]' ))) # 点击Pay Now self.driver.find_element_by_xpath( '//*[@id="buyer-ordertable"]/tbody[1]/tr[2]/td[4]/button[1]' ).click() #再次支付流程,页面布局与首次支付不一致 self.fill_in_payment_information2() time.sleep(3) WebDriverWait(driver=self.driver, timeout=30).until( EC.element_to_be_clickable( (By.XPATH, '//div[@class="checkout-button"]/button[1]'))) self.driver.find_element_by_xpath( '//div[@class="checkout-button"]/button[1]').click() logger.info('点击了确认支付的按钮!') # 由于之前已支付过,但未成功,存在一个confirm_pay_files/taskid_xx.txt文件,且文件内容为空; # 读取文件内容,若为空,则写入再支付次数;若不为空,则更新支付次数, 格式:{“times”: 1} confirm_pay_dir = os.path.join(os.path.dirname(__file__), 'confirm_pay_files') confirm_pay_filename = confirm_pay_dir + '/' + 'taskid_' + str( self.task_id) + '.txt' times = load_json(confirm_pay_filename, default={"times": 0})['times'] times += 1 save_json(confirm_pay_filename, json_data={"times": times}) # WebDriverWait(driver=self.driver, timeout=30).until( # EC.element_to_be_clickable((By.XPATH, '//*[@id="header"]/div/div[2]/div[1]/a')) # ) time.sleep(20) if 'payOnlineSuccess' in self.driver.current_url or 'Thank you for your payment' in self.driver.page_source: self.driver.save_screenshot('PaySuccess.png') # self.driver.back() time.sleep(2) self.driver.execute_script( 'window.scrollTo(document.body.scrollWidth,0 );') WebDriverWait(driver=self.driver, timeout=30).until( EC.presence_of_element_located( (By.XPATH, '//div[@id="nav-user-account"]/div[1]'))) element = self.driver.find_element_by_xpath( '//div[@id="nav-user-account"]/div[1]') # print(element) actions = ActionChains(self.driver) actions.move_to_element(element) actions.perform() time.sleep(1) WebDriverWait(self.driver, 40).until( EC.element_to_be_clickable( (By.XPATH, '//ul[@class="flyout-quick-entry"]/li[2]/a'))) self.driver.find_element_by_xpath( '//ul[@class="flyout-quick-entry"]/li[2]/a').click( ) time.sleep(4) self.do_after_place_order_success(confirm_pay_filename) elif 'payOnlineFailure' in self.driver.current_url: self.driver.save_screenshot('PayFailed.png') self.do_after_place_order_failed(confirm_pay_filename) else: WebDriverWait(self.driver, 40).until( EC.element_to_be_clickable((By.ID, "search-key"))) self.driver.find_element_by_id('search-key').send_keys( self.task_infos[str(self.task_id)]["asin"]["keywords"]) time.sleep(random.uniform(0.5, 1.5)) self.driver.find_element_by_class_name( 'search-button').send_keys(Keys.ENTER) for i in range(1, 2): #弹窗处理 try: WebDriverWait(self.driver, 15).until( EC.element_to_be_clickable( (By.CLASS_NAME, 'close-layer'))) self.driver.find_element_by_class_name( 'close-layer').click() except TimeoutException: pass source = self.driver.page_source result = self.parse_list_page(source) if result: self.get_detail_page_to_add( self.target_good_detail_url) break # else: # try: # #此处处理列表搜索页少于3页的情况:只解析第一个列表搜索页,未找到目标商品时直接进行url拼接; # if len(self.driver.find_elements_by_xpath('//*[@id="pagination-bottom"]/div[1]/a')) > 2: # WebDriverWait(driver=self.driver, timeout=30).until( # EC.element_to_be_clickable((By.XPATH, '//span[@class="ui-pagination-active"]/following-sibling::a[1]')) # ) # self.driver.find_element_by_xpath('//span[@class="ui-pagination-active"]/following-sibling::a[1]').click() # logger.info('第%d列表搜索页没找到目标商品,正在跳转到第%d列表搜索页...'% (i,i+1)) # time.sleep(3) # except NoSuchElementException as e: # pass else: logger.info('搜索页中没有找到目标商品,正在拼接目标商品的详情url,进行特殊处理...') self.target_good_detail_url = 'https://www.aliexpress.com/item/-a/' + self.target_id + '.html' self.get_detail_page_to_add(self.target_good_detail_url) self.add_other_goods() self.delete_other_goods_from_cart() self.place_order() #最后关闭浏览器,结束程序 self.driver.quit() logger.info('当前账户操作完毕,关闭当前浏览器!') except (TimeoutException, WebDriverException, NoSuchElementException, NoSuchFrameException): # 在操作过程中等待超时,先退出当前登录状态,再重新执行run方法回调,重新走流程;也可直接结束程序,只适合在多线程的情况下操作。 logger.info('等待超时,或者元素位未完全加载导致定位出错!') logger.info('关闭当前浏览器,结束当前线程!') logger.info('系统会自动生成新的线程来执行下单任务!') self.driver.quit() sys.exit(0)