您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么用Python實現全自動購買火車票”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么用Python實現全自動購買火車票”吧!
這個是實現結果,因為一天只能取消三次,所以最后一步點擊確認被我注釋了。
1.首先實現使用selenium登陸12306
關于使用selenium實現12306登陸可以看我的另一篇文章 這里實現了使用selenium登陸12306,這次是基于上次的代碼進行修改實現全自動購買車票的 實現全自動登陸12306鏈接。
2.根據上面實現登陸后,實現購買火車票還需兩步
這里只進行了二等座的查詢和購票,想要買其他的自己也可以進行修改 1.進行車票的查詢 這里面需要注意的是在輸入目的地和起始地時需要先click一下文本框browser.find_element_by_id(‘fromStationText’).click() 不然輸入的地址無效 還有將日期的只讀屬性去掉。
def search_railway_ticket(fromstation,tostation,train_date): # 火車票頁面查詢url search_url = 'https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc' # 轉到查詢車次頁面 browser.get(search_url) time.sleep(2) #輸入出發地 WebDriverWait(browser, 1000).until( EC.presence_of_element_located((By.ID, 'fromStationText')) ) #先點擊一下 browser.find_element_by_id('fromStationText').click() browser.find_element_by_id('fromStationText').send_keys(fromstation) browser.find_element_by_id('fromStationText').send_keys(Keys.ENTER) time.sleep(1) WebDriverWait(browser, 1000).until( EC.presence_of_element_located((By.ID, 'toStationText')) ) #輸入目的地 browser.find_element_by_id('toStationText').click() browser.find_element_by_id('toStationText').send_keys(tostation) browser.find_element_by_id('toStationText').send_keys(Keys.ENTER) time.sleep(5) #將日期的只讀屬性去掉 js = 'document.getElementById("train_date").removeAttribute("readonly")' browser.execute_script(js) #去掉原本的時間 WebDriverWait(browser, 1000).until( EC.presence_of_element_located((By.ID, 'train_date')) ) browser.find_element_by_id("train_date").clear() #輸入出發時間 browser.find_element_by_id('train_date').send_keys(train_date) # 等待查詢按鈕是否可用 WebDriverWait(browser, 1000).until( EC.element_to_be_clickable((By.ID, 'query_ticket')) ) searBtn = browser.find_element_by_id('query_ticket') searBtn.click() print('點擊按鈕')
2.購買火車票 在這個函數中需要注意的是最好把最后一步注釋掉 browser.find_element_by_id(‘qr_submit_id’).click() 因為一天只能取消3次訂單。
def buy_ticket(fromstation,tostation,train_date,train_number,passenger): #查詢火車票 search_railway_ticket(fromstation,tostation,train_date) time.sleep(5) #獲取每一個車次的信息 tr_list = browser.find_elements_by_xpath('.//tbody[@id="queryLeftTable"]/tr[not(@datatran)]') for tr in tr_list: #獲取車次號 number = tr.find_element_by_class_name('number').text if number in train_number: #獲取是否還有票 left_ticket = tr.find_element_by_xpath('./td[4]').text if left_ticket =='有'or left_ticket.isdigit: print(f'{number}還有票') #點擊預訂 orderBtn = tr.find_element_by_class_name('btn72') orderBtn.click() time.sleep(5) #獲取12306中乘客的信息 passenger_list = browser.find_elements_by_xpath('//*[@id="normal_passenger_id"]/li') for li in passenger_list: name = li.find_element_by_xpath('./label').text print(name) #配對12306人名 if name == passenger: li.find_element_by_tag_name('input').click() #提交訂單 submit = browser.find_element_by_id('submitOrder_id') submit.click() WebDriverWait(browser, 1000).until( EC.element_to_be_clickable((By.ID, 'qr_submit_id')) ) #一天只能取消3次 所以最好把最后一步注釋了 browser.find_element_by_id('qr_submit_id').click() print('已經提交訂單') break
下面是源代碼
測試的時候可以把#click_captcha()這個點擊驗證碼的去掉自己手動點擊,這樣就不用扣超級鷹的積分(有錢的話當我沒說),留下了貧窮的淚水。
from selenium import webdriver from selenium.webdriver import Actionchains import time from PIL import Image import requests from hashlib import md5 from selenium.webdriver import ChromeOptions #驗證碼識別處理 from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class Chaojiying_Client(object): def __init__(self, username, password, soft_id): self.username = username password = password.encode('utf8') self.password = md5(password).hexdigest() self.soft_id = soft_id self.base_params = { 'user': self.username, 'pass2': self.password, 'softid': self.soft_id, } self.headers = { 'Connection': 'Keep-Alive', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', } def PostPic(self, im, codetype): """ im: 圖片字節 codetype: 題目類型 參考 http://www.chaojiying.com/price.html """ params = { 'codetype': codetype, } params.update(self.base_params) files = {'userfile': ('ccc.jpg', im)} r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers) return r.json() def ReportError(self, im_id): """ im_id:報錯題目的圖片ID """ params = { 'id': im_id, } params.update(self.base_params) r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers) return r.json() def login(username,password): # 填寫賬號密碼 browser.find_element_by_id('J-userName').send_keys(username) browser.find_element_by_id('J-password').send_keys(password) # 獲取驗證碼 get_captcha() # 填寫驗證碼 click_captcha() #點擊登錄 time.sleep(4) browser.find_element_by_id('J-login').click() time.sleep(4) #滑動驗證碼 slider() print('成功登陸') time.sleep(5) def slider(): #滑動驗證碼 WebDriverWait(browser, 1000).until( EC.presence_of_element_located((By.XPATH, '//*[@id="nc_1_n1z"]')) ) span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]') # 對div_tag進行滑動操作 action = Actionchains(browser) # 點擊長按指定的標簽 action.click_and_hold(span).perform() action.drag_and_drop_by_offset(span, 400, 0).perform() def click_captcha(): # 獲取驗證碼需要的為點擊位置 chaojiying = Chaojiying_Client('自己的用戶名', '密碼', '軟件id') # 用戶中心>>軟件ID 生成一個替換 96001 im = open('./captcha.png', 'rb').read() # 本地圖片文件路徑 來替換 a.jpg 有時WIN系統須要// location = chaojiying.PostPic(im, 9004)['pic_str'] # 1902 驗證碼類型 官方網站>>價格體系 3.4+版 print 后要加() print(chaojiying.PostPic(im, 9004)) # 將位置進行分割成 [ [ ], [ ], [ ] ]類型 location_list = [i.split(',') for i in location.split('|')] for l in location_list: x = l[0] y = l[1] Actionchains(browser).move_to_element_with_offset(browser.find_element_by_class_name('login-pwd-code'), int(x),int(y)).click().perform() time.sleep(0.5) def get_captcha(): # 獲取網頁的截圖 allscreen = browser.get_screenshot_as_file('allscreen.png') # 獲取captcha captcha = browser.find_element_by_class_name('login-pwd-code') # 獲取captcha的左上角位置 location = captcha.location # 獲取圖片大小 size = captcha.size # 裁取captcha rangle = (location['x'],location['y'],(location['x']+size['width']),(location['y']+size['height'])) i = Image.open('./allscreen.png') captcha_img = './captcha.png' frame = i.crop(rangle) frame.save(captcha_img) def buy_ticket(fromstation,tostation,train_date,train_number,passenger): #查詢火車票 search_railway_ticket(fromstation,tostation,train_date) time.sleep(5) tr_list = browser.find_elements_by_xpath('.//tbody[@id="queryLeftTable"]/tr[not(@datatran)]') for tr in tr_list: number = tr.find_element_by_class_name('number').text if number in train_number: left_ticket = tr.find_element_by_xpath('./td[4]').text if left_ticket =='有'or left_ticket.isdigit: print(f'{number}還有票') orderBtn = tr.find_element_by_class_name('btn72') orderBtn.click() time.sleep(5) passenger_list = browser.find_elements_by_xpath('//*[@id="normal_passenger_id"]/li') for li in passenger_list: name = li.find_element_by_xpath('./label').text if name == passenger: li.find_element_by_tag_name('input').click() submit = browser.find_element_by_id('submitOrder_id') submit.click() WebDriverWait(browser, 1000).until( EC.element_to_be_clickable((By.ID, 'qr_submit_id')) ) #一天只能取消3次 所以把最后一步注釋了 # browser.find_element_by_id('qr_submit_id').click() print('已經提交訂單') break def search_railway_ticket(fromstation,tostation,train_date): # 火車票頁面查詢url search_url = 'https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc' # 轉到查詢車次頁面 browser.get(search_url) time.sleep(2) #輸入出發地 WebDriverWait(browser, 1000).until( EC.presence_of_element_located((By.ID, 'fromStationText')) ) #先點擊一下 browser.find_element_by_id('fromStationText').click() browser.find_element_by_id('fromStationText').send_keys(fromstation) browser.find_element_by_id('fromStationText').send_keys(Keys.ENTER) time.sleep(1) WebDriverWait(browser, 1000).until( EC.presence_of_element_located((By.ID, 'toStationText')) ) #輸入目的地 browser.find_element_by_id('toStationText').click() browser.find_element_by_id('toStationText').send_keys(tostation) browser.find_element_by_id('toStationText').send_keys(Keys.ENTER) time.sleep(5) #將日期的只讀屬性去掉 js = 'document.getElementById("train_date").removeAttribute("readonly")' browser.execute_script(js) #去掉原本的時間 WebDriverWait(browser, 1000).until( EC.presence_of_element_located((By.ID, 'train_date')) ) browser.find_element_by_id("train_date").clear() #輸入出發時間 browser.find_element_by_id('train_date').send_keys(train_date) # 等待查詢按鈕是否可用 WebDriverWait(browser, 1000).until( EC.element_to_be_clickable((By.ID, 'query_ticket')) ) searBtn = browser.find_element_by_id('query_ticket') searBtn.click() print('點擊按鈕') if __name__ == '__main__': option = ChromeOptions() # 實例化一個ChromeOptions對象 option.add_experimental_option('excludeSwitches', ['enable-automation']) # 以鍵值對的形式加入參數 option.add_experimental_option('useAutomationExtension', False) browser = webdriver.Chrome(options=option) # 獲取響應 browser.get('https://kyfw.12306.cn/otn/resources/login.html') script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});' browser.execute_script(script) browser.maximize_window() time.sleep(1) # 點擊賬號登陸 browser.find_element_by_class_name('login-hd-account').click() #登陸12306的賬號密碼 login('用戶名','密碼') time.sleep(4) #例buy_ticket('南昌','撫州北','2020-12-15','D2241','xx') buy_ticket('起始地','目的地','出發日期','車次','姓名')
感謝各位的閱讀,以上就是“怎么用Python實現全自動購買火車票”的內容了,經過本文的學習后,相信大家對怎么用Python實現全自動購買火車票這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。