Esempio n. 1
0
    def click_btn(self, xpath, el=None):
        try:
            if not el:
                btn = self.wait.until(
                    EC.presence_of_element_located((By.XPATH, xpath)))
                if btn.is_enabled():
                    btn.click()
                else:
                    logger.debug(f"click_btn:{xpath}该元素不可操作")
                    self.run_status = False
                    self.result["status"] = 401
                    self.result["errorMessage"] = "获取的元素不可用"

            else:
                el.find_element_by_xpath(xpath=xpath).click()
            time.sleep(2)
        except TimeoutException:
            logger.error(f"点击{xpath}超时")
            self.run_status = False
            self.result["status"] = 401
            self.result["errorMessage"] = "获取的元素超时"
        except Exception as e:
            logger.error(f"定位{xpath}时,点击click时出错,错误信息:{str(e)}")
            self.run_status = False
            self.result["status"] = 401
            self.result["errorMessage"] = "获取的元素出现错误"
Esempio n. 2
0
    def fill_card_info(self):
        """
        输入卡号信息
        :return:
        """
        card_num_xpath = '//*[@id="cardNumber"]'
        card_name_xpath = '//*[@id="cardholderName"]'
        month_xpath = '//*[@id="expiryMonth"]'
        year_xpath = '//*[@id="expiryYear"]'
        cvv_code_xpath = '//*[@id="securityCode"]'

        card_info_dict = {
            card_num_xpath:
            self.payment_card_info["cardNumber"],
            card_name_xpath:
            self.payment_card_info["lastName"] + "/" +
            self.payment_card_info["firstName"],
            month_xpath:
            self.payment_card_info["cardExpired"].split("-")[1],
            year_xpath:
            self.payment_card_info["cardExpired"].split("-")[0],
            cvv_code_xpath:
            self.payment_card_info["cvv"],
        }

        for k, v in card_info_dict.items():
            self.fill_input(content=v, xpath=k)

        logger.debug("填写卡号信息完成")
Esempio n. 3
0
 def fill_input(self, content, xpath, single_input=False):
     """
     获取到xpath表达式,定位元素,输入内容
     :param args:
     :param kwargs:
     :return:
     """
     try:
         input_content = self.wait.until(
             EC.presence_of_element_located((By.XPATH, xpath)))
         if input_content.is_enabled():
             # 一个一个字母输入
             input_content.clear()
             if single_input:
                 for item in content:
                     input_content.send_keys(item)
                     time.sleep(0.7)
             else:
                 input_content.send_keys(content)
         else:
             logger.debug(f"fill_input:{xpath}该元素不可操作")
             self.run_status = False
             self.result["status"] = 401
             self.result["errorMessage"] = "获取的元素不可用"
     except Exception as e:
         logger.error(f"定位{xpath}时,填写{content}时出错,错误信息:{str(e)}")
         self.run_status = False
         self.result["status"] = 401
         self.result["errorMessage"] = "获取元素失败"
Esempio n. 4
0
 def pay(self):
     """
     点击进行支付
     :return:
     """
     logger.debug("开始支付")
     pay_btn_xpath = '//*[@id="submitButton"]'
     self.click_btn(pay_btn_xpath)
