Python 3.0 实现定时时监控12306 火车票

本文介绍如何使用Python 3.0编写程序实现定时监控12306火车票余量。针对403 forbidden错误和HTTPS问题提供了解决方案,并建议使用模拟浏览器登录的辅助抢票程序。还提到了12306响应信息的改变,以及城市列表和更新的资源链接。
摘要由CSDN通过智能技术生成

 

                            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 =
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangxiaoming

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值