Пример #1
0
 def create_task_order_log(data):
     url = 'http://third.gets.com/api/index.php?sec=20171212getscn&act=aliexpressCreateTaskOrderLog'
     resp = requests.post(url, data)
     if resp.json()['status'] == 0:
         logger.info('新增刷单操作日志成功!')
     else:
         logger.info('新增刷单操作日志失败!')
Пример #2
0
 def update_brushing_status(data):
     # 测试机
     # url = 'http://testthird.gets.com:8383/api/index.php?sec=20171212getscn&act=aliexpressModifyTaskOrderStatus'
     # 线上
     url = 'http://third.gets.com/api/index.php?sec=20171212getscn&act=aliexpressModifyTaskOrderStatus'
     resp = requests.post(url=url, data=data)
     # print(resp.text)
     if resp.json()['msg'] == 'ok':
         logger.info('刷单状态更新成功!')
     else:
         logger.info('刷单状态更新失败!')
 def parse_list_page(self, html):
     parseHtml = etree.HTML(html)
     good_detail_urls = parseHtml.xpath(
         '//ul[@id="hs-below-list-items"]/li/div[1]/div[1]/div/a/@href')
     #绑定当前页的所有商品详情链接
     self.good_detail_urls = good_detail_urls
     for detail_url in good_detail_urls:
         if re.search(self.target_id, detail_url):
             detail_url = "https:" + detail_url
             self.target_good_detail_url = detail_url
             logger.info('目标商品的详情链接是:%s' % self.target_good_detail_url)
             self.good_detail_urls = good_detail_urls
             # logger.info('目标商品所在列表页的所有商品的详情链接是:%s' % self.good_detail_urls)
             return True
     return False
    def get_detail_page_to_add(self, url):
        self.driver.get(url)
        #弹窗处理
        try:
            WebDriverWait(self.driver, 20).until(
                EC.element_to_be_clickable((By.CLASS_NAME, 'close-layer')))
            self.driver.find_element_by_class_name('close-layer').send_keys(
                Keys.ENTER)
        except TimeoutException:
            pass
        try:
            #有些商品是没有颜色可选的,需要做异常处理
            WebDriverWait(driver=self.driver, timeout=10).until(
                EC.element_to_be_clickable(
                    (By.XPATH, '//ul[@id="j-sku-list-1"]/li[1]/a')))
            self.driver.find_element_by_xpath(
                '//ul[@id="j-sku-list-1"]/li[1]/a').send_keys(Keys.ENTER)
        except TimeoutException:
            pass
        time.sleep(random.randint(1, 4))

        try:
            #有些商品是没有规格可选的,需要做异常处理
            WebDriverWait(driver=self.driver, timeout=10).until(
                EC.element_to_be_clickable(
                    (By.XPATH, '//ul[@id="j-sku-list-2"]/li[1]/a')))
            self.driver.find_element_by_xpath(
                '//ul[@id="j-sku-list-2"]/li[1]/a').click()
        except TimeoutException:
            pass
        time.sleep(random.randint(1, 4))
        self.driver.find_element_by_id('j-add-cart-btn').send_keys(Keys.ENTER)
        if self.target_id in url:
            logger.info('目标商品已成功添加到购物车!')
        else:
            logger.info('非目标商品已成功添加到购物车!')
        #关闭添加购物车后的提示窗口
        try:
            WebDriverWait(driver=self.driver, timeout=10).until(
                EC.element_to_be_clickable(
                    (By.XPATH, '//a[@class="ui-window-close"]')))
            self.driver.find_element_by_xpath(
                '//a[@class="ui-window-close"]').click()
        except TimeoutException:
            pass
 def delete_other_goods_from_cart(self):
     WebDriverWait(driver=self.driver, timeout=20).until(
         EC.element_to_be_clickable(
             (By.XPATH, '//div[@class="nav-cart nav-cart-box"]/a[1]')))
     self.driver.find_element_by_xpath(
         '//div[@class="nav-cart nav-cart-box"]/a[1]').send_keys(Keys.ENTER)
     items = self.driver.find_elements_by_class_name("item-group-wrapper")
     try:
         for item in items:
             good_detail_url = item.find_element_by_xpath(
                 './/a[@target="_blank"]').get_attribute('href')
             if not re.search(self.target_id, good_detail_url):
                 #非目标商品,直接从购物车删除
                 item.find_element_by_xpath(
                     './/div[@class="product-remove"]/form[1]/a').click()
                 logger.info('非目标商品已从购物车中删除!')
                 time.sleep(2)
     #点击删除后,网页会刷新,元素已发生改变,需捕获异常并处理
     except StaleElementReferenceException:
         self.delete_other_goods_from_cart()
 def fill_in_and_save_payment_information(self):
     logger.info('正在进入支付信息的填写流程...')
     WebDriverWait(driver=self.driver, timeout=60).until(
         EC.element_to_be_clickable((By.XPATH, '//input[@name="cardNum"]')))
     time.sleep(random.uniform(0.5, 1.0))
     self.driver.find_element_by_name('cardNum').send_keys(
         self.task_infos[str(self.task_id)]["payment"]["CreditCardNumber"])
     time.sleep(random.uniform(0.5, 1.0))
     self.driver.find_element_by_name('dateM').send_keys(
         self.task_infos[str(self.task_id)]["payment"]["ccMonth"])
     time.sleep(random.uniform(0.5, 1.0))
     self.driver.find_element_by_name('dateY').send_keys(
         self.task_infos[str(self.task_id)]["payment"]["ccYear"])
     time.sleep(random.uniform(0.5, 1.0))
     self.driver.find_element_by_name('cvv2').send_keys(self.task_infos[str(
         self.task_id)]["payment"]["cvv"])
     # 切割全名并判断长度
     FullName_text = self.task_infos[str(
         self.task_id)]["address"]["FullName"].split()
     if len(FullName_text) == 1:
         time.sleep(random.uniform(0.5, 1.0))
         self.driver.find_element_by_name('cardHolderF').send_keys(
             FullName_text[0])
         time.sleep(random.uniform(0.5, 1.0))
         self.driver.find_element_by_name('cardHolderL').send_keys(
             FullName_text[0])
     else:
         time.sleep(random.uniform(0.5, 1.0))
         self.driver.find_element_by_name('cardHolderF').send_keys(
             FullName_text[0])
         time.sleep(random.uniform(0.5, 1.0))
         self.driver.find_element_by_name('cardHolderL').send_keys(
             FullName_text[1])
     # time.sleep(random.uniform(0.5, 1.0))
     # self.driver.find_element_by_name('saveinfo').click()
     time.sleep(random.uniform(0.5, 1.0))
     self.driver.find_element_by_xpath(
         '//div[@class="payment-line"]/button[1]').click()
     logger.info('完成支付信息的填写!')
