python写12306抢票

  1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 '''
  4 利用splinter写的一个手动过验证及自动抢票的例子,
  5 大家可以自己扩展或者弄错窗体、web端。
  6 本例子只做参考。
  7 本代码发布于2018.12.18(如果报错请查看官网是否改动)
  8 '''
  9 import re
 10 from splinter.browser import Browser
 11 from time import sleep
 12 import sys
 13 import httplib2
 14 from urllib import parse
 15 import smtplib
 16 from email.mime.text import MIMEText
 17 
 18 
 19 class BrushTicket(object):
 20     """买票类及实现方法"""
 21 
 22     def __init__(self,train_date, user_name, password, passengers, from_time, from_station, to_station,  seat_type, receiver_mobile, receiver_email,isHave=False,):
 23         """定义实例属性,初始化"""
 24         # 有票就行
 25         self.isHave = isHave
 26         # 1206账号密码
 27         self.user_name = user_name
 28         self.password = password
 29         # 乘客姓名
 30         self.passengers = passengers
 31         # 起始站和终点站
 32         self.from_station = from_station
 33         self.to_station = to_station
 34         # 乘车日期
 35         self.from_time = from_time
 36         #发车时间
 37         self.train_date=train_date
 38         # 座位类型所在td位置
 39         if seat_type == '商务座特等座':
 40             seat_type_index = 1
 41             seat_type_value = 9
 42         elif seat_type == '一等座':
 43             seat_type_index = 2
 44             seat_type_value = 'M'
 45         elif seat_type == '二等座':
 46             seat_type_index = 3
 47             seat_type_value = 0
 48         elif seat_type == '高级软卧':
 49             seat_type_index = 4
 50             seat_type_value = 6
 51         elif seat_type == '软卧':
 52             seat_type_index = 5
 53             seat_type_value = 4
 54         elif seat_type == '动卧':
 55             seat_type_index = 6
 56             seat_type_value = 'F'
 57         elif seat_type == '硬卧':
 58             seat_type_index = 7
 59             seat_type_value = 3
 60         elif seat_type == '软座':
 61             seat_type_index = 8
 62             seat_type_value = 2
 63         elif seat_type == '硬座':
 64             seat_type_index = 9
 65             seat_type_value = 1
 66         elif seat_type == '无座':
 67             seat_type_index = 10
 68             seat_type_value = 1
 69         elif seat_type == '其他':
 70             seat_type_index = 11
 71             seat_type_value = 1
 72         else:
 73             seat_type_index = 7
 74             seat_type_value = 3
 75         self.seat_type_index = seat_type_index
 76         self.seat_type_value = seat_type_value
 77         # 通知信息
 78         self.receiver_mobile = receiver_mobile
 79         self.receiver_email = receiver_email
 80         # 主要页面网址
 81         self.login_url = 'https://kyfw.12306.cn/otn/login/init'
 82         self.init_my_url = 'https://kyfw.12306.cn/otn/view/index.html'
 83         self.ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
 84         # 浏览器驱动信息,驱动下载页:https://sites.google.com/a/chromium.org/chromedriver/downloads
 85         self.driver_name = 'chrome'
 86         #驱动的位置
 87         self.executable_path = 'C:/Program Files (x86)/Google/Chrome/Application/chromedriver.exe'
 88 
 89     def do_login(self):
 90         """登录功能实现,手动识别验证码进行登录"""
 91         self.driver.visit(self.login_url)
 92         sleep(1)
 93         self.driver.fill('loginUserDTO.user_name', self.user_name)
 94         self.driver.fill('userDTO.password', self.password)
 95         print('请输入验证码……')
 96         while True:
 97             if self.driver.url != self.init_my_url:
 98                 sleep(1)
 99             else:
