Пример #1
0
 def __call__(self, driver):
     return not EC.title_is(LOGIN_PAGE_TITLE)(driver) \
            or EC.presence_of_element_located((By.ID, EMAIL_MISSING_ALERT_ID))(driver) \
            or EC.presence_of_element_located((By.ID, PASSWORD_MISSING_ALERT_ID))(driver) \
            or EC.presence_of_element_located((By.ID, ERROR_MESSAGE_BLOCK_ID))(driver) \
            or EC.presence_of_element_located((By.ID, WARNING_MESSAGE_BLOCK_ID))(driver) \
            or EC.presence_of_element_located((By.ID, CAPTCHA_MISSING_ALERT_ID))(driver)
Пример #2
0
    def logout(self):
        """
        登出
        :return: True
        """
        if EC.presence_of_all_elements_located((By.ID, NAV_TOOLS_BLOCK_ID))(self.browser):
            loop = 2
            for i in range(0, loop):
                try:
                    if EC.presence_of_all_elements_located((By.ID, ACCOUNT_LINK_1_ID))(self.browser):
                        account_link = self.browser.find_element_by_id(ACCOUNT_LINK_1_ID)
                    else:
                        account_link = self.browser.find_element_by_id(ACCOUNT_LINK_2_ID)

                    ActionChains(self.browser).move_to_element(account_link).perform()
                    WebDriverWait(self.browser, 1).until(
                        lambda driver: EC.visibility_of_any_elements_located((By.ID, ACCOUNT_BLOCK_1_ID))(driver)
                                       or EC.visibility_of_any_elements_located((By.ID, ACCOUNT_BLOCK_2_ID))(driver)
                    )
                except TimeoutException:
                    if i == loop - 1:
                        raise
                else:
                    break

            try:
                logout = self.browser.find_element_by_id(LOGOUT_LINK_ID)
            except NoSuchElementException:
                pass
            else:
                logout.click()
                WebDriverWait(self.browser, self._wait).until(EC.title_is(LOGIN_PAGE_TITLE))

        return True
Пример #3
0
    def order(self):
        """
        确认支付
        :return:
        """
        WebDriverWait(self.browser, self._wait).until(EC.title_is(ORDER_COMPLETE_PAGE_TITLE))

        self.browser.get_screenshot_as_file('xxxx.png')  # TODO
Пример #4
0
    def login(self):
        """
        登录
        :return: 登入成功/失败
        """
        if not self.browser.title == LOGIN_PAGE_TITLE:
            self.visit(self.login_page, EC.title_is(LOGIN_PAGE_TITLE))

        email_input_field = self.browser.find_element_by_id(EMAIL_INPUT_FIELD_ID)
        password_input_field = self.browser.find_element_by_id(PASSWORD_INPUT_FIELD_ID)
        submit_button = self.browser.find_element_by_id(LOGIN_BUTTON_ID)

        email_input_field.clear()
        email_input_field.send_keys(self.email)
        password_input_field.clear()
        password_input_field.send_keys(self.password)
        submit_button.click()

        WebDriverWait(self.browser, self._wait).until(login_complete(), '登录后页面异常。')

        return not EC.title_is(LOGIN_PAGE_TITLE)(self.browser)
Пример #5
0
    def get_order_code(self, asins):
        """
        取得Amazon单号
        :return:
        """
        if EC.title_is(ORDER_COMPLETE_PAGE_TITLE)(self.browser):
            # 从注文完成页面中取得
            orders = self.browser.find_elements_by_xpath(ORDER_CODE_XPATH)
            for order in orders:
                print(order.text)
        else:
            # 非注文完成页面,从注文履历中取得
            self.visit(self.history_page)

            # 如跳转到登录页面,进行登录
            if self.browser.title == LOGIN_PAGE_TITLE:
                self.login()

            WebDriverWait(self.browser, self._wait).until(EC.title_is(HISTORY_PAGE_TITLE))

            # 注文番号取得
            orders = iter(
                self.browser.find_element_by_id(HISTORY_BLOCK_ID).find_elements_by_xpath(HISTORY_ORDER_BLOCK_XPATH))
            for order in orders:
                # 每组商品的注文番号
                code = order.find_element_by_xpath(HISTORY_ORDER_CODE_BLOCK_XPATH).text

                # 检查该注文内的所有商品
                items = iter(order.find_elements_by_xpath(HISTORY_ITEM_BLOCK_XPATH))
                for item in items:
                    item_name = item.find_element_by_xpath(HISTORY_ITEM_NAME_XPATH)
                    asin = re.search('(?<=^https://www\.amazon\.co\.jp/gp/product/)[A-Z0-9]{10}(?=/)',
                                     item_name.get_attribute("href")).group()
                    print(asin)
                    # TODO
        return True