Esempio n. 5
0
    def fill_passenger_info(self):
        """
        填写乘客信息
        :return:
        """
        # 关闭登陆提示框
        close_btn_xpath = '//*[@id="loginform-modal"]/div/div/div[1]/a'
        self.click_btn(close_btn_xpath)
        # 获取所有的乘客输入div标签
        form_passenger_xpath = '//ng-form[@name="passengersCtl.paxInfo"]/div[1]/div'
        form_passengers_obj = self.get_ele_list(form_passenger_xpath)

        for index, passenger in enumerate(self.passengers_info):
            # index : 乘客对应的form输入框
            # 名字
            firstname_xpath = './form//ul/li[1]/input'
            lastname_xpath = './form//ul/li[2]/input'
            self.fill_input(content=passenger["name"].split("/")[1],
                            xpath=firstname_xpath,
                            el=form_passengers_obj[index])
            self.fill_input(content=passenger["name"].split("/")[0],
                            xpath=lastname_xpath,
                            el=form_passengers_obj[index])

            man_xpath = './form/div[1]/div[4]/div[2]/div/div[2]/ul/li[3]/span[1]'
            female_xpath = './form/div[1]/div[4]/div[2]/div/div[2]/ul/li[3]/span[2]'
            if passenger["sex"] == "F":  # 女生
                self.click_btn(el=form_passengers_obj[index],
                               xpath=female_xpath)
            else:
                self.click_btn(el=form_passengers_obj[index], xpath=man_xpath)

            # 输入出生日期
            # 在输入日期之前先点击输入框
            birthday_xpath = './form//ul/li[4]/input'
            self.click_btn(xpath=birthday_xpath, el=form_passengers_obj[index])
            birthday = "".join(passenger["birthday"].split("-"))
            self.fill_input(xpath=birthday_xpath,
                            content=birthday,
                            el=form_passengers_obj[index],
                            single_input=False)

            # 选择国家
            if index == 0:
                country_xpath = './form/div[2]/ul/li[1]/dl/dd/div[1]/label/input'
                self.fill_input(content="日本",
                                xpath=country_xpath,
                                el=form_passengers_obj[index])

        # 填写完毕,点击下一步
        next_xpath = '//dd[@class="usr-action-box--jp-b next"]/button'
        self.click_btn(xpath=next_xpath)

        logger.debug("乘客信息填写完毕")
        time.sleep(3)
Esempio n. 6
0
    def select_payment_method(self):
        """
        选择支付方式
        :return:
        """
        # 选用VCC visa
        vcc_xpath = '//div[@class="cardtype ng-scope"]/label[2]/span'
        self.click_btn(vcc_xpath)
        time.sleep(5)

        logger.debug("支付方式选择完毕")
        # 点击下一步
        next_xpath = '//div[@class="vnl-payment-action"]/a[@data-id="act-next"]'
        self.click_btn(next_xpath)
        time.sleep(5)
Esempio n. 7
0
 def click_btn(self, xpath):
     try:
         btn = self.wait.until(
             EC.presence_of_element_located((By.XPATH, xpath)))
         if btn.is_enabled():
             btn.click()
             time.sleep(1)
         else:
             logger.debug(f"click_btn:{xpath}该元素不可操作")
             self.run_status = False
     except TimeoutException:
         logger.error(f"点击{xpath}超时")
         self.run_status = False
     except Exception as e:
         logger.error(f"定位{xpath}时,点击click时出错,错误信息:{str(e)}")
         self.run_status = False
Esempio n. 8
0
 def click_btn(self, xpath, el=None):
     try:
         if not el:
             btn = self.wait.until(
                 EC.presence_of_element_located((By.XPATH, xpath)))
             if btn.is_enabled():
                 btn.click()
                 time.sleep(1)
             else:
                 logger.debug(f"click_btn:{xpath}该元素不可操作")
                 self.run_status = False
         else:
             el.find_element_by_xpath(xpath).click()
     except TimeoutException:
         logger.error(f"点击{xpath}超时")
         self.run_status = False
         raise StopException("点击超时")
     except Exception as e:
         logger.error(f"定位{xpath}时,点击click时出错,错误信息:{str(e)}")
         self.run_status = False
Esempio n. 9
0
    def sure_info(self):
        """
        确认所选信息, 校对选择的行李是否正确,获取行李的总价格回填行李价格和其他费用
        :return:
        """
        if sum(self.luggages_weight) > 0:
            # 有行李
            # 获取行李价格
            detail_info_list_xpath = '//div[@data-id="flight_1"]//div[@class="vnl-fare-detail-summary-detail-box vnl-fare-detail-summary-detail__blk"][2]/div'
            detail_info_list = self.get_ele_list(detail_info_list_xpath)
            for item in detail_info_list:
                if "託運行李" in self.get_text(xpath='./p', el=item):
                    luggage_price_xpath = './/dd[@class="price ng-binding"]'
                    luggage_price = self.get_text(xpath=luggage_price_xpath,
                                                  el=item).split()[1].replace(
                                                      ",", "")  # 'HKD 1,976'
                    self.fill_back["baggagePrice"] = float(luggage_price)

                    break

        else:
            # 回填行李重量和价格
            self.fill_back["baggagePrice"] = 0.0

        # 获取价格,去掉行李的价格
        total_price_xpath = '//div[@class="vnl_itinerary_price-total_price"]/span/span'
        total_price = self.get_text(
            xpath=total_price_xpath).split()[1].replace(",", "")

        self.fill_back["price"] = float(
            total_price) - self.fill_back["baggagePrice"]

        # 同意协议
        sure_xpath = '//div[@class="reconfirm_agreement_check"]/p//span[1]'
        self.click_btn(sure_xpath)
        # 点击下一步
        pay_btn_xpath = '//a[@data-id="act-purchase"]'
        self.click_btn(pay_btn_xpath)

        logger.debug("同意协议点击无误")
        time.sleep(10)
