示例#1
0
def show_alert_info(text=None, split='  '):
    """
    @param text 添加到打印信息头部
    @param split 打印信息分隔符
    打印通知警告信息
    """
    print_info = []
    if text:
        print_info.append(text)

    # 对话框
    check_el = browser.find_el_if_exist('content_checkticketinfo_id', by=By.ID)
    if check_el and check_el.is_displayed():
        check_text = check_el.find_element_by_id('sy_ticket_num_id').text
        console.print(check_text, style="bold red")
    # 提示框
    notice_el = browser.find_el_if_exist('content_transforNotice_id', by=By.ID)
    if notice_el and notice_el.is_displayed():
        el = browser.find_el_if_exist('#orderResultInfo_id > div > span')
        if el:
            print_info.append(f'[red]{el.text}[/red]')
        el = find_el_if_exist(notice_el, 'p', by=By.TAG_NAME)
        if el:
            print_info.append(el.text)
    console.print(split.join(print_info))
示例#2
0
def check_alert():
    alert_el = browser.find_el_if_exist('content_defaultwarningAlert_id',
                                        by=By.ID)
    if alert_el and alert_el.is_enabled():
        btn = browser.find_el_if_exist('qd_closeDefaultWarningWindowDialog_id',
                                       by=By.ID)
        if btn and btn.is_enabled():
            btn.click()
示例#3
0
    def _try_submit(self, index, left_tr, train_name):
        """
        尝试提交
        :param index: 表格索引
        :param left_tr: 列车信息行
        :param train_name: 列车车次名称
        """
        left_tr_id = left_tr.get_attribute('id')
        submit_btn = browser.find_el_if_exist('#' + left_tr_id +
                                              ' > td.no-br > a')
        if submit_btn:
            ss, es, st, et, du = _get_train_info(index)
            if str.startswith(left_tr_id, 'ticket_'):
                serial_num = left_tr_id[len('ticket_'):].split('_')[0]
                # 座位类型是否匹配
                for seat_type in config.seat_types:
                    if seat_type_dict[seat_type]:
                        seat_selector = '#' + seat_type_dict[
                            seat_type] + '_' + serial_num
                        seat = left_tr.find_element_by_css_selector(
                            seat_selector)
                        if seat:
                            ticket_info = {
                                "address": f"{ss} - {es}",
                                "time": f"{st} - {et}",
                                "duration": du,
                                'train': train_name
                            }

                            # 判断是否有余票,如果有余票就尝试提交
                            def try_submit(seat_el):
                                if seat_el.text and seat_el.text is not '无' \
                                        and seat_el.text is not '--':
                                    self._running = False
                                    ticket_info['seat_type'] = seat_type
                                    ticket_info['value'] = seat_el.text
                                    self._ticket_info = ticket_info
                                    console.print(
                                        _table_ticket_info(ticket_info))
                                    submit_btn.click()
                                    return True
                                return False

                            seat_div = browser.find_el_if_exist(seat_selector +
                                                                ' > div')
                            if try_submit(seat_div if seat_div else seat):
                                return True
                    console.print(
                        f":vampire: {config.from_time} - {train_name} - {seat_type}",
                        "[red]暂无余票[/red]")
        else:
            console.print(f":vampire: {config.from_time} - {train_name}",
                          "[red]暂无余票[/red]")
        return False
示例#4
0
def has_login():
    """
    判断用户是否登录
    """
    url = browser.current_url
    if url.startswith(index_page):
        return browser.find_el_if_exist(
            '#J-header-logout > a.logout') is not None
    if url.startswith(ticket_url):
        return browser.find_el_if_exist(
            '#J-header-logout > a:nth-child(3)') is not None
    return False
示例#5
0
def _get_train_info(index):
    """
    获取列车信息
    :param index: 表格索引
    """
    train_num_id = '#train_num_' + str(index)
    cds = train_num_id + ' > div.cds'
    cdz = train_num_id + ' > div.cdz'
    ss = browser.find_el_if_exist(cdz + ' > strong.start-s').text
    es = browser.find_el_if_exist(cdz + ' > strong.end-s').text
    st = browser.find_el_if_exist(cds + ' > strong.start-t').text
    et = browser.find_el_if_exist(cds + ' > strong.color999').text
    du = browser.find_el_if_exist(train_num_id + '> div.ls > strong').text
    return ss, es, st, et, du