Пример #6
0
    def clear_cart(self):
        """
        清空购物车
        :return: 购物车清空成功/失败
        """
        if self.browser.title != CART_PAGE_TITLE:
            self.visit(self.cart_page, EC.title_is(CART_PAGE_TITLE))

        for delete in self.browser.find_elements_by_xpath(DELETE_LINK_XPATH):
            try:
                WebDriverWait(self.browser, self._wait).until(EC.element_is_enabled(delete))
            except TimeoutException:
                return False

            delete.click()

        return True
Пример #7
0
 def __call__(self, driver):
     return EC.title_is(AGE_CERTIFICATION_PAGE_TITLE)(driver) \
            or EC.element_to_be_clickable((By.ID, ADD_TO_CART_BUTTON_ID))(driver)
Пример #8
0
    def checkout(self, address):
        """
        支付操作
        :param address
        :return:
        """
        checkout_button = self.browser.find_element_by_name(CHECKOUT_BUTTON_NAME)
        if not checkout_button.is_enabled():
            raise Exception('无法进行支付!')

        checkout_button.click()

        # 如跳转到登录页面,进行登录
        if self.browser.title == LOGIN_PAGE_TITLE:
            self.login()

        # 清空已存地址
        self._clear_address()

        # --输入地址--
        name_input_field = self.browser.find_element_by_id(NAME_INPUT_FIELD_ID)
        postcode1_input_field = self.browser.find_element_by_id(POSTCODE1_INPUT_FIELD_ID)
        postcode2_input_field = self.browser.find_element_by_id(POSTCODE2_INPUT_FIELD_ID)
        prefecture_select = self.browser.find_element_by_id(PREFECTURE_SELECT_FIELD_ID)
        address1_input_field = self.browser.find_element_by_id(ADDRESS1_INPUT_FIELD_ID)
        address2_input_field = self.browser.find_element_by_id(ADDRESS2_INPUT_FIELD_ID)
        company_input_field = self.browser.find_element_by_id(COMPANY_INPUT_FIELD_ID)
        tel_input_field = self.browser.find_element_by_id(TEL_INPUT_FIELD_ID)

        # 初始化
        name_input_field.clear()
        postcode1_input_field.clear()
        postcode2_input_field.clear()
        Select(prefecture_select).select_by_value('')
        address1_input_field.clear()
        address2_input_field.clear()
        company_input_field.clear()
        tel_input_field.clear()

        # 姓名
        name_input_field.send_keys(address['name'])

        # 邮政编码
        postcode1_input_field.send_keys(address['postcode'][:-4])
        postcode2_input_field.send_keys(address['postcode'][-4:])

        # 都道府县
        WebDriverWait(self.browser, self._wait).until(EC.value_is_not(prefecture_select, ''))
        Select(prefecture_select).select_by_value(address['prefecture'])

        # 住所1
        WebDriverWait(self.browser, self._wait).until(EC.value_is_not(address1_input_field, ''))
        if re.match(address1_input_field.get_attribute('value'), address['address1']):
            address1_input_field.clear()
            address1_input_field.send_keys(address['address1'])
        else:
            raise Exception('地址与邮编不符!')

        # 住所2
        address2_input_field.send_keys(address['address2'])

        # 公司
        company_input_field.send_keys(address['company'])

        # 电话号码
        tel_input_field.send_keys(address['tel'])

        # 下一步
        self.browser.find_element_by_name(ADDRESS_NEXT_BUTTON_NAME).click()

        # --配送方式选择--
        WebDriverWait(self.browser, self._wait).until(EC.title_is(SHIPPING_PAGE_TITLE))
        self.browser.find_element_by_id(SHIPPING_FORM_ID).submit()

        # --支付方式选择--TODO
        WebDriverWait(self.browser, self._wait).until(EC.title_is(PAYMENT_PAGE_TITLE))
        self.browser.find_element_by_name('paymentMethod').click()
        self.browser.find_element_by_id(PAYMENT_NEXT_BUTTON_ID).click()

        # 检查
        WebDriverWait(self.browser, self._wait).until(EC.title_is(ORDER_PAGE_TITLE))
        if not self.browser.find_element_by_name(ORDER_BUTTON_NAME).is_enabled():
            raise Exception('无法完成支付,请确认交易信息!')

        price = None
        gift = None
        summaries = list()
        for summary in iter(self.browser.find_element_by_id(ORDER_SUMMARY_BLOCK_ID).find_elements_by_tag_name('tr')):
            td = summary.find_elements_by_tag_name('td')
            if len(td) == 2:
                label = re.sub(r'[::]\s*$', '', td[0].text)
                value = self._price(td[1].text)
                if label == 'ご請求額':
                    price = value
                elif label == 'Amazonギフト券':
                    gift = value

                summaries.append({
                    'label': label,
                    'price': value
                })

        if len(summaries) == 0 or price is None or gift is None:
            raise Exception('交易价格明细取得失败!')

        return price - gift, summaries
