2019獨角獸企業重金招聘Python工程師標準>>>
又是一年,馬上就要回家過年了,還沒有買到票的小伙伴們是否已經像熱鍋上的螞蟻了無腦的開始找黃牛了?
俗話說的好,求人不如求自己,搶票這玩意,其實我覺得我也可以~
來來來,直接入正題吧! 這里有兩種方案,一種是基于Selenium2的自動化框架控制瀏覽器實現,另一種方案則是基于Python自身的爬蟲package如request,urllib等來實現,本文實現第一種方案,第二種方案也在摸索中。
實現過程
一、新版12306官網主要頁面網址
https://kyfw.12306.cn/otn/resources/login.html
https://kyfw.12306.cn/otn/view/index.html
https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc
二、瀏覽器驅動信息
這里使用的是chrome瀏覽器
在此處下載
https://sites.google.com/a/chromium.org/chromedriver/downloads
三、初始化必要信息
買票必要信息,比如乘車人,來往車站,車次類型等等
# 乘客姓名
passengers_input = 'xxx'
passengers = passengers_input.split(",")#乘車日期,格式為2019-01-10
from_time = '2019-01-31'# 城市cookie字典
city_list = {'sz':'%u6DF1%u5733%2CSZQ', #深圳'zz':'%u90D1%u5DDE%2CZZF', #鄭州'gz':'%u5E7F%u5DDE%2CGZQ', #廣州
}
# 出發站
from_station = '%u5E7F%u5DDE%2CGZQ'# 終點站
to_station = '%u90D1%u5DDE%2CZZF'# 車次編號
numbers = ['Z90','Z190','Z14','Z168','Z98','T124','T370']# 座位類型
seat_type = '硬臥'#通知郵件
receiver_email = 'xxxxxxxxx@163.com'
注意:城市字典是將城市簡寫和城市代碼之間聯系起來。如果沒有你想要到城市,可以在打開12306的查票頁面,然后打開瀏覽器的開發者模式,輸入對應的城市,然后查看請求信息。
四、登錄功能實現
登錄我們需要手動登錄,掃碼或者輸入賬號都可以。登錄后記錄session,供后面搶票使用
def do_login(self):"""登錄功能實現,手動識別驗證碼進行登錄"""self.driver.visit(self.login_url)sleep(1)# 選擇登陸方式登陸print('請掃碼登陸或者賬號登陸……')while True:if self.driver.url != self.init_my_url:sleep(1)else:break
五、搶票功能實現
核心功能實現,通過掃描關鍵字來確認是否有余票,然后實現點擊頁面,進而走向下一步。
current_tr = self.driver.find_by_xpath('//tr[@datatran="' + number + '"]/preceding-sibling::tr[1]')
if current_tr:if current_tr.find_by_tag('td')[self.seat_type_index].text == '--':print('無此座位類型出售,已結束當前刷票,請重新開啟!')sys.exit(1)else:# 有票,嘗試預訂print('刷到票了(余票數:' + str(current_tr.find_by_tag('td')[self.seat_type_index].text) + '),開始嘗試預訂……')current_tr.find_by_css('td.no-br>a')[0].click()sleep(1)key_value = 1for p in self.passengers:# 選擇用戶print('開始選擇用戶……')self.driver.find_by_text(p).last.click()# 選擇座位類型print('開始選擇席別……')if self.seat_type_value != 0:self.driver.find_by_xpath("//select[@id='seatType_" + str(key_value) + "']/option[@value='" + str(self.seat_type_value) + "']").first.click()key_value += 1sleep(0.2)if p[-1] == ')':self.driver.find_by_id('dialog_xsertcj_ok').click()print('正在提交訂單……')self.driver.find_by_id('submitOrder_id').click()sleep(2)print('正在確認訂單……')self.driver.find_by_id('qr_submit_id').click()
六、搶票成功后郵件通知自己
一個很簡單的功能,不過卻是必要的,避免自己錯過!
def send_mail(self, receiver_address, content):"""發送郵件通知"""# 連接郵箱服務器信息host = 'xxxx.163.com'port = 25sender = 'xxxxxx@163.com' # 你的發件郵箱號碼pwd = 'xxxxx' # 第三方授權登錄嗎,不是登錄密碼!!# 發件信息receiver = receiver_addressbody = '<h2>溫馨提醒:</h2><p>' + content + '</p>'msg = MIMEText(body, 'html', _charset="utf-8")msg['subject'] = '搶票成功通知!'msg['from'] = sendermsg['to'] = receivers = smtplib.SMTP(host, port)# 開始登陸郵箱,并發送郵件s.login(sender, pwd)s.sendmail(sender, receiver, msg.as_string())
過程演示
- 執行代碼
- 登錄12306網站
- 搶票成功
- 等待支付
- 郵件通知
總結:
總的來說是成功的,但還不是完全自動化的。不過相比手動搶票還是快很多的。其實網上這種代碼很多,只不過因為12306網站的更新大多數不能用了,我也是在前輩們的基礎上修改完成的。想要最新源碼的同學可以關注的我公眾號,回復搶票源碼!