示例#6
0
def _init():
    # 跳转到登录页
    browser.get(login_page)
    time.sleep(1)
    if browser.find_el_if_exist('ERROR', by=By.ID) is not None:
        console.print('[red]12306请求过于频繁,请稍等重试 . . . [/red]')
        browser.wait_unblock()
    # 等待用户密码登录按钮可以点击,切换到用户密码登录 Tab
    wait.WebDriverWait(browser, 5).until(
        ec.element_to_be_clickable(
            (By.CLASS_NAME, 'login-hd-account'))).click()
    time.sleep(1)
示例#7
0
 def _create_order(self):
     """
     创建订单
     """
     time.sleep(0.5)
     passenger_list = browser.find_els_if_exist('#normal_passenger_id > li')
     # 选择乘坐人
     passenger_index = 1
     self._ticket_info['passengers'] = []
     for passenger in config.passengers:
         for passenger_li in passenger_list:
             passenger_input = passenger_li.find_element_by_tag_name(
                 'input')
             if passenger_li.find_element_by_tag_name(
                     'label').text == passenger:
                 console.print(f"选择乘坐人 [{passenger}] . . .")
                 self._ticket_info['passengers'].append(passenger)
                 passenger_input.click()
                 warning_alert = browser.find_el_if_exist(
                     'content_defaultwarningAlert_id', by=By.ID)
                 if warning_alert:
                     warning_alert.find_element_by_id(
                         'qd_closeDefaultWarningWindowDialog_id').click()
                     time.sleep(0.5)
                 # 选择席座
                 console.print(
                     f"开始选择席座 [{self._ticket_info['seat_type']}] . . .")
                 seat_select = browser.find_element_by_id(
                     f"seatType_{str(passenger_index)}")
                 _, seat_type_value = _get_seat_type_index_value(
                     self._ticket_info['seat_type'])
                 if seat_type_value != 0:
                     Select(seat_select).select_by_value(
                         str(seat_type_value))
                 passenger_index += 1
                 time.sleep(0.5)
     if passenger_index == 1:
         console.print("未找到乘客信息 ... 提交订单失败", style="bold red")
     print('正在提交订单 . . .')
     wait.WebDriverWait(browser, 5).until(
         ec.element_to_be_clickable((By.ID, 'submitOrder_id'))).click()
     print('正在确认订单 . . .')
     wait.WebDriverWait(browser, 5).until(
         ec.element_to_be_clickable((By.ID, 'qr_submit_id'))).click()
     # 截取屏幕,订单信息页
     print('预订成功,正在截取屏幕 . . .')
     time.sleep(5)
     browser.screenshot(
         f'{self.fs}_{self.ts}_{config.from_time.replace("-", "")}_{self._ticket_info["train"].lower()}.png'
     )
     time.sleep(60)
示例#8
0
def slider_captcha():
    try_time = 1
    div = browser.find_el_if_exist('nc_1_n1z', by=By.ID)
    while div and div.is_displayed():
        if try_time > 10:
            console.print('滑块验证码验证失败 . . .', style='bold red')
            sys.exit(-1)
        # 动作链
        action = ActionChains(browser)
        # 点击长按指定的标签
        action.click_and_hold(div)
        # 处理滑动模块
        for i in range(5):
            # perform()立即执行动作链操作
            # move_by_offset(x,y):x水平方向 y竖直方向
            try:
                action.move_by_offset(350, 0).perform()  # 速度为30mm
            except WebDriverException:
                time.sleep(0.5)
        time.sleep(0.5)
        action.release()
        try_time += 1
        div = browser.find_el_if_exist('nc_1_n1z', by=By.ID)