Esempio n. 10
0
    def fill_contact_info(self):
        """
        填写联系人信息
        :return:
        """
        # 填写邮箱
        email_xpath = '//div[@class="vnl-payment-contact-information"]//div[@class="right"]/dl[1]/dd//input'
        self.fill_input(xpath=email_xpath, content=self.contact["linkEmail"])
        email_sure_xpath = '//div[@class="vnl-payment-contact-information"]//div[@class="right"]/dl[2]/dd//input'
        self.fill_input(xpath=email_sure_xpath,
                        content=self.contact["linkEmail"])

        # 联系人区号
        area_code_xpath = '//div[@class="vnl-payment-contact-information"]//div[@class="left"]/dl[4]/dd//input'
        self.fill_input(xpath=area_code_xpath, content=100000)
        # 联系人电话
        phone_num_xpath = '//div[@class="vnl-payment-contact-information"]//div[@class="left"]/dl[5]/dd//input'
        self.fill_input(xpath=phone_num_xpath,
                        content=self.contact["linkPhone"])

        logger.debug("联系人信息填写完毕")
Esempio n. 11
0
 def fill_input(self, content, xpath, single_input=False, el=None):
     """
     获取到xpath表达式,定位元素,输入内容
     :param args:
     :param kwargs:
     :return:
     """
     try:
         if not el:
             input_content = self.wait.until(
                 EC.presence_of_element_located((By.XPATH, xpath)))
             if input_content.is_enabled():
                 # 一个一个字母输入
                 input_content.clear()
                 if single_input:
                     for item in content:
                         input_content.send_keys(item)
                         time.sleep(0.7)
                 else:
                     input_content.send_keys(content)
             else:
                 logger.debug(f"fill_input:{xpath}该元素不可操作")
                 self.run_status = False
         else:
             if not single_input:
                 el.find_element_by_xpath(xpath).send_keys(content)
             else:
                 for item in content:
                     el.find_element_by_xpath(xpath).send_keys(item)
                     time.sleep(0.3)
     except TimeoutException:
         logger.error("填写信息超时")
         self.run_status = False
         raise StopException("填写信息超时")
     except Exception as e:
         logger.error(f"定位{xpath}时,填写{content}时出错,错误信息:{str(e)}")
         self.run_status = False
Esempio n. 12
0
def main():
    pur = Purchase()
    # 初始化浏览器,选择航班
    if pur.run_status:
        pur.select_flight()
    else:
        # 初始化失败
        logger.error("初始化失败")
        pur.result["status"] = 401
        pur.result["errorMessage"] = "因为网络波动,浏览器初始化失败"

    # 选择航班成功,选择行李,座位等
    if pur.run_status:
        if pur.child_num:
            # 需要选择座位
            click_seat = pur.select_site()
            if isinstance(click_seat, list):
                # 点击座位
                pur.click_select_seat(click_seat)
                # 选择行李
                pur.select_packages()
        else:
            pur.select_packages()
    else:
        logger.debug("选择航班错误")

    # 选择结束,点击继续, 进行登陆
    if pur.run_status:
        pur.loggin()
    else:
        logger.debug("选择行李或选择座位错误")

    # 登陆成功,进行支付
    if pur.run_status:
        pur.fill_payment_info()
    else:
        logger.debug("登陆失败")

    if pur.run_status:
        pur.check_out_price()
    # 进行支付
    if pur.run_status:
        pur.payment()
    else:
        logger.debug("填写支付信息出现错误")

    return pur.result
