1. 程式人生 > >Python實現自動化搶票

Python實現自動化搶票

臨近放假,相信我們每天都在群聊裡或者朋友圈看到一些幫忙搶火車票的資訊。

作為一個在廣東出生長大上小中大學的仔,我搶得最多的只是外賣紅包,火車票倒是從沒搶過。

看到朋友們搶回家的車票這麼辛(bei)苦(can),結合圈裡一些前輩的指點,抱著學習的心態用Python做了一個簡單的自動化搶票程式,搶到票之後通過繫結的郵箱(比如QQ)發通知。下面分享主要內容:

 

 

先自報家門:

    版本號 Python 3.6.5

    編譯器 PyCharm PRO 2018.1

    瀏覽器

 Google Chrome 71.0.3

 

首先,我們用到一個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)

 

最後 ,祝大家都能順利搶到票回家過年。