Python實現自動化搶票
阿新 • • 發佈:2019-01-07
臨近放假,相信我們每天都在群聊裡或者朋友圈看到一些幫忙搶火車票的資訊。
Google Chrome 71.0.3
else:
作為一個在廣東出生長大上小中大學的仔,我搶得最多的只是外賣紅包,火車票倒是從沒搶過。
看到朋友們搶回家的車票這麼辛(bei)苦(can),結合圈裡一些前輩的指點,抱著學習的心態用Python做了一個簡單的自動化搶票程式,搶到票之後通過繫結的郵箱(比如QQ)發通知。下面分享主要內容:
先自報家門:
版本號 Python 3.6.5
編譯器 PyCharm PRO 2018.1
瀏覽器
首先,我們用到一個Splinter庫:
相信做自動化測試、自動化爬蟲的朋友都知道Selenium工具,它可以把人為驅動行為轉化為機器執行,Splinter的藥效跟它是一樣的。我們可以進去cmd後用 pip install splinter
這個命令來安裝。
然後 ,開始使勁地碼:
1. 定義自動購票的類(初始化屬性)
class Buy_Tickets(object): # 定義例項屬性,初始化 def __init__(self, username, passwd, order, passengers, dtime, starts, ends): self.username = username self.passwd = passwd self.order = order # 車次,0代表所有車次 self.passengers = passengers # 乘客名 self.starts = starts # 起始地和終點 self.ends = ends self.dtime = dtime # 日期 self.login_url = 'https://kyfw.12306.cn/otn/login/init' self.initMy_url = 'https://kyfw.12306.cn/otn/view/index.html' self.ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init' self.driver_name = 'chrome' self.executable_path = 'C:\python\chromedriver.exe'
2. 實現登入功能
def login(self):
self.driver.visit(self.login_url) self.driver.fill('loginUserDTO.user_name', self.username) # sleep(1) self.driver.fill('userDTO.password', self.passwd) # sleep(1) print('請輸入驗證碼...') while True: if self.driver.url != self.initMy_url: sleep(1) else: break
3. 實現購票功能
def start_buy(self):
self.driver = Browser(driver_name=self.driver_name, executable_path=self.executable_path) # 視窗大小的操作 self.driver.driver.set_window_size(1200, 700) self.login() self.driver.visit(self.ticket_url) try: print('開始購票...') # 載入查詢資訊 self.driver.cookies.add({"_jc_save_fromStation": self.starts}) self.driver.cookies.add({"_jc_save_toStation": self.ends}) self.driver.cookies.add({"_jc_save_fromDate": self.dtime}) self.driver.reload() count = 0 if self.order != 0: while self.driver.url == self.ticket_url: self.driver.find_by_text('查詢').click() count += 1 print('第%d次點選查詢...' % count) try: self.driver.find_by_text('預訂')[self.order - 1].click() sleep(1.5) except Exception as e: print(e) print('預訂失敗...') continue
4. 郵箱通知付款
def sendMail(self, mail_title, mail_content):
my_sender = '[email protected]' # 發件人郵箱賬號 my_user = '[email protected]' # 收件人郵箱賬號 try: '''傳送郵件''' msg = MIMEText(mail_content, "plain", 'utf-8') # 傳送郵件內容 msg["Subject"] = Header(mail_title, 'utf-8') # 傳送郵件主題/標題 msg["From"] = formataddr(['Bruce pk', my_sender]) # 郵件傳送方 msg["To"] = formataddr(['brucepk', my_user]) # 郵件接收方 s = smtplib.SMTP("smtp.qq.com", 25) # 郵箱的傳輸協議,埠預設25 s.login(my_sender, 'xxxxx') # 登入郵箱,這裡的第二個引數為qq郵箱授權碼,不要填你的登入密碼 s.sendmail(my_sender, [my_user, ], msg.as_string()) # 傳送方,接收方,傳送訊息 s.quit() # 退出郵箱 print("搶票通知郵件傳送成功!") except Exception: print("郵件傳送失敗~~")
還有,網路不好或者12306的伺服器不穩定的時候,就會卡住,針對這種情況,系統會重複查詢:
else:
while self.driver.url == self.ticket_url: self.driver.find_by_text('查詢').click() count += 1 print('第%d次點選查詢...' % count) try: for i in self.driver.find_by_text('預訂'): i.click() sleep(1) except Exception as e: print(e) print('預訂失敗...') continue print('開始預訂...') sleep(1) print('開始選擇使用者...') for p in self.passengers: self.driver.find_by_text(p).last.click() sleep(0.5) if p[-1] == ')': self.driver.find_by_id('dialog_xsertcj_ok').click() sleep(3) print('提交訂單...') self.driver.find_by_id('submitOrder_id').click() sleep(5) print('確認選座...') self.driver.find_by_id('qr_submit_id').click() print('預訂成功...') sleep(5) self.sendMail(mail_title, mail_content) except Exception as e: print(e)
最後 ,祝大家都能順利搶到票回家過年。