Esempio n. 13
0
    def select_flight(self, flight_num):
        """
        选择对应的航班号
        :param flight_num:
        :return:
        """
        try:
            flight_info_xpath = '/html/body/div[1]/div[2]/div/div/div[1]/div/div[1]/div[3]/div[2]/div/div[4]/div/div[2]/dl'
            dl_list = self.get_ele_list(flight_info_xpath)

            # 匹配航班号
            for index, item in enumerate(dl_list):
                # 获取页面的航班号
                if index == 0:
                    continue
                page_flight_num_xpath = './dt/span[2]'
                page_flight_num, page_flight_date = self.get_text(
                    page_flight_num_xpath, item).split()
                if page_flight_num == flight_num:
                    # 点击选中航班
                    # 点击原味香草simple
                    simple_xpath = './dd[2]'
                    self.click_btn(simple_xpath, item)
                    time.sleep(2)
                    # 关闭提示框
                    tip_xpath = './dd[2]/div/span/span[2]/div/div/div[1]/a'
                    self.click_btn(tip_xpath, item)
                    time.sleep(1)
                    # 获取价格校验航班价格
                    page_flight_price_xpath = './dd[2]/div/span/span[2]'
                    currency, page_flight_price = self.get_text(
                        page_flight_price_xpath, item).split()
                    if float(page_flight_price
                             ) > self.target_price:  # 页面价格大于目标价格,中断程序
                        logger.info(
                            f"目标价格小于页面价格, 页面价格为:{page_flight_price}, 任务目标价格为:{self.target_price}"
                        )
                        self.fill_back["status"] = 403
                        raise StopException("目标价格小于页面价格")

                    # 回填数据
                    # 。。。。。。

                    # 点击下一步
                    next_step_xpath = '/html/body/div[1]/div[2]/div/div/div[1]/div/div[1]/div[4]/div[3]/div[2]/a'
                    self.click_btn(next_step_xpath)
                    time.sleep(2)

                    # 记录日志
                    logger.debug(f"选择航班结束, 航班号为{page_flight_num}")
                    break
            else:
                self.fill_back["status"] = 402
                logger.debug("没有找到航班")
                raise StopException("没有查询到航班")

        except StopException as e:
            logger.error(f"{e}导致程序中断")
            raise StopException(e)
        except Exception as e:
            logger.error(f"选择航班发生错误,错误提示:{e}")
            raise StopException(e)
Esempio n. 14
0
    def select_luggages(self):
        if sum(self.luggages_weight) > 0:
            # 有乘客携带行李,选择行李
            add_luggage_xpath = '//div[@class="vnl-service-options-box vnl-service-options-box--jp-b baggage"]'
            self.click_btn(add_luggage_xpath)
            passenger_luggage_list_xpath = '//div[@class="vnl-seat-select-box"]/div/div[2]/div/div[2]/div'
            passenger_luggage_list = self.get_ele_list(
                passenger_luggage_list_xpath)

            # 对每个乘客进行行李的点击
            for index, passenger in enumerate(self.passengers):
                # 滑动到可见元素
                self.scroll_screen(passenger_luggage_list[index])
                time.sleep(2)

                if passenger["baggageWeight"] == 0:
                    continue
                # 计算获取对应的重量
                quotient, residue = divmod(passenger["baggageWeight"], 5)
                if residue > 0:
                    quotient += 1
                # 行李重量li标签的索引
                if quotient < 4:
                    select_weight_index = 2
                else:
                    select_weight_index = quotient - 2
                # 51KG一下的
                # 点击选择行李重量
                if select_weight_index < 10:
                    weight_xpath = './div[@class="vnl-baggage-select-box--flight_baggage-one-person"]/div[2]/ol/li[{}]'
                    self.click_btn(
                        xpath=weight_xpath.format(select_weight_index),
                        el=passenger_luggage_list[index])
                else:
                    # 501KG以上的行李选择
                    # 先点击更多
                    more_xpath = './div[@class="vnl-baggage-select-box--flight_baggage-one-person"]/div[2]/ol/li[@class="more"]'
                    # 滑动屏幕
                    # self.scroll_screen()
                    self.click_btn(more_xpath,
                                   el=passenger_luggage_list[index])
                    time.sleep(1)
                    select_weight_index -= 8
                    weight_xpath = './div[@class="vnl-baggage-select-box--flight_baggage-one-person"]/div[2]/ol/li[@class="more"]/div/ul/li[{}]'
                    self.click_btn(
                        xpath=weight_xpath.format(select_weight_index),
                        el=passenger_luggage_list[index])
                pass

            else:
                # 点击完成
                over_xpath = '//a[@ng-click="selectBaggageCtl.close()"]'
                self.click_btn(over_xpath)
                time.sleep(2)

        # 无行李,选择空过
        # 点击下一步
        next_xpath = '//a[@data-id="act-next"]'
        self.click_btn(next_xpath)

        logger.debug("选择行李完毕")
        time.sleep(2)
        # 选择不用了,谢谢
        no_thanks_js = "document.querySelector('body > div.vnl-modal-popup.vnl-modal-popup_wrap > div > div > div > div.vnl-popup_btn > a.no.action_close').click()"
        self.driver.execute_script(no_thanks_js)