def main():
    #单进程模式:循环获取待刷单任务,一次获取一个;若获取不到任务,程序退出。
    while True:
        #测试机地址,获取刷单任务,返回字典格式的json串
        # url = 'http://testthird.gets.com:8383/api/index.php?sec=20171212getscn&act=aliexpressGetTaskOrdersList2&get_type=1&limit=1&debug_list=0&debug_allot=0'
        #线上地址,获取刷单任务,返回字典格式的json串
        url = 'http://third.gets.com/api/index.php?sec=20171212getscn&act=aliexpressGetTaskOrdersList2&get_type=1&limit=1'
        resp = requests.get(url)
        # if json.loads(resp.text,strict=False) == []:
        try:
            # if 'status' in resp.json():
            if resp.json() == []:
                logger.info('未获取到待刷单列表的数据,程序结束!')
                sys.exit(0)
            else:
                logger.info('成功获取到一条待刷单的数据!')
                task_infos = resp.json()
                # print(task_infos)
                for key in task_infos.keys():
                    task_id = int(key)
                spider = AliexpressOrderSpider(task_infos, task_id)
                spider.run()
        except json.decoder.JSONDecodeError:
            pass
Пример #8
0
    def run(self):
        try:
            self.driver.get('http://www.aliexpress.com/')
            #过滤弹窗
            try:
                WebDriverWait(self.driver, 40).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"]'))
            )
            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.randint(1, 5))
            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.randint(1, 5))
            self.driver.find_element_by_id('fm-login-submit').submit()
            #此处判断登录过程中是否有滑块验证码,有则终止程序
            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, 40).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,
                        # "order_no": '',
                        # "payment_date": '',
                        # "actual_order_amount": 0.00
                    }
                }
                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_receive_dir = os.path.join(os.path.dirname(__file__), 'confirm_receive_files')
            confirm_receive_filename = confirm_receive_dir + '/' + 'taskid_' + str(self.task_id) + '.txt'
            if os.path.exists(confirm_receive_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()
                # 搜索按钮可点击
                # WebDriverWait(self.driver, 40).until(
                #     EC.element_to_be_clickable((By.ID, 'id="search-btn"'))
                # )
                time.sleep(5)
                # 先找到所有的订单items,再根据订单号或者商品asin,定位到目标订单所在的item
                items = self.driver.find_elements_by_xpath('//*[@id="buyer-ordertable"]/tbody')
                for item in items:
                    if item.find_element_by_xpath('./tr[1]/td[2]/p[1]/span[2]').text == self.task_infos[str(self.task_id)]["import_aliexpress_order"]:
                        logger.info('找到目标订单所在的tbody!')
                        # 根据当前订单的状态做判断
                        if item.find_element_by_xpath('./tr[2]/td[4]/button[3]').text.strip() == 'Leave Feedback':
                            logger.info('当前账户已收货,但未成功留评,准备执行留评的流程...')
                            item.find_element_by_xpath('./tr[2]/td[4]/button[3]').click()
                            # 进入评论页面
                            WebDriverWait(self.driver, 60).until(
                                EC.element_to_be_clickable((By.XPATH, '//div[@name="eval_star_node"]/span[1]'))
                                # EC.element_to_be_clickable((By.XPATH, '//*[@id="star_%s"]/span[1]' % '99723247396644'))
                            )
                            logger.info('进入评论填写页面...')
                            logger.info('当前url:%s' % self.driver.current_url)
                            # 此处需要根据接口数据,来判断好评与差评,再调整星级的点按位置(修改Xpath,可使用占位符,设置星级数为一个实例属性,这样可以简化减少代码臃肿)
                            # 点星商品描述时,需要上传图片
                            if self.task_infos[str(self.task_id)]['review']['title'] == 'bad':
                                stars_num = 1
                            else:
                                stars_num = 5
                            self.driver.find_element_by_xpath(
                                '//div[@name="eval_star_node"]/span[%s]' % stars_num).click()
                            time.sleep(10)
                            # self.driver.find_element_by_xpath('//*[@id="image_uploader_99723247396644"]/div/button')
                            self.driver.find_element_by_xpath('//div[@class="feedback-main"]/textarea').send_keys(
                                self.task_infos[str(self.task_id)]['review']["content"])
                            time.sleep(random.randint(1, 5))
                            img_url = self.task_infos[str(self.task_id)]['review']["images"]
                            if img_url:
                                logger.info('发现图片链接,正在下载图片并将图片上传到评论页面中...')
                                # img_path = ' '#图片的绝对路径或者相对路径
                                img_path = self.get_img_path(img_url=img_url)
                                self.driver.find_element_by_xpath('//div[@class="ui-uploader"]/button[1]').send_keys(
                                    img_path)
                                # 时间延迟,使图片上传完,此处的时间延迟应该怎么做?多久合适?
                                time.sleep(30)
                            else:
                                logger.info('未发现图片链接,将不上传图片到评论页面!')
                                time.sleep(random.randint(1, 3))
                            # 服务态度
                            self.driver.find_element_by_xpath(
                                '//*[@id="j-leave-feedback-container"]/div/div[4]/div[2]/div/div[1]/span[%s]' % stars_num).click()
                            # 物流速度
                            time.sleep(random.randint(1, 3))
                            self.driver.find_element_by_xpath(
                                '//*[@id="j-leave-feedback-container"]/div/div[4]/div[3]/div/div[1]/span[%s]' % stars_num).click()
                            # 勾选,设置为匿名评论
                            time.sleep(random.randint(1, 3))
                            self.driver.find_element_by_id('j-anonymous-feedback').click()
                            # 点击按钮留下反馈
                            time.sleep(random.randint(1, 3))
                            self.driver.find_element_by_id('buyerLeavefb-submit-btn').click()
                            # 留评后的url
                            # 'https://feedback.aliexpress.com/management/leaveFeedback.htm?parentOrderId=99723247396644'
                            time.sleep(20)
                            # 评论完成时,url中没有'isOrderCompleted=Y'
                            # if not 'isOrderCompleted=Y' in self.driver.current_url:
                            if 'Your feedback has been submitted' in self.driver.page_source:
                                logger.info('留评成功!')
                                # 更新刷单状态
                                review_data = {
                                    str(self.task_id): {
                                        "task_id": self.task_id,
                                        "status": 6,
                                    }
                                }
                                self.update_brushing_status(json.dumps(review_data))
                                # 新增刷单操作日志
                                log_data = {
                                    "task_id": self.task_id,
                                    "info": "留评成功!",
                                    'ip': self.get_ip_info(proxies={'https': self.proxy})
                                }
                                self.create_task_order_log(json.dumps(log_data))
                                os.remove(confirm_receive_filename)
                                logger.info('删除了一个文件:%s' % confirm_receive_filename)
                            else:
                                logger.info('留评失败!')
                                review_data = {
                                    str(self.task_id): {
                                        "task_id": self.task_id,
                                        "status": 61,
                                    }
                                }
                                # 更新刷单状态
                                self.update_brushing_status(json.dumps(review_data))
                                # 新增刷单操作日志
                                log_data = {
                                    "task_id": self.task_id,
                                    "info": "留评失败!",
                                    'ip': self.get_ip_info(proxies={'https': self.proxy})
                                }
                                self.create_task_order_log(json.dumps(log_data))
                                os.remove(confirm_receive_filename)
                                logger.info('删除了一个文件:%s' % confirm_receive_filename)
                    break
            else:
                self.review()
            logger.info('当前账户操作完毕,关闭当前浏览器!')
            self.driver.quit()
        except NoSuchFrameException:
            logger.info('切换到登录的frame超时,正在重新请求主页,继续执行登录操作')
            self.run()
        except (TimeoutException, WebDriverException):
            logger.info('等待超时,或者元素位未完全加载导致定位出错!')
            logger.info('关闭当前浏览器,结束当前线程!')
            logger.info('系统会自动生成新的线程来执行下单任务!')
            self.driver.quit()
            sys.exit(0)
Пример #9
0
 def update_account_login_success_info(data):
     url = 'http://third.gets.com/api/index.php?sec=20171212getscn&act=aliexpressUpdateAccountLoginSuccessInfo'
     requests.post(url, data)
     logger.info('对应账户的header和cookies字段已成功修改!')
Пример #10
0
 def insert_account_login_log(data):
     url = 'http://third.gets.com/api/index.php?sec=20171212getscn&act=aliexpressInsertAccountLoginLog'
     requests.post(url, data)
     logger.info('账户登录日志已成功插入!')
Пример #11
0
    def review(self):
        # 点击首页中的"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()

        #点击确认收货
        WebDriverWait(self.driver, 40).until(
            EC.element_to_be_clickable((By.XPATH, '//table[@id="buyer-ordertable"]/tbody/tr[2]/td[4]/button[2]'))
        )
        #此处先进行判断,如果卖家发货,则可以走留评的流程,否则,程序退出。
        if self.driver.find_element_by_xpath('//table[@id="buyer-ordertable"]/tbody/tr[2]/td[4]/button[2]').text.strip() == 'Confirm Goods Received':
            logger.info('卖家已发货,正在执行留评的流程...')
            self.driver.find_element_by_xpath('//table[@id="buyer-ordertable"]/tbody/tr[2]/td[4]/button[2]').click()

            # 进入订单明细页面,勾选目标商品所在的订单,再次点击确认收货
            WebDriverWait(self.driver, 40).until(
                EC.element_to_be_clickable((By.XPATH, '//*[@id="button-confirmOrderReceived"]'))
            )
            trs = self.driver.find_elements_by_xpath('//*[@id="confirm-receiving"]/tbody/tr')
            for tr in trs:
                good_detail_url = tr.find_element_by_xpath('./td[4]/div[1]/a').get_attribute('href')
                if  re.search(self.target_id, good_detail_url):
                    tr.find_element_by_xpath('./td[2]/input').click()
            time.sleep(random.randint(1, 3))
            self.driver.find_element_by_xpath('//*[@id="button-confirmOrderReceived"]').click()
            # 点击弹出的“comfirm”按钮
            WebDriverWait(self.driver, 40).until(
                EC.element_to_be_clickable((By.ID, 'confirm_cpf'))
            )
            self.driver.find_element_by_id('confirm_cpf').click()
            logger.info('点击了最终确认收货的按钮!')
            # 在项目的根目录下,新建一个文件夹confirm_receive_files,并在该文件夹下生成一个文件,文件名命名为'taskid_xx.txt'文件,‘xx’代表任务id
            confirm_receive_dir = os.path.join(os.path.dirname(__file__), 'confirm_receive_files')
            if not os.path.exists(confirm_receive_dir):
                os.mkdir(confirm_receive_dir)
            confirm_receive_filename = confirm_receive_dir + '/' + 'taskid_' + str(self.task_id) + '.txt'
            f = open(confirm_receive_filename, 'w', encoding='utf-8')
            f.close()
            logger.info('同时创建了一个文件:%s' % confirm_receive_filename)
            #进入评论页面
            WebDriverWait(self.driver, 60).until(
                EC.element_to_be_clickable((By.XPATH, '//div[@name="eval_star_node"]/span[1]'))
                # EC.element_to_be_clickable((By.XPATH, '//*[@id="star_%s"]/span[1]' % '99723247396644'))
            )
            logger.info('进入评论填写页面...')
            logger.info('当前url:%s' % self.driver.current_url)
            #此处需要根据接口数据,来判断好评与差评,再调整星级的点按位置(修改Xpath,可使用占位符,设置星级数为一个实例属性,这样可以简化减少代码臃肿)
            #点星商品描述时,需要上传图片
            if self.task_infos[str(self.task_id)]['review']['title'] == 'bad':
                stars_num = 1
            else:
                stars_num = 5
            self.driver.find_element_by_xpath('//div[@name="eval_star_node"]/span[%s]' % stars_num).click()
            time.sleep(10)
            # self.driver.find_element_by_xpath('//*[@id="image_uploader_99723247396644"]/div/button')
            self.driver.find_element_by_xpath('//div[@class="feedback-main"]/textarea').send_keys(self.task_infos[str(self.task_id)]['review']["content"])
            time.sleep(random.randint(1, 5))
            img_url = self.task_infos[str(self.task_id)]['review']["images"]
            if img_url:
                logger.info('发现图片链接,正在下载图片并将图片上传到评论页面中...')
                # img_path = ' '#图片的绝对路径或者相对路径
                img_path = self.get_img_path(img_url=img_url)
                self.driver.find_element_by_xpath('//div[@class="ui-uploader"]/button[1]').send_keys(img_path)
                #时间延迟,使图片上传完,此处的时间延迟应该怎么做?多久合适?
                time.sleep(30)
            else:
                logger.info('未发现图片链接,将不上传图片到评论页面!')
                time.sleep(random.randint(1, 3))
            #服务态度
            self.driver.find_element_by_xpath('//*[@id="j-leave-feedback-container"]/div/div[4]/div[2]/div/div[1]/span[%s]' % stars_num).click()
            #物流速度
            time.sleep(random.randint(1, 3))
            self.driver.find_element_by_xpath('//*[@id="j-leave-feedback-container"]/div/div[4]/div[3]/div/div[1]/span[%s]' % stars_num).click()
            #勾选,设置为匿名评论
            time.sleep(random.randint(1, 3))
            self.driver.find_element_by_id('j-anonymous-feedback').click()
            #点击按钮留下反馈
            time.sleep(random.randint(1, 3))
            self.driver.find_element_by_id('buyerLeavefb-submit-btn').click()
            #留评后的url
            # 'https://feedback.aliexpress.com/management/leaveFeedback.htm?parentOrderId=99723247396644'
            time.sleep(20)
            #评论完成时,url中没有'isOrderCompleted=Y'
            # if not 'isOrderCompleted=Y' in self.driver.current_url:
            if 'Your feedback has been submitted' in self.driver.page_source:
                logger.info('留评成功!')
                # 更新刷单状态
                review_data = {
                    str(self.task_id): {
                        "task_id": self.task_id,
                        "status": 6,
                    }
                }
                self.update_brushing_status(json.dumps(review_data))
                # 新增刷单操作日志
                log_data = {
                    "task_id": self.task_id,
                    "info": "留评成功!",
                    'ip': self.get_ip_info(proxies={'https': self.proxy})
                }
                self.create_task_order_log(json.dumps(log_data))
                os.remove(confirm_receive_filename)
                logger.info('删除了一个文件:%s' % confirm_receive_filename)
            else:
                logger.info('留评失败!')
                review_data = {
                    str(self.task_id): {
                        "task_id": self.task_id,
                        "status": 61,
                    }
                }
                #更新刷单状态
                self.update_brushing_status(json.dumps(review_data))
                # 新增刷单操作日志
                log_data = {
                    "task_id": self.task_id,
                    "info": "留评失败!",
                    'ip': self.get_ip_info(proxies={'https': self.proxy})
                }
                self.create_task_order_log(json.dumps(log_data))
                os.remove(confirm_receive_filename)
                logger.info('删除了一个文件:%s' % confirm_receive_filename)
        else:
            logger.info('卖家尚未发货,暂时不能留评,程序退出!')
            self.driver.quit()
            sys.exit(0)
Пример #12
0
def main(task_infos, task_id):
    spider = AliexpressReviewSpider(task_infos, task_id)
    spider.run()

if __name__ == '__main__':
    # 多线程循环模式:默认一次最多获取5个待评论任务,自动根据获取到的任务数量创建相应数量的线程数,去执行各自分配到的刷单任务;当获取不到任务时,程序退出。
    #修改limit参数即可设置获取的任务数量,现在是1
    while True:
        url = 'http://third.gets.com/api/index.php?sec=20171212getscn&act=aliexpressGetTaskOrdersList2&get_type=3&limit=2'
        resp = requests.get(url)
        try:
            if resp.json() == []:
                # logger.info('未获取到待评论列表的数据,程序结束!')
                # sys.exit(0)
                logger.info('当前未获取到待评论的数据,程序将启动休眠模式,60分钟后自动唤醒...')
                time.sleep(60 * 60)
            else:
                task_infos = resp.json()
                task_id_str_list = []
                for task_id_str in task_infos:
                    task_id_str_list.append(task_id_str)
                logger.info('成功获取到%d条待评论的数据!' % len(task_id_str_list))
                logger.info('将创建%d个线程来分别执行评论任务!' % len(task_id_str_list))
                threads = []
                for i in range(len(task_id_str_list)):
                    task_id = int(task_id_str_list[i])
                    t = threading.Thread(target=main, args=(task_infos, task_id))
                    threads.append(t)
                    t.start()
                    time.sleep(30)
    def run(self):
        try:
            self.driver.get('http://www.aliexpress.com/')
            #过滤弹窗
            try:
                WebDriverWait(self.driver, 40).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.randint(1,3))
            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.randint(1, 5))
            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.randint(1, 5))
            self.driver.find_element_by_id('fm-login-submit').click()
            #此处判断登录过程中是否有滑块验证码,有则终止程序
            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, 40).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,
                        # "order_no": '',
                        # "payment_date": '',
                        # "actual_order_amount": 0.00
                    }
                }
                self.update_brushing_status(json.dumps(brushing_data))
                self.driver.quit()
                logger.info('程序退出!')
                sys.exit(0)

            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, 3):
                #弹窗处理
                try:
                    WebDriverWait(self.driver, 20).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(driver=self.driver, timeout=30).until(
                    EC.element_to_be_clickable((
                        By.XPATH,
                        '//span[@class="ui-pagination-active"]/following-sibling::a[1]'
                    )))
                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:
                    next_page_btn = self.driver.find_element_by_xpath(
                        '//span[@class="ui-pagination-active"]/following-sibling::a[1]'
                    )
                    next_page_btn.click()
                    logger.info('第%d列表搜索页没找到目标商品,正在跳转到第%d列表搜索页...' %
                                (i, i + 1))
                    time.sleep(3)
            else:
                logger.info('前2页中没有找到目标商品,正在拼接目标商品的详情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()
            brushing_data = self.place_order()
            # 更新刷单状态. place_order()成功下单时返回json数据,否则返回None.
            if brushing_data:
                self.update_brushing_status(brushing_data)
                # 新增刷单操作日志
                data = {
                    "task_id": self.task_id,
                    "info": "下单成功!",
                    'ip': self.get_ip_info(proxies={'https': self.proxy})
                }
                self.create_task_order_log(json.dumps(data))
            self.driver.quit()
            logger.info('当前账户操作完毕,关闭当前浏览器!')
        except NoSuchFrameException:
            logger.info('切换到登录的frame超时,正在重新请求主页,继续执行登录操作')
            self.run()
        # except NoSuchElementException:
        #     logger.info('定位不到对应的元素,将重新访问首页,继续走流程!')
        #     self.run()
        # except WebDriverException:
        #     logger.info('点击下一页连接时出错,将重新访问首页,继续走流程!')
        #     self.run()
        except (TimeoutException, WebDriverException) as e:
            # 在操作过程中等待超时,先退出当前登录状态,再重新执行run方法回调,重新走流程。也可直接结束程序,只适合在多线程的情况下操作。
            logger.info('等待超时,或者元素位未完全加载导致点击出错,正在检查登录状态,若已登录,则退出登录状态,重新走流程!')
            self.driver.execute_script(
                'window.scrollTo(document.body.scrollWidth,0 );')
            time.sleep(3)
            try:
                element = self.driver.find_element_by_xpath(
                    '//div[@id="nav-user-account"]/div[1]')
                actions = ActionChains(self.driver)
                actions.move_to_element(element)
                actions.perform()
                WebDriverWait(self.driver, 60).until(
                    EC.element_to_be_clickable(
                        (By.XPATH,
                         '//div[@id="nav-user-account"]/div[2]/div[1]/a')))
                self.driver.find_element_by_xpath(
                    '//div[@id="nav-user-account"]/div[2]/div[1]/a').click()
                time.sleep(4)
                # 此处必须有关闭浏览器的操作,否则登录状态退出不彻底,不能正常run回调
                self.driver.close()
            except NoSuchElementException:
                pass
            #是否需要close?
            self.run()
    def place_order(self):
        #页面刷新,可有可无
        self.driver.refresh()
        WebDriverWait(driver=self.driver, timeout=20).until(
            EC.element_to_be_clickable(
                (By.XPATH, '//div[@class="product-price-info3"]/a[1]')))
        quantity = self.driver.find_element_by_xpath(
            '//input[@readonly="readonly"]').get_attribute('value')
        # 发现一个有意思的情况,同一款商品同规格同颜色,多次添加到购物车,进入购物车查看时,商品数量依然为1。
        # 所以,商品数量的处理,可以简化。
        if quantity == '1':
            price_text = self.driver.find_element_by_xpath(
                '//span[@class="total-price ui-cost notranslate"]/b').text
            price = re.sub(r'US \$', '', price_text)
            #此处购物车中的待支付金额是否超出单笔最大额度,若超出,则终止刷单。
            logger.info('删除非目标商品后,购物车中查看到的待支付金额:%s' % price)
            if float(price) > float(self.task_infos[str(
                    self.task_id)]["payment"]["single_max_trade"]):
                logger.info('删除非目标商品后,购物车中查看到的待支付金额超出单笔最大额度,终止刷单!')
                # 新增刷单操作日志
                data = {
                    "task_id": self.task_id,
                    "info": "删除非目标商品后,购物车中查看到的待支付金额超出单笔最大额度,终止刷单!",
                    'ip': self.get_ip_info(proxies={'https': self.proxy})
                }
                self.create_task_order_log(json.dumps(data))
                logger.info('程序结束!')
                sys.exit(0)
            self.driver.find_element_by_xpath(
                '//div[@class="product-price-info3"]/a[1]').send_keys(
                    Keys.ENTER)

            logger.info('走下单流程!准备进入个人信息和支付信息的填写流程...')
            #跳转到个人信息填写页面,需要加以判断,是否已有地址信息
            WebDriverWait(driver=self.driver, timeout=30).until(
                EC.presence_of_element_located(
                    (By.XPATH, '//*[@id="page"]/div[1]/div[1]/ol/li[1]')))
            try:
                default_address_info_element = self.driver.find_element_by_xpath(
                    '//*[@id="address-main"]/div[2]/ul/li/div/div[1]')
                if 'selected' in default_address_info_element.get_attribute(
                        'class'):
                    logger.info('已有默认收货地址!')
                    self.driver.execute_script(
                        'window.scrollTo(0,document.body.scrollHeight)')
                    time.sleep(3)
                    try:
                        # if self.driver.find_element_by_xpath('//*[@id="j-payment-method"]/div[4]/ul/li[1]/span/span'):
                        if self.driver.find_element_by_xpath(
                                '//ul[@class="pay-method-list"]/li[1]/span/span'
                        ):
                            logger.info('已有默认支付信息!')
                    except NoSuchElementException:
                        # 找不到对应的元素,即没有默认支付信息,则继续走支付信息的填写流程
                        self.fill_in_and_save_payment_information()
            except NoSuchElementException as e:
                logger.info('没有默认收货地址,正在新建收货地址...')
                WebDriverWait(driver=self.driver, timeout=30).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, '//div[@class="sa-btn-group"]/a')))
                self.driver.find_element_by_name('contactPerson').send_keys(
                    self.task_infos[str(self.task_id)]["address"]["FullName"])
                time.sleep(random.uniform(0.5, 1.0))
                country_selectBtn = Select(
                    self.driver.find_element_by_name('country'))
                country_selectBtn.select_by_visible_text('United States')
                time.sleep(random.uniform(0.5, 1.0))
                self.driver.find_element_by_name('address').send_keys(
                    self.task_infos[str(
                        self.task_id)]["address"]["AddressLine1"])
                if self.task_infos[str(
                        self.task_id)]["address"]["AddressLine2"]:
                    time.sleep(random.uniform(0.5, 1.0))
                    self.driver.find_element_by_name('address2').send_keys(
                        self.task_infos[str(
                            self.task_id)]["address"]["AddressLine2"])
                state_selectBtn = Select(
                    self.driver.find_element_by_xpath(
                        '//input[@name="province"]/following-sibling::select[1]'
                    ))
                try:
                    time.sleep(random.uniform(0.5, 1.0))
                    state_selectBtn.select_by_visible_text(self.task_infos[str(
                        self.task_id)]["address"]["StateOrRegion"])
                except Exception:
                    logger.info('从接口获取的StateOrRegion信息对应不上,默认为下拉列表的第一个州或地区!')
                    StateOrRegion = self.driver.find_element_by_xpath(
                        '//input[@name="province"]/following-sibling::select[1]/option[2]'
                    ).text
                    print(StateOrRegion)
                    time.sleep(random.uniform(0.5, 1.0))
                    state_selectBtn.select_by_visible_text(StateOrRegion)
                # 此处需要时间延迟,来加载城市的下拉列表
                time.sleep(12)
                city_selectBtn = Select(
                    self.driver.find_element_by_xpath(
                        '//input[@name="city"]/following-sibling::select[1]'))
                #amazon的城市信息与速卖通的城市信息不一定匹配,比如大小写不一致,需要做异常处理
                try:
                    time.sleep(random.uniform(0.5, 1.0))
                    city_selectBtn.select_by_visible_text(self.task_infos[str(
                        self.task_id)]["address"]["City"])
                except Exception:
                    logger.info('从接口获取的城市信息对应不上,正在进行异常处理...')
                    try:
                        city_text = self.task_infos[str(
                            self.task_id)]["address"]["City"].split()
                        city_text[-1] = city_text[-1].lower()
                        city = " ".join(city_text)
                        print(city)
                        time.sleep(random.uniform(0.5, 1.0))
                        city_selectBtn.select_by_visible_text(city)
                    except Exception:
                        logger.info('大小写处理失败,默认为下拉列表的第一个城市!')
                        city = self.driver.find_element_by_xpath(
                            '//input[@name="city"]/following-sibling::select[1]/option[2]'
                        ).text
                        # print(city)
                        time.sleep(random.uniform(0.5, 1.0))
                        city_selectBtn.select_by_visible_text(city)
                # city_selectBtn.select_by_visible_text('Jersey city')
                time.sleep(random.uniform(0.5, 1.0))
                self.driver.find_element_by_name('zip').send_keys(
                    self.task_infos[str(
                        self.task_id)]["address"]["PostalCode"])
                #电话号码需要处理,若有"+1"前缀,则去掉"+1"前缀
                PhoneNumber = self.task_infos[str(
                    self.task_id)]["address"]["PhoneNumber"]
                if re.match(r'\+1', PhoneNumber):
                    PhoneNumber = re.sub(r'\+1', '', PhoneNumber)
                time.sleep(random.uniform(0.5, 1.0))
                self.driver.find_element_by_name('mobileNo').send_keys(
                    PhoneNumber)
                time.sleep(random.uniform(0.5, 1.0))
                self.driver.find_element_by_name('isDefault').click()
                time.sleep(random.uniform(0.5, 1.0))
                self.driver.find_element_by_xpath(
                    '//div[@class="sa-btn-group"]/a[1]').click()
                self.fill_in_and_save_payment_information()

            WebDriverWait(driver=self.driver, timeout=30).until(
                EC.element_to_be_clickable(
                    (By.XPATH,
                     '//div[@class="place-order-button"]/button[1]')))
            #点击"Confirm & Pay"
            time.sleep(random.uniform(0.5, 1.0))
            self.driver.find_element_by_xpath(
                '//div[@class="place-order-button"]/button[1]').click()
            WebDriverWait(driver=self.driver, timeout=30).until(
                EC.element_to_be_clickable(
                    (By.XPATH, '//*[@id="header"]/div/div[2]/div[1]/a')))
            time.sleep(15)
            if 'payOnlineSuccess' in self.driver.current_url:
                self.driver.save_screenshot('PaySuccess.png')
                logger.info('下单成功!')
                # logger.info("成功下单后的url:%s" % self.driver.current_url)
                payment_date = datetime.datetime.now().strftime(
                    '%Y-%m-%d %H:%M:%S')
                logger.info('下单时间:%s' % payment_date)
                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)
                order_no = self.driver.find_element_by_xpath(
                    '//*[@id="buyer-ordertable"]//tr[1]/td[2]/p[1]/span[2]'
                ).text
                logger.info("订单号为:%s" % order_no)
                price_text = self.driver.find_element_by_xpath(
                    '//*[@id="buyer-ordertable"]/tbody[1]/tr[1]/td[4]/div/p[2]'
                ).text.strip()
                actual_order_amount = re.sub(r'\$ ', '', price_text)
                logger.info('订单总价:%s' % actual_order_amount)
                brushing_data = {
                    str(self.task_id): {
                        "task_id": self.task_id,
                        "status": 2,
                        "order_no": order_no,
                        "payment_date": payment_date,
                        "actual_order_amount": float(actual_order_amount)
                    }
                }
                # print(json.dumps(data))
                return json.dumps(brushing_data)
            else:
                logger.info('支付失败!')
                self.driver.save_screenshot('PayFailed.png')
                logger.info('支付失败的url:%s' % self.driver.current_url)
                #新增刷单操作日志
                data = {
                    "task_id": self.task_id,
                    "info": "支付失败!导致下单失败!",
                    'ip': self.get_ip_info(proxies={'https': self.proxy})
                }
                self.create_task_order_log(json.dumps(data))