Python 3.0 实现定时时监控12306 火车票
本文章内容将完整发表在公众号: 程序员开发者社区, 欢迎关注,后台回复:资源,有惊喜!
王小涛同学的 2015年的已经不好用了,在其基础上改了改
这里提供个 2016的 可以在python3.0 环境下运行的:
看代码:
import urllib.request as request
import http.cookiejar as cookiejar
import re
import ssl
import os
import smtplib
from email.mime.text import MIMEText
import time
user = 'xxxx' # 登陆邮箱
pwd = '' # 邮箱密码
to = [''] # 发送的邮箱
with open('D:\\Python源码\\city.txt', 'r') as f:
a = f.read()
station = re.compile(u'\w+:(.+?):(\w+):\d').findall(a)
dic1 = {}
for b in range(0, len(station)):
dic1[station[b][0]] = station[b][1]
def gethtml(geturl):
cj = cookiejar.LWPCookieJar()
cookiejarsupport = request.HTTPCookieProcessor(cj)
opener = request.build_opener(cookiejarsupport, request.HTTPHandler)
#handler = request.HTTPBasicAuthHandler()
# create "opener" (OpenerDirector instance)
#opener = request.build_opener(handler)
USER_AGENTS = (
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0',
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100 101 Firefox/22.0',
'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0',
('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) '
'Chrome/19.0.1084.46 Safari/536.5'),
('Mozilla/5.0 (Windows; Windows NT 6.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46'
'Safari/536.5')
)
'''
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36',
'Host': 'www.12306.cn',
'Referer': 'https://kyfw.12306.cn/otn/leftTicket/init'
}
'''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
}
#x = opener.open(geturl);
#verify=False ,
request.install_opener(opener)
req = request.Request(url=geturl,headers=headers)
#request.packages.urllib3.disable_warnings()
#r = request.get(geturl,verify=False)
#station_code_html = r.text
#gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
ssl._create_default_https_context = ssl._create_unverified_context
#gcontext = ssl._create_unverified_context()
#gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
#html = request.urlopen(req,context=gcontext).read().decode()
html = request.urlopen(req).read().decode()
print(html)
return html
#return station_code_html
#print(x)
def getstation(html):
fromstation = re.compile(r'from_station_name":"(.+?)","').findall(html)
tostation = re.compile(r'to_station_name":"(.+?)",').findall(html)
startime = re.compile(r'"start_time":"(.+?)"').findall(html)
arrtime = re.compile(r'arrive_time":"(.+?)"').findall(html)
lishi = re.compile(r'"lishi":"(.+?)",').findall(html)
webbuy = re.compile(r'"canWebBuy":"(.+?)').findall(html)
startstation = re.compile(r'start_station_name":"(.+?)"').findall(html)
endstation = re.compile(r'end_station_name":"(.+?)"').findall(html)
ruanwo = re.compile((r'"rw_num":"(.+?)",')).findall(html)
ruanzuo = re.compile((r'"rz_num":"(.+?)"')).findall(html)
yingwo = re.compile(r'"yw_num":"(.+?)"').findall(html)
ruanzuo = re.compile(r'"rz_num":"(.+?)"').findall(html)
yingzuo = re.compile(r'"yz_num":"(.+?)"').findall(html)
wuzuo = re.compile(r'"wz_num":"(.+?)"').findall(html)
checi = re.compile(r'station_train_code":"(.+?)"').findall(html)
datanum = re.compile((r'day_difference":"(.+?)"')).findall(html)
erdengzuo = re.compile(r'ze_num":"(.+?)",').findall(html)
num = range(0, len(wuzuo))
for i in num:
try:
if yingzuo[i].isdigit() or erdengzuo[i].isdigit() or wuzuo[i].isdigit(): # Z108
print(checi[i], ' 二等座: ', erdengzuo[i], ' 硬座: ', yingzuo[i], ' 无座: ', wuzuo[i])
if yingwo[i] != '--' or yingzuo[i] != '无':
msg = MIMEText(
'火车: ' + fromstation[i] + ' ->' + tostation[i] + '(' + checi[i] + ')\n二等座:' + erdengzuo[
i] + '张;硬座:' + yingzuo[i] + '张;无座:' + wuzuo[
i] + '张!快买去!\n网址: http://www.12306.cn/opn/lcxxcx/init')
msg['Subject'] = '有票啦!'
msg['From'] = user
msg['To'] = ','.join(to)
s = smtplib.SMTP('smtp.qq.com', timeout=30) # 连接SMTP端口
s.login(user, pwd) # 登陆服务器
s.sendmail(user, to, msg.as_string())
s.close()
print('发送成功')
print('------------------------------------------------------------')
except:
continue
print('''''
By:王小明_同學
--------------------------------------------------------------
欢迎使用!
--------------------------------------------------------------
''')
print('请输入购票类型: (0为成人票 其他为学生票) ')
leixing = input()
print('请输入起点:')
qidian = input()
try:
if dic1[qidian]:
qidian = dic1[qidian]
except:
print('起点输入有误!')
print('请输入终点:')
zhongdian = input()
try:
if dic1[zhongdian]:
zhongdian = dic1[zhongdian]
except:
print('终点输入有误!')
print('请输入购票年份:')
year = input() + '-'
print('请输入购票月份:(2位)')
month = input() + '-'
print('请输入购票日期:(2位)')
date = input()
date = year + month + date
if leixing == 0:
#geturl='https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2017-01-25&from_station=CDW&to_station=SHH'
geturl = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate='+date+'&from_station ='+qidian+'&to_station='+ zhongdian
#geturl = 'http://www.12306.cn/opn/lcxxcx/query?purpose_codes=ADULT&queryDate=' + date + '&from_station=' + qidian + '&to_station=' + zhongdian
else:
geturl = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=0X00&queryDate=' + date + '&from_station =' + qidian + '&to_station=' + zhongdian
#geturl = 'http://www.12306.cn/opn/lcxxcx/query?purpose_codes=0X00&queryDate=' + date + '&from_station=' + qidian + '&to_station=' + zhongdian
#geturl='https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2017-01-25&from_station=CDW&to_station=SHH'
while 1:
getstation(gethtml(geturl))
print('火车票监测中...')
time.sleep(200)
返回:
{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"datas":[{"train_no":"24000D20010J","station_train_code":"D2001","start_station_telecode":"BXP","start_station_name":"北京西","end_station_telecode":"ABV","end_station_name":"运城北","from_station_telecode":"BXP","from_station_name":"北京西","to_station_telecode":"ABV","to_station_name":"运城北","start_time":"07:45","arrive_time":"13:53","day_difference":"0","train_class_name":"动车","lishi":"06:08","canWebBuy":"N","lishiValue":"368","yp_info":"F3S5PVHpigT7Y%2F8BrDGhq%2F7A%2Bgc%2Bg6HzvgO0kBo8EtNe5Z0l","control_train_day":"20170226","start_train_date":"20170125","seat_feature":"O3M3W3","yp_ex":"O0M0O0","train_seat_feature":"3","train_type_code":"2","start_province_code":"31","start_city_code":"0357","end_province_code":"02","end_city_code":"0413","seat_types":"OMO","location_code":"P2","from_station_no":"01","to_station_no":"15","control_day":74,"sale_time":"0800","is_support_card":"0","note":"","controlled_train_flag":"0","controlled_train_message":"正常车次,不受控","gg_num":"--","gr_num":"--","qt_num":"--","rw_num":"--","rz_num":"--","tz_num":"--","wz_num":"无","yb_num":"--","yw_num":"--","yz_num":"--","ze_num":"无","zy_num":"无","swz_num":"--"},{"train_no":"240000G60520","station_train_code":"G605","start_station_telecode":"BXP","start_station_name":"北京西","end_station_telecode":"AJV","end_station_name":"永济北","from_station_telecode":"BXP","from_station_name":"北京西","to_station_telecode":"ABV","to_station_name":"运城北","start_time":"10:28","arrive_time":"16:20","day_difference":"0","train_class_name":"","lishi":"05:52","canWebBuy":"N","lishiValue":"352","yp_info":"IMouS%2BGFTUXH%2BwMaugVCx03q5dA143f59dOgPckwBMNovOoB","control_train_day":"20170226","start_train_date":"20170125","seat_feature":"O3M393","yp_ex":"O0M090","train_seat_feature":"3","train_type_code":"2","start_province_code":"31","start_city_code":"0357","end_province_code":"02","end_city_code":"5408","seat_types":"OM9","location_code":"P4","from_station_no":"01","to_station_no":"14","control_day
https 的问题这个程序已经处理了
如果还是有403 forbidden :
geturl 使用:
https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2017-01-25&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT
怎样发邮件 , 这个就不说了,邮件博客已经说明, 主要是 微信 -》设置-》通用-》功能-》开启QQ邮箱提醒,这样就可以将消息推送到微信显示了(需要微信绑定了QQ)
看个:
import urllib.request as request
import http.cookiejar as cookiejar
import re
import ssl
import os
import smtplib
from email.mime.text import MIMEText
import time
import random
# coding= utf-8
user = 'xxxxx@126.com' # 登陆邮箱
pwd = 'xxxx' # 邮箱密码
to = ['xxxx@xxxx.com.cn','xxxx@xxxx.com.cn'] # 发送的邮箱xxxx@xx.com
USER_AGENTS = (
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0',
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100 101 Firefox/22.0',
'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0',
('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) '
'Chrome/19.0.1084.46 Safari/536.5'),
('Mozilla/5.0 (Windows; Windows NT 6.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46'
'Safari/536.5'),
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6',
'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0'
)
#12306 有很多个地址 leftTicket 是一个 lcxxcx 是一个
date = '2017-01-24'
#geturl='https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date='+date+'&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SMS&purpose_codes=ADULT'
geturl='https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date='+date+'&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=CSQ&purpose_codes=ADULT'
#geturl='https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate='+date+'&from_station=CDW&to_station=SHH'
#geturl='https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date='+date+'&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT'
print(date)
def getXSRF(data):
cer = re.compile('name="authenticityToken" value="(.*)"')
s = cer.findall(data)
return s[0]
with open('D:\\city.txt', 'r') as f:
a =