|  | 
|  | 1 | +from selenium import webdriver | 
|  | 2 | +from selenium.webdriver.support.ui import WebDriverWait | 
|  | 3 | +from selenium.webdriver.support import expected_conditions as EC | 
|  | 4 | +from selenium.webdriver.common.by import By | 
|  | 5 | +import time,base64 | 
|  | 6 | +import chaojiying | 
|  | 7 | +from selenium.webdriver import ActionChains | 
|  | 8 | +from selenium.webdriver.support.ui import WebDriverWait, Select | 
|  | 9 | + | 
|  | 10 | +class Ticket(object): | 
|  | 11 | + | 
|  | 12 | +    def __init__(self, username, password): | 
|  | 13 | +        self.username = username | 
|  | 14 | +        self.password = password | 
|  | 15 | +        self.login_url = 'https://kyfw.12306.cn/otn/resources/login.html' | 
|  | 16 | +         | 
|  | 17 | + | 
|  | 18 | +     | 
|  | 19 | +    def findElement(self, type, id): | 
|  | 20 | +        # 查找元素 | 
|  | 21 | +        return EC.visibility_of_element_located((type, id)) | 
|  | 22 | + | 
|  | 23 | +    def login(self): | 
|  | 24 | +        self.driver = webdriver.Chrome(executable_path='D:\chromedriver.exe') | 
|  | 25 | + | 
|  | 26 | +        with open('D:\stealth.min.js') as f: | 
|  | 27 | +            stealth = f.read() | 
|  | 28 | +        self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {"source": stealth}) | 
|  | 29 | + | 
|  | 30 | +        self.wait = WebDriverWait(self.driver, 10, 0.1) | 
|  | 31 | +        self.driver.get(self.login_url) | 
|  | 32 | +         | 
|  | 33 | +        self.wait.until(self.findElement(By.LINK_TEXT,'账号登录')).click() | 
|  | 34 | + | 
|  | 35 | +        self.wait.until(self.findElement(By.ID, 'J-userName')).send_keys(self.username) | 
|  | 36 | +         | 
|  | 37 | +        self.wait.until(self.findElement(By.ID, 'J-password')).send_keys(self.password) | 
|  | 38 | + | 
|  | 39 | +        time.sleep(20) | 
|  | 40 | + | 
|  | 41 | +        success_flag = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'lgcode-success'))).get_attribute('style') | 
|  | 42 | +        while success_flag == 'display: none;': | 
|  | 43 | +            img = self.wait.until(EC.visibility_of_element_located((By.ID, 'J-loginImg'))) | 
|  | 44 | + | 
|  | 45 | +            base64Img = img.get_attribute('src') | 
|  | 46 | +            base64Img = base64Img.replace('data:image/jpg;base64,', '') | 
|  | 47 | +            imgdata=base64.urlsafe_b64decode(base64Img) | 
|  | 48 | +            file=open('1.jpg','wb') | 
|  | 49 | +            file.write(imgdata) | 
|  | 50 | +            file.close() | 
|  | 51 | + | 
|  | 52 | +            cj = chaojiying.Chaojiying_Client('用户名', '密码', '软件ID') | 
|  | 53 | +            im = open('1.jpg', 'rb').read() | 
|  | 54 | +            cjy_result = cj.PostPic(im, 9004) | 
|  | 55 | +            print(cjy_result)											 | 
|  | 56 | +            x_y = cjy_result['pic_str'] | 
|  | 57 | +            pic_id = cjy_result['pic_id'] | 
|  | 58 | + | 
|  | 59 | +            all_list = [] | 
|  | 60 | +            for i in x_y.split('|'): | 
|  | 61 | +                all_list.append([int(i.split(',')[0]), int(i.split(',')[1])]) | 
|  | 62 | + | 
|  | 63 | +            for rangle in all_list: | 
|  | 64 | +                ActionChains(self.driver).move_to_element_with_offset(img, rangle[0], rangle[1]).click().perform() | 
|  | 65 | + | 
|  | 66 | +            self.wait.until(self.findElement(By.ID, 'J-login')).click() | 
|  | 67 | +            success_flag = self.driver.find_element_by_class_name('lgcode-success').get_attribute('style') | 
|  | 68 | + | 
|  | 69 | +            if success_flag == 'display: none;': | 
|  | 70 | +                cj.ReportError(pic_id) | 
|  | 71 | + | 
|  | 72 | +        nc_1_n1z = self.wait.until(self.findElement(By.ID, 'nc_1_n1z')) | 
|  | 73 | +        tracks = [6,16,31,52,72,52,62,50] | 
|  | 74 | +     | 
|  | 75 | +        action = ActionChains(self.driver) | 
|  | 76 | +     | 
|  | 77 | +        action.click_and_hold(nc_1_n1z).perform() | 
|  | 78 | +        for track in tracks: | 
|  | 79 | +            action.move_by_offset(track, 0) | 
|  | 80 | +        time.sleep(0.5) | 
|  | 81 | +        action.release().perform() | 
|  | 82 | + | 
|  | 83 | +    def buy(self):     | 
|  | 84 | +        ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init' | 
|  | 85 | +        self.driver.get(ticket_url) | 
|  | 86 | +        time.sleep(2) | 
|  | 87 | + | 
|  | 88 | +        self.driver.add_cookie({'name': '_jc_save_fromStation', 'value': '%u5E38%u5DDE%2CCZH'}) #常州 | 
|  | 89 | +        self.driver.add_cookie({'name': '_jc_save_toStation', 'value': '%u4E0A%u6D77%2CSHH'}) #上海 | 
|  | 90 | +        self.driver.add_cookie({'name': '_jc_save_fromDate', 'value': '2021-08-02'}) | 
|  | 91 | +        self.driver.refresh() | 
|  | 92 | +        # 一个温馨提示弹窗 | 
|  | 93 | +        self.wait.until(self.findElement(By.LINK_TEXT, '确认')).click() | 
|  | 94 | +         | 
|  | 95 | +        # 是否进入预订页面 | 
|  | 96 | +        while self.driver.current_url == ticket_url: | 
|  | 97 | +            self.wait.until(self.findElement(By.LINK_TEXT, '查询')).click() | 
|  | 98 | +            time.sleep(2) | 
|  | 99 | +            try: | 
|  | 100 | +                a = self.driver.find_element_by_xpath("//tr[@datatran='K1805']/preceding-sibling::tr[1]/child::node()[last()]/a") | 
|  | 101 | +                if a.text == '预订': | 
|  | 102 | +                    a.click() | 
|  | 103 | +                    break | 
|  | 104 | +            except Exception as e: | 
|  | 105 | +                print("没有车次") | 
|  | 106 | +            | 
|  | 107 | +             | 
|  | 108 | +        passengers = ['xxxx'] | 
|  | 109 | +        ticketType = ['成人票'] | 
|  | 110 | +        seatType = ['硬座(¥28.5)'] | 
|  | 111 | +        for index, p in enumerate(passengers, 1): | 
|  | 112 | +            self.driver.find_element_by_xpath("//label[text()='"+p+"']/preceding-sibling::input[1]").click() | 
|  | 113 | +            | 
|  | 114 | +             | 
|  | 115 | +            selectTicketType = Select(self.driver.find_element_by_id('ticketType_' + str(index))) | 
|  | 116 | +            selectTicketType.select_by_visible_text(ticketType[index - 1]) | 
|  | 117 | +             | 
|  | 118 | +            selectSeatType = Select(self.driver.find_element_by_id('seatType_' + str(index))) | 
|  | 119 | +            selectSeatType.select_by_visible_text(seatType[index - 1]) | 
|  | 120 | +             | 
|  | 121 | +            self.driver.find_element_by_id('submitOrder_id').click() | 
|  | 122 | +             | 
|  | 123 | +            self.driver.find_element_by_id('qr_submit_id').click() | 
|  | 124 | + | 
|  | 125 | + | 
|  | 126 | +if __name__ == '__main__': | 
|  | 127 | +    username = 'xxxx' | 
|  | 128 | +    password = 'xxxxxxx' | 
|  | 129 | + | 
|  | 130 | +    ticket = Ticket(username, password) | 
|  | 131 | +    ticket.login() | 
|  | 132 | +    ticket.buy() | 
|  | 133 | + | 
0 commit comments