Python打造刷火车票工具邮件通知自己
本帖最后由 Pojie1999.0909 于 2018-1-18 08:26 编辑准备环境
win10操作系统、python3.6、python库
docopt、requests、pyinstaller
效果
http://img.blog.csdn.net/20180117172936922?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
http://img.blog.csdn.net/20180117172952864?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
开始
懒得写了,,贴代码
#coding:utf-8
"""命令行火车票查看器
Usage:
tk [-gdtkz] <from> <to> <date>
Options:
-h,--help 显示帮助菜单
-g 高铁
-d 动车
-t 特快
-k 快速
-z 直达
Example:
tk 石家庄 昌黎 2016-10-10
tk -dg 石家庄 昌黎 2016-10-10
"""
'''
Created on 2018年1月17日
@author: DELL
'''
import smtplib
from email.mime.text import MIMEText
import time
from stations import stations as sta
from docopt import docopt
import requests
def sendMail(subject,body):
try:
"""发送邮件"""
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = "的qq邮箱"#from
msg["To"] = "的qq邮箱"#to
s = smtplib.SMTP_SSL("smtp.qq.com", 465)
s.login("你的qq邮箱","你的qq邮箱授权码")#这里的第二个参数为qq邮箱授权码,不要填你的密码
s.sendmail("你的qq邮箱",["的qq邮箱",],msg.as_string())#from,to,msg
s.quit()
print("刷到票拉!邮件发送成功!")
except Exception as e:
print("刷到票拉!可是邮件发送失败~~"+e.message)
class TrainCollection:
header = '车次 车站 时间 历时 一等 二等 软卧 硬卧 硬座 无座'.split() #23软卧 24软座26无座 28硬卧 29硬座 30二等 31一等 32商务特等
def __init__(self,available_trains,options,fromto):
"""查询到的火车班次集合
:param available_trains:一个列表,包含可获得的火车班次,每个火车班次是一个字典
:param options:查询的选项,如高铁,动车,etc...
"""
self.available_trains = available_trains
self.options = options
self.fromto = fromto
#def _get_duration(self,raw_train):
# duration = raw_train.get('lishi').replace(':','小时')+'分'
@property
def trains(self):
train_no = self.available_trains
initial = train_no.lower()
if not self.options or initial in self.options:
train = [
train_no,
'\n'.join(, self.fromto]),
'\n'.join(, self.available_trains]),
self.available_trains,
self.available_trains,
self.available_trains,
self.available_trains,
self.available_trains,
self.available_trains,
self.available_trains
]
yield train
"""
def pretty_print(self):
pt = PrettyTable()
pt._set_field_names(self.header)
for train in self.trains:
pt.add_row(train)
print(pt)
"""
def CanISendMessage(self):
flag = False
for train in self.trains:
if train=='有' or train=='有':
return True
return flag
def checkIt():
url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(date,from_station,to_station)
"""测试
print(url)
html = urlopen(url)
print(html.read())
temp = json.loads(html.read())
print(temp)
print(type(temp))
print(temp["data"])
print(temp["data"]["result"])
"""
headers = {
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3",
"Connection": "Keep-Alive",
"Cookie": "JSESSIONID=A9C5372008A2D67B84E8EABF0F040B7A; RAIL_DEVICEID=MBKbxqbUfDzzIpo2brgvh_2cPdBFvBQVpXv2Kj43TpRT7ARJkdxFoKdhk4Blw8JQi63NCxMhXtxxR3FVMuhhnTVcKJKExL4rrMG6V_jNCOhEpR9bukvfJKf609zJbLB6r8lhCZk2kcOktpO0MJ1_mONunAQSp1Mu; RAIL_EXPIRATION=1516446126590; route=6f50b51faa11b987e576cdb301e545c4; BIGipServerotn=401605130.64545.0000; acw_tc=AQAAAMsuNmmy6gMAPZPvfGHGldIGyAY9; _jc_save_toStation=%u660C%u9ECE%2CCLP; _jc_save_wfdc_flag=dc; _jc_save_toDate=2018-01-17; _jc_save_fromDate=2018-02-11; _jc_save_fromStation=%u77F3%u5BB6%u5E84%2CSJP",
"Host": "kyfw.12306.cn",
"If-Modified-Since": "0",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299",
"X-Requested-With": "XMLHttpRequest",
"Cache-Control": "no-cache"
}
print (url)
r = requests.get(url,headers=headers,verify=False)
print(r.text)
result = r.json()['data']['result']
result_len = len(result)
print(result)
#获取参数
options = ''.join([
#使用生成器表达式
key for key,value in arguments.items() if value is True
])
fromto = (
arguments['<from>'],
arguments['<to>']
)
for i in range(result_len):
#print(result.split('|'))
if(TrainCollection(result.split('|'),options,fromto)):
sendMail("乞丐刷票 - by cgsthtm", "大人!有回家的车票啦!终于可以回家啦~~快去抢啊!!")
def cli():
"""接受命令行输入参数"""
while True:
checkIt()
time.sleep(60)#每60秒执行一次
arguments = docopt(__doc__)
from_station = sta.get(arguments["<from>"])
to_station = sta.get(arguments["<to>"])
date = arguments["<date>"]
if __name__ == "__main__":
cli()
""" test
msg = MIMEText("the body of the email is here")
msg["Subject"] = "An Email Alert"
msg["From"] = ""
msg["To"] = ""
s= smtplib.SMTP('smtp.qq.com')
s.send_message(msg)
s.quit()
"""
Removeformat
注意
改成你自己的邮箱账号和授权码
http://img.blog.csdn.net/20180117173038484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
http://img.blog.csdn.net/20180117173057071?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0dTX19fX19fXw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
用法
顺便加上昨天忘记上传的附件
查询频率,一分钟查询一次
如果有硬座或硬卧就发邮件通知自己
不想限制硬座硬卧的自己改吧 一米阳光几度暖 发表于 2018-1-22 00:20
from stations import stations as sta
ImportError: No module named 'stations'我是了下,报错,请 ...
stations是一个py文件,把这个附件下载放到tks.py同级目录下就好啦 谢谢,分给你
i 支持支持,太厉害了 就算查到了,等你去买的时候什么都没了 不明觉厉 你就不能写简单一点吗。 邮件通知到你,也没了吧。。。直接变成买的不好麽 谢谢你的分享 谢谢楼主分享