马上就春节了,你抢到回家的票了吗?
别急,今天给大家推荐一款开源、功能强大且实用的12306抢票工具!
1、介绍
该项目名为py12306
,由 GitHub 用户 pjialin 创建和维护,用Python语言开发。
项目目前在GitHub
上有非常高的关注度,截止到今天,已获得了13k的点赞星标👍。
开源地址:https://github.com/pjialin/py12306
简单来说,py12306
是一款12306购票助手工具,可以让你能加更方便、容易地购买到火车票,它支持集群,多账号,多任务购票以及提供了一个 Web 页面来管理购票任务。
它支持的主要特性有:
- 支持按多日期查询余票、从站点查询
- 支持自动打码下单
- 电话、语音、邮件、微信多种消息通知支持
- 多账号、多任务、多线程、分布式运行
- Docker容器化部署支持
- 支持Web可视化管理页面
2、安装与使用
温馨提醒:py12306
需要运行在 Python 3.6 以上版本。
- 安装依赖
git clone https://github.com/pjialin/py12306
pip install -r requirements.txt
- 配置程序
cp env.py.example env.py
执行运行前,根据自己的需求,调整配置,例如:
# 12306 账号
USER_ACCOUNTS = [
# 目前已支持仅查询,不下单,屏蔽掉下面的账号即可
{
'key': 0, # 如使用多个账号 key 不能重复
'user_name': 'your user name',
'password': '忽略',
'type': 'qr' # qr 为扫码登录,填写其他为密码登录
},
# {
# 'key': 'wangwu',
# 'user_name': 'wangwu@qq.com',
# 'password': 'wangwu',
# 'type': ''
# }
]
# 查询间隔(指每一个任务中每一个日期的间隔 / 单位秒)
# 默认取间隔/2 到 间隔之间的随机数 如设置为 1 间隔则为 0.5 ~ 1 之间的随机数
# 接受字典形式 格式: {'min': 0.5, 'max': 1}
QUERY_INTERVAL = 1
# 网络请求重试次数
REQUEST_MAX_RETRY = 5
# 用户心跳检测间隔 格式同上
USER_HEARTBEAT_INTERVAL = 120
# 多线程查询
QUERY_JOB_THREAD_ENABLED = 0 # 是否开启多线程查询,开启后第个任务会单独分配线程处理
- 启动前测试
目前提供了一些简单的测试,包括用户账号检测,乘客信息检测,车站检测等
python main.py -t
# 默认不会进行通知测试,要对通知进行测试需要加上 -n 参数
python main.py -t -n
- 运行程序
python main.py
常用参数列表:
- -t 测试配置信息
- -t -n 测试配置信息以及通知消息
- -c 指定自定义配置文件位置
3、Docker安装与使用
- 将配置文件下载到本地
docker run --rm pjialin/py12306 cat /config/env.py > env.py
# 或
curl https://raw.githubusercontent.com/pjialin/py12306/master/env.docker.py.example -o env.py
- 修改好配置后运行
docker run --rm --name py12306 -p 8008:8008 -d -v $(pwd):/config -v py12306:/data pjialin/py12306
当前目录会多一个 12306.log 的日志文件, tail -f 12306.log
4、Web 管理页面
从py12306/web/web.py
代码中可知,此项目web部分,采用了flask框架来开发,默认端口为8080
# -*- coding: utf-8 -*-
import json
import logging
from datetime import timedelta
from flask import Flask, request
from flask_jwt_extended import (
JWTManager)
from py12306.config import Config
from py12306.helpers.func import *
@singleton
class Web:
session = None
jwt = None
log = None
def __init__(self):
self.session = Flask(__name__)
self.log = logging.getLogger('werkzeug')
self.log.setLevel(logging.ERROR)
self.register_blueprint()
self.session.config['JWT_SECRET_KEY'] = 'secret' # 目前都是本地,暂不用放配置文件
self.session.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(seconds=60 * 60 * 24 * 7) # Token 超时时间 7 天
self.jwt = JWTManager(self.session)
def register_blueprint(self):
from py12306.web.handler.user import user
from py12306.web.handler.stat import stat
from py12306.web.handler.app import app
from py12306.web.handler.query import query
from py12306.web.handler.log import log
self.session.register_blueprint(user)
self.session.register_blueprint(stat)
self.session.register_blueprint(app)
self.session.register_blueprint(query)
self.session.register_blueprint(log)
@classmethod
def run(cls):
self = cls()
self.start()
def start(self):
if not Config().WEB_ENABLE or Config().is_slave(): return
# if Config().IS_DEBUG:
# self.run_session()
# else:
create_thread_and_run(self, 'run_session', wait=False)
def run_session(self):
debug = False
if is_main_thread():
debug = Config().IS_DEBUG
self.session.run(debug=debug, port=Config().WEB_PORT, host='0.0.0.0')
if __name__ == '__main__':
Web.run()
打开浏览器访问:http://127.0.0.1:8080
即可