100                 break
101 
102     def start_brush(self):
103         """买票功能实现"""
104         self.driver = Browser(driver_name=self.driver_name,executable_path=self.executable_path)
105         # 浏览器窗口的大小
106         # self.driver.driver.set_window_size(900, 700)
107         self.do_login()
108         self.driver.visit(self.ticket_url)
109         try:
110             print('开始刷票……')
111             # 加载车票查询信息
112             self.driver.cookies.add({"_jc_save_fromStation": self.from_station})#出发位置
113             self.driver.cookies.add({"_jc_save_toStation": self.to_station})#目的地
114             self.driver.cookies.add({"_jc_save_fromDate": self.from_time})#出发时间
115             self.driver.reload()
116             count = 0
117             while self.driver.url.split('?')[0] == self.ticket_url:
118                 try:
119                     self.wait_time('query_ticket')
120                     elemt= self.driver.find_by_xpath('//select[@id="cc_start_time"]//option[@value="'+str(self.train_date)+'"]',).first
121                     elemt.click()
122                     sleep(1)
123                     self.driver.find_by_text('查询').click()
124                     self.wait_time('train_type_btn_all')
125                     count += 1
126                     print('第%d次点击查询……' % count)
127                     
128                     elems = self.driver.find_by_id('queryLeftTable')[0].find_by_xpath('//tr[starts-with(@id,"ticket_")]')
129                     while len(elems)==0:
130                         sleep(0.5)
131                         elems = self.driver.find_by_id('queryLeftTable')[0].find_by_xpath('//tr[starts-with(@id,"ticket_")]')
132                     #是不是有票就行
133                     if(self.isHave):
134                         for current_tr in elems:
135                             if(current_tr.text==''):
136                                 print('没票')
137                                 continue
138                                 # 下标索引
139                             if current_tr.find_by_tag('td')[self.seat_type_index].text == '--' or current_tr.find_by_tag('td')[self.seat_type_index].text == '':
140                                     print('无此座位类型出售!')
141                                     continue
142                             else:
143                                     # 有票,尝试预订
144                                     print('刷到票了(余票数:' + str(current_tr.find_by_tag('td')[self.seat_type_index].text) + '),开始尝试预订……')
145                                     current_tr.find_by_css('td.no-br>a')[0].click()
146                                     key_value = 1
147                                     # 等待页面加载完毕
148                                     self.wait_time('normalPassenger_' +str(int(key_value-1)))
149 
150                                     for p in self.passengers:
151                                         # 选择用户
152                                         print('开始选择用户……')
153                                         self.driver.find_by_text(p).last.click()
154                                         # 选择座位类型
155                                         print('开始选择席别……')
156                                         if self.seat_type_value != 0:
157                                             sleep(1)
158                                             seat_select = self.driver.find_by_id("seatType_" + str(key_value))[0]
159                                             seat_select.find_by_xpath("//option[@value='" + str(self.seat_type_value) + "']")[0].click()
160                                         key_value += 1
161                                         if p[-1] == ')':
162                                             self.driver.find_by_id('dialog_xsertcj_ok').click()
163                                         print('正在提交订单……')
164                                         self.driver.find_by_id('submitOrder_id').click()
165                                         self.wait_time('content_checkticketinfo_id')
166                                         # 查看返回结果是否正常
167                                         submit_false_info = self.driver.find_by_id('orderResultInfo_id')[0].text
168                                         if submit_false_info != '':
169                                             print(submit_false_info)
170                                             self.driver.find_by_id('qr_closeTranforDialog_id').click()
171                                             self.driver.find_by_id('preStep_id').click()
172                                             continue
173                                         print('正在确认订单……')
174                                         # 等待加载完毕
175                                         self.wait_time('qr_submit_id')
176                                         self.driver.find_by_id('qr_submit_id').click()
177                                         print('预订成功,请及时前往支付……')
178                                         # 发送通知信息
179                                         self.send_mail(self.receiver_email, '恭喜您,抢到票了,请及时前往12306支付订单!')
180                                         self.send_sms(self.receiver_mobile, '恭喜您,抢到票了,请及时前往12306支付订单!')
181                     else:
182                         for current_tr in elems:
183                             if(current_tr.text==''):
184                                 print('没票')
185                                 continue
186                             else:
187                                 # 下标索引
188                                 print('判断车票是否存在')
189                                 if current_tr.find_by_tag('td')[self.seat_type_index].text == '--' or current_tr.find_by_tag('td')[self.seat_type_index].text == '':
190                                     print('无此座位类型出售!')
191                                     continue
192                                 else:
193                                     # 有票,尝试预订
194                                     print('刷到票了(余票数:' + str(current_tr.find_by_tag('td')[self.seat_type_index].text) + '),开始尝试预订……')
195                                     current_tr.find_by_css('td.no-br>a')[0].click()
196                                     key_value = 1
197                                     # 等待页面加载完毕
198                                     self.wait_time('normalPassenger_' +str(int(key_value-1)))
199 
200                                     for p in self.passengers:
201                                           # 选择用户
202                                         print('开始选择用户……')
203                                         self.driver.find_by_text(p).last.click()
204                                         # 选择座位类型
205                                         print('开始选择席别……')
206                                         if self.seat_type_value != 0:
207                                             seat_select = self.driver.find_by_id("seatType_" + str(key_value))[0]
208                                             seat_select.find_by_xpath("//option[@value='" + str(self.seat_type_value) + "']")[0].click()
209                                         key_value += 1
210                                         if p[-1] == ')':
211                                             self.driver.find_by_id('dialog_xsertcj_ok').click()
212                                         print('正在提交订单……')
213                                         self.driver.find_by_id('submitOrder_id').click()
214                                         self.wait_time('content_checkticketinfo_id')
215                                         # 查看返回结果是否正常
216                                         submit_false_info = self.driver.find_by_id('orderResultInfo_id')[0].text
217                                         if submit_false_info != '':
218                                             print(submit_false_info)
219                                             self.driver.find_by_id('qr_closeTranforDialog_id').click()
220                                             self.driver.find_by_id('preStep_id').click()
221                                             continue
222                                         print('正在确认订单……')
223                                         # 等待加载完毕
224                                         self.wait_time('qr_submit_id')
225                                         self.driver.find_by_id('qr_submit_id').click()
226                                         print('预订成功,请及时前往支付……')
227                                         # 发送通知信息
228                                         self.send_mail(self.receiver_email, '恭喜您,抢到票了,请及时前往12306支付订单!')
229                                         self.send_sms(self.receiver_mobile, '恭喜您,抢到票了,请及时前往12306支付订单!')
230                                         
231                     # self.driver.quit()
232                     return
233                 except Exception as error_info:
234                     print(error_info)
235         except Exception as error_info:
236             print(error_info)
237 
238     def wait_time(self, name):
239             while self.driver.is_element_present_by_id(name) == False:
240                  sleep(1)
241 
242 
243     def send_sms(self, mobile, sms_info):
244         """发送手机通知短信,用的是-互亿无线-的测试短信"""
245         host = "106.ihuyi.com"
246         sms_send_uri = "/webservice/sms.php?method=Submit"
247         account = "C59782899"
248         pass_word = "19d4d9c0796532c7328e8b82e2812655"
249         params = parse.urlencode(
250             {'account': account, 'password': pass_word,
251                 'content': sms_info, 'mobile': mobile, 'format': 'json'}
252         )
253         headers = {"Content-type": "application/x-www-form-urlencoded",
254                    "Accept": "text/plain"}
255         conn = httplib2.HTTPConnectionWithTimeout(host, port=80, timeout=30)
256         conn.request("POST", sms_send_uri, params, headers)
257         response = conn.getresponse()
258         response_str = response.read()
259         conn.close()
260         return response_str
261 
262     def send_mail(self, receiver_address, content):
263         """发送邮件通知"""
264         # 连接邮箱服务器信息
265         host = 'smtp.qq.com' #QQ
266         sender = '[email protected]'  # 你的发件邮箱号码
267         pwd = 'riebhcallwgzbfei'  # 不是登陆密码,是客户端授权密码
268         # 发件信息
269         receiver = receiver_address
270         body = '<h2>温馨提醒:</h2><p>' + content + '</p>'
271         msg = MIMEText(body, 'html', _charset="utf-8")
272         msg['subject'] = '抢票成功通知!'
273         msg['from'] = sender
274         msg['to'] = receiver
275         s = smtplib.SMTP(host, port=465, timeout=30)
276         # 开始登陆邮箱,并发送邮件
277         s.login(sender, pwd)
278         s.sendmail(sender, receiver, msg.as_string())
279         s.close()
280 
281 
282 if __name__ == '__main__':
283     # 12306用户名
284     user_name = 'XXXXX'
285     # 12306登陆密码
286     password = 'XXXXX'
287     # 乘客姓名
288     passengers = '张三'
289     # 乘车日期
290     from_time = '2018-12-21'
291    
292     #发车时间
293     train_date={
294         '00:00--24:00':'00002400',
295         '00:00--06:00':'00000600',
296         '06:00--12:00':'06001200',
297         '12:00--18:00':'12001800',
298         '18:00--24:00':'18002400',
299     }
300 
301      # 城市cookie字典
302     city_list = {'成都': '%u6210%u90FD%2CCDW',
303                  '重庆': '%u91CD%u5E86%2CCQW',
304                  '北京': '%u5317%u4EAC%2CBJP',
305                  '广州': '%u5E7F%u5DDE%2CGZQ',
306                  '杭州': '%u676D%u5DDE%2CHZH',
307                  '宜昌': '%u5B9C%u660C%2CYCN',
308                  '郑州': '%u90D1%u5DDE%2CZZF',
309                  '深圳': '%u6DF1%u5733%2CSZQ',
310                  '西安': '%u897F%u5B89%2CXAY',
311                  '大连': '%u5927%u8FDE%2CDLT',
312                  '武汉': '%u6B66%u6C49%2CWHN',
313                  '上海': '%u4E0A%u6D77%2CSHH',
314                  '南京': '%u5357%u4EAC%2CNJH',
315                  '合肥': '%u5408%u80A5%2CHFH'}
316     # 出发站
317     from_station = city_list['广州']
318     # 终点站
319     to_station = city_list['武汉']
320     # 座位类型
321     seat_type = '二等座'
322     # 抢票成功,通知该手机号码
323     receiver_mobile = 'xxxxxx'
324     #抢票成功,通知该邮件
325     receiver_email = '[email protected]'
326     # 开始抢票
327     ticket = BrushTicket(train_date['18:00--24:00'],user_name, password, passengers.split(","), from_time, from_station,
328                          to_station, seat_type, receiver_mobile, receiver_email,True)
329     ticket.start_brush()
demo

环境:python3,chromedriver(请下载对应的版本的浏览器驱动)

效果图:

本代码发布于2018.12.18(如果报错请查看包是否引用正确或官网是否改动)

猜你喜欢

转载自www.cnblogs.com/Zhengxue/p/10136109.html