示例#9
0
 def _try_submit(self, train_trs):
     """
     尝试提交
     :param train_trs: 列车车次名称
     """
     for train_tr in train_trs:
         submit_btn = find_el_if_exist(train_tr, 'td.no-br > a')
         ss, es, st, et, du, tn = tk.get_train_info(train_tr)
         if submit_btn and submit_btn:
             left_tr_id = train_tr.get_attribute('id')
             serial_num = left_tr_id[len('ticket_'):].split('_')[0]
             # 座位类型是否匹配
             for seat_type in config.seat_types:
                 if tk.seat_type_dict[seat_type]:
                     seat_type_id = tk.seat_type_dict[seat_type][
                         "code"] + '_' + serial_num
                     seat = train_tr.find_element_by_id(seat_type_id)
                     if seat:
                         ticket_info = {
                             "address": f"{ss} - {es}",
                             "time": f"{st} - {et}",
                             "duration": du,
                             'train': tn
                         }
                         # 判断是否有余票,如果有余票就尝试提交
                         seat_text = seat.text
                         if seat_text == '有' or re.match(
                                 "^\\d+$", seat_text):
                             self._running = False
                             ticket_info['seat_type'] = seat_type
                             ticket_info['value'] = seat_text
                             self._ticket_info = ticket_info
                             console.print(
                                 tk.table_ticket_info(ticket_info))
                             submit_btn.click()
                             return True
                     else:
                         console.print(f"未找到坐席类型 :[red] {seat_type} [/red]")
                         console.print("请按照要求配置坐席类型:",
                                       ",".join(tk.seat_type_dict.keys()))
                         sys.exit(-1)
                 console.print(
                     f":vampire: {config.from_time} - {tn} - {seat_type}",
                     "[red]暂无余票[/red]")
         else:
             console.print(f":vampire: {config.from_time} - {tn}",
                           "[red]暂无余票[/red]")
     return False
示例#10
0
 def _create_order(self):
     """
     创建订单
     """
     time.sleep(1)
     passenger_list = browser.find_els_if_exist('#normal_passenger_id > li')
     # 选择乘坐人
     passenger_index = 1
     self._ticket_info['passengers'] = []
     # 检查余票数量
     ticket_value = self._ticket_info['value']
     surplus_ticket_number = int(
         ticket_value) if ticket_value != '有' else 9999
     for passenger in config.passengers[:surplus_ticket_number]:
         for passenger_li in passenger_list:
             passenger_input = passenger_li.find_element_by_tag_name(
                 'input')
             if passenger_li.find_element_by_tag_name(
                     'label').text == passenger:
                 console.print(f"选择乘坐人 [{passenger}] . . .")
                 self._ticket_info['passengers'].append(passenger)
                 passenger_input.click()
                 warning_alert = browser.find_el_if_exist(
                     'content_defaultwarningAlert_id', by=By.ID)
                 if warning_alert:
                     warning_alert.find_element_by_id(
                         'qd_closeDefaultWarningWindowDialog_id').click()
                     time.sleep(0.5)
                 # 选择席座
                 console.print(
                     f"开始选择席座 [{self._ticket_info['seat_type']}] . . .")
                 seat_select = browser.find_element_by_id(
                     f"seatType_{str(passenger_index)}")
                 seat_type = tk.seat_type_dict[
                     self._ticket_info['seat_type']]
                 if not seat_type:
                     console.print(f"未找到坐席类型 :[red] {seat_type} [/red]")
                     sys.exit(-1)
                 seat_type_value = seat_type['value']
                 if seat_type_value != '0':
                     Select(seat_select).select_by_value(seat_type_value)
                 passenger_index += 1
                 time.sleep(0.5)
     if passenger_index == 1:
         console.print("未找到乘客信息 ... 无法选择乘客和坐席", style="bold red")
     try:
         print('正在提交订单 . . .')
         wait.WebDriverWait(browser, 10).until(
             ec.element_to_be_clickable((By.ID, 'submitOrder_id'))).click()
         time.sleep(1)
         # 确认提交订单
         print('正在确认订单 . . .')
         wait.WebDriverWait(browser, 10).until(
             ec.element_to_be_clickable((By.ID, 'qr_submit_id'))).click()
         # 等待跳转到支付页面, 如果超时未跳转, 说明订单生成失败
         wait.WebDriverWait(browser, 10).until(
             lambda driver: driver.current_url.startswith(pay_order_url))
         submit_btn = browser.find_el_if_exist('qr_submit_id', by=By.ID)
         if not submit_btn or not submit_btn.is_displayed():
             console.print(f'该车次无法提交[{self._ticket_info["train"]}]。',
                           style="bold yellow")
             config.trains.remove(self._ticket_info["train"])
             show_alert_info('该车次无法提交[{self._ticket_info["train"]}]。', '\n')
             return False
     except WebDriverException as e:
         browser.screenshot(
             f'{datetime.now().strftime(datetime_format_str)}-error.png')
         show_alert_info('提交订单失败:\n')
         raise e
     # 截取屏幕,订单信息页
     print('预订成功,正在截取屏幕 . . .')
     browser.screenshot(
         f'{self.fs}_{self.ts}_{config.from_time.replace("-", "")}_{self._ticket_info["train"].lower()}.png'
     )
     return True