Пример #9
0
    def cart(self, products):
        """
        购物车操作
        :param products:
        :return: 操作完成后的商品情报
        """
        # 操作完成后,购物车中的商品情报
        cart = dict()

        if self.browser.title != CART_PAGE_TITLE:
            self.visit(self.cart_page, EC.title_is(CART_PAGE_TITLE))

        # 购物车中的商品列表
        container = self.browser.find_element_by_id(CART_FORM_ID)
        try:
            container = container.find_element_by_css_selector(CART_ITEM_LIST_BLOCK_CSS)
        except NoSuchElementException:
            raise Exception('操作失败,购物车中无商品!')
        items = container.find_elements_by_css_selector(CART_ITEM_BLOCK_CSS)

        if len(items) != len(products):
            # 加入到购物车中的商品数与购买商品数不一致
            raise Exception('加入到购物车中的商品数与购买商品数不一致!')

        # 循环购物车中商品列表,检查商品状态的同时修改购买数量
        for item in items:
            asin = item.get_attribute('data-asin')
            quantity = int(item.get_attribute('data-quantity'))

            try:
                # 处理中的商品
                product = products[asin]
            except KeyError:
                # 购物车中存在未被购买的商品
                raise Exception(f'未购买商品{asin}存在于购物车中!')

            # 保证price与quantity均为int型
            product['price'] = int(product['price'])
            product['quantity'] = int(product['quantity'])

            if quantity != product['quantity']:
                quantity_input_field = item.find_element_by_name(QUANTITY_INPUT_FIELD_NAME)
                if quantity_input_field.is_displayed():
                    # 当数量输入栏可见时,直接输入购买数量后Enter
                    quantity_input_field.clear()
                    quantity_input_field.send_keys(product['quantity'])
                    quantity_input_field.send_keys(Keys.ENTER)

                else:
                    # 当数量输入栏不可见时,选择购买数量
                    if product['quantity'] < 10:
                        Select(item.find_element_by_name(QUANTITY_SELECT_NAME)).select_by_value(
                            str(product['quantity']))

                    else:
                        Select(item.find_element_by_name(QUANTITY_SELECT_NAME)).select_by_value('10')
                        WebDriverWait(self.browser, self._wait).until(EC.element_is_displayed(quantity_input_field))

                        quantity_input_field.clear()
                        quantity_input_field.send_keys(product['quantity'])
                        quantity_input_field.send_keys(Keys.ENTER)

                WebDriverWait(self.browser, self._wait).until(cart_quantity_changed(container, asin))

            # 检查价格与数量
            item = container.find_element_by_xpath(CART_ITEM_BLOCK_XPATH % asin)

            cart[asin] = {
                'price': int(item.get_attribute('data-price')),
                'quantity': int(item.get_attribute('data-quantity'))
            }

        return cart