Esempio n. 15
0
    def select_flight_info(self):
        """
        选择航班信息出发地,目的地,出发时间,人数,先按照单程票购买
        :return:
        """
        logger.info("输入航班信息")
        # 点击One way,选择单程票
        oneway_btn = '//*[@id="siteContent"]/div[1]/div[3]/div[1]/label[2]'
        self.click_btn(oneway_btn)

        # 选择出发地
        depAir_xpath = '//*[@id="origin"]'
        self.click_btn(xpath=depAir_xpath)
        # 输入查询出发地
        depAir_input_xpath = '//*[@id="siteContent"]/div[3]/div[3]/div/input'
        self.fill_input(self.depAirport,
                        xpath=depAir_input_xpath,
                        single_input=True)
        time.sleep(2)
        # 选择查询到的第一个结果点击选择, 点击第一个会不准确
        result_xpath = '//*[@id="siteContent"]/div[3]/div[4]/ul[2]/li[@data-code="{}"]'.format(
            self.depAirport)
        self.click_btn(xpath=result_xpath)
        logger.debug("输入出发地")

        time.sleep(2)

        # 选择目的地
        arrAir_xpath = '//*[@id="destination"]'
        self.click_btn(xpath=arrAir_xpath)
        # 输入查询目的地
        arrAir_input_xpath = '//*[@id="siteContent"]/div[4]/div[3]/div/input'
        self.fill_input(self.arrAirport,
                        xpath=arrAir_input_xpath,
                        single_input=True)
        time.sleep(2)
        # 准确选择目的地
        result_xpath = '//*[@id="siteContent"]/div[4]/div[4]/ul/li[@data-code="{}"]'.format(
            self.arrAirport)
        self.click_btn(xpath=result_xpath)
        logger.debug("输入目的地")

        # 选择出发日期
        departure_xpath = '//*[@id="departuredate"]'
        self.click_btn(xpath=departure_xpath)
        # //*[@id="datepicker"]/div/div[1]/table/tbody/tr[5]/td[4]/a
        # 尝试点击日期
        year, month, day = self.depDate.split("-")
        # 获取当前月份
        current_month = datetime.now().month
        div_num = str(int(month) - int(current_month) + 1)
        # 选择出发日期
        self.select_date(div_num=div_num, day=day)

        # 点击选择乘客
        passenger_btn = '//*[@id="travellers"]'
        self.click_btn(xpath=passenger_btn)
        # 计算成人,儿童,婴儿的个数
        self.calculation_age(self.passengerVOList)
        # 点击+,选择人数
        adult_xpath = '//*[@id="siteContent"]/div[6]/div[2]/div/div[1]'
        children_xpath = '//*[@id="siteContent"]/div[6]/div[3]/div/div[1]'
        infants_xpath = '//*[@id="incInfant"]'
        all_li = {
            "adult": adult_xpath,
            "children": children_xpath,
            "infants": infants_xpath
        }
        for category in all_li:
            for item in range(getattr(self, category)):
                self.click_btn(xpath=all_li[category])

        # 点击确定
        done_btn = '//*[@id="setTravellerData"]'
        self.click_btn(xpath=done_btn)

        # 信息填写完毕,点击search按钮,查询航班信息
        search_btn = '//*[@id="SearchViewControlGroupFlightSelection_SearchViewFlightSearchControl_ButtonSubmit"]'
        self.click_btn(search_btn)

        logger.info("查询信息填写完毕")
        # 等待查询结果
        time.sleep(5)