最近有发现 GitHub 上的一个 python 项目抢票项目, 可在自己笔记本上搭建环境并且部署好即可以实现自动打码, 自动登录, 准点预售和捡漏, 智能候补, 邮件通知. 源代码地址如下:
https://codeload.github.com/testerSunshine/12306/zip/master.
特别说明: 本项目属于爬虫类项目, 如果商用可能会有法律风险, 请各位读者谨慎使用, 如果由于根据本文使用 12306 自动抢票软件引发法律纠纷, 笔者并不承担.
12306 抢票项目的安装和使用
目前 "12306 自动抢票" 的 GitHub 官网上还没有一个完整的安装和布署攻略, 这里我就把完整的安装流程向大家说明一下. 不过目前本项目应该还只支持 UBANTU 等 Linux 平台, 这个项目的很多依赖项在 Windows 平台上装非常麻烦, 所以建议直接在 UBANTU 上布署, 这样相对比较简单.
1. 下载项目源码:
使用以下命令下载项目源码
- Git clone https://github.com/testerSunshine/12306.git
- cd 12306
2. 下载项目依赖的识别码打码模型
打开以下网址: https://github.com/testerSunshine/12306model, 下载下图两个标红的模型文件, 并放到 12306 项目的根目录 (一般是~/12306)
3. 安装项目依赖
使用以下命令下载项目依赖项, 本项目的依赖项比较多, 建议直接使用 sudo 安装更多稳妥, 如果有报错, 则需要单独去解决具体安装项的问题, 目前看最主要的问题可能在于 tensorflow 的安装, 不过由于不需要 GPU 的版本, 所以直接安装应该也不会有什么问题.
sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
4. 安装 chromedriver
使用以下命令安装 chromedriver, 一般安装后会放在 / usr/local/bin 下, 需要在配置文件的 CHROME_PATH 标签下填好
sudo apt-get install chromium-chromedriver
5. 修改配置文件
修改 "12306 自动抢票" 项目根目录下的 TickerConfig.py, 具体注释原作者已经写好了, 如下:
关于软件使用配置说明, 一定要看!!!
- # ps: 如果是候补车票, 需要通过人证一致性核验的用户及激活的 "铁路畅行" 会员可以提交候补需求, 请您按照操作说明在铁路 12306app. 上完成人证核验
- # 关于候补了之后是否还能继续捡漏的问题在此说明: 软件为全自动候补加捡漏, 如果软件候补成功则会停止抢票, 发出邮件通知, 但是不会影响你继续捡漏,
- # 如果这个时候捡漏捡到的话, 也是可以付款成功的, 也就是说, 捡漏 + 候补, 可以最大程度提升抢票成功率
- # 刷票模式: 1 = 刷票 2 = 候补 + 刷票
- TICKET_TYPE = 2
- # 候补最晚兑现日期, 目前软件为捡漏加自动候补, 所以这个值一定要填, 并且这个日期一定要填小于最长订票时间 (30 天)
- # 格式为日期 + 小时 + 分
- # 举例: 比如今天才可以买 10.1 号的票, 比如你那个发车是 10.1 号上午两点, 你兑现时间写到 10.1 晚上 22 点?
- # t("#fromDate").val() + "#" + t("#dafaultTime").html().replace("时", "") +"#"+ t("#dafaultMinutes").HTML().replace(" 分 ",""),
- J_Z_PARAM = "2019-09-28#22#59"
- # 出发日期 (list) "2018-01-06", "2018-01-07"
- # ps: 日期如果是单日, 一定要前面补个 0, 正确做法: 2019-01-01, 错误做法: 2019-1-1
- STATION_DATES = [
- "2019-09-25"
- ]
- # 填入需要购买的车次 (list),"G1353"
- STATION_TRAINS = [
- "",
- ]
- # 出发城市, 比如深圳北, 就填深圳就搜得到
- FROM_STATION = ""
- # 到达城市 比如深圳北, 就填深圳就搜得到
- TO_STATION = ""
- # 座位 (list) 多个座位 ex:
- # "商务座",
- # "一等座",
- # "二等座",
- # "特等座",
- # "软卧",
- # "硬卧",
- # "硬座",
- # "无座",
- # "动卧",
- SET_TYPE = [
- "",
- ]
- # 当余票小于乘车人, 如果选择优先提交, 则删减联系人和余票数一致在提交
- # bool
- IS_MORE_TICKET = True
- # 乘车人 (list) 多个乘车人 ex:
- # - "张三"
- # - "李四"
- TICKET_PEOPLES = [
- "",
- ]
- # 12306 登录账号
- USER = ""PWD =""
- # 加入小黑屋时间默认为 5 分钟, 此功能为了防止僵尸票导致一直下单不成功错过正常的票
- TICKET_BLACK_LIST_TIME = 5
- # 自动打码
- IS_AUTO_CODE = True
- # 邮箱配置, 如果抢票成功, 将通过邮件配置通知给您
- # 列举 163
- # email: "xxx@163.com"
- # notice_email_list: "123@qq.com"
- # username: "xxxxx"
- # password: "xxxxx
- # host: "smtp.163.com"
- # 列举 qq ,qq 设置比较复杂, 需要在邮箱 --> 账户 --> 开启 smtp 服务, 取得授权码 == 邮箱登录密码
- # email: "xxx@qq.com"
- # notice_email_list: "123@qq.com"
- # username: "xxxxx"
- # password: "授权码"
- # host: "smtp.qq.com"
- EMAIL_CONF = {
- "IS_MAIL": False,
- "email": "",
- "notice_email_list": "",
- "username": "",
- "password": "",
- "host": "",
- }
- # 是否开启 pushbear 微信提醒, 使用前需要前往 http://pushbear.ftqq.com 扫码绑定获取 send_key 并关注获得抢票结果通知的公众号
- PUSHBEAR_CONF = {
- "is_pushbear": False,
- "send_key": ""
- }
- # 是否开启 cdn 查询, 可以更快的检测票票 1 为开启, 2 为关闭
- IS_CDN = 1
- # 下单接口分为两种, 1 模拟网页自动捡漏下单 (不稳定),2 模拟车次后面的购票按钮下单 (稳如老狗)
- ORDER_TYPE = 2
- # 下单模式 1 为预售, 整点刷新, 刷新间隔 0.1-0.5S, 然后会校验时间, 比如 12 点的预售, 那脚本就会在 12.00 整检票, 刷新订单
- # 2 是捡漏, 捡漏的刷新间隔时间为 0.5-3 秒, 时间间隔长, 不容易封 ip
- ORDER_MODEL = 2
- # 是否开启代理, 0 代表关闭, 1 表示开始
- # 开启此功能的时候请确保代理 ip 是否可用, 在测试放里面经过充分的测试, 再开启此功能, 不然可能会耽误你购票的宝贵时间
- # 使用方法:
- # 1, 在 agency/proxy_list 列表下填入代理 ip
- # 2, 测试 UnitTest/TestAll/testProxy 测试代理是否可以用
- # 3, 开启代理 ip
- IS_PROXY = 0
- # 预售放票时间, 如果是捡漏模式, 可以忽略此操作
- OPEN_TIME = "13:00:00"
- # 1 = 使用 selenium 获取 devicesID
- # 2 = 使用网页端 / otn/HttpZF/logdevice 获取 devicesId, 这个接口的算法目前可能有点问题, 如果登录一直 302 的请改为配置 1
- COOKIE_TYPE = 1
- # 如果 COOKIE_TYPE=1, 则需配置 chromeDriver 路径 (注意是填你机器本地 chromeDriver 的路径, 这个地方一定要改), 下载地址 http://chromedriver.storage.googleapis.com/index.html
- # chromedriver 配置版本只要和 Chrome 的大版本匹配就行
- # 如果是 Windows, 最好在路径加上 r, ex: r"/Users/wenxianping/Downloads/chromedriver"
- CHROME_PATH = ""
- PASSENGER_TICKER_STR = {
- '一等座': 'M',
- '特等座': 'P',
- '二等座': 'O',
- '商务座': 9,
- '硬座': 1,
- '无座': 1,
- '软座': 2,
- '软卧': 4,
- '硬卧': 3,
- }
- # 软件版本
- RE_VERSION = "1.1.106"
6. 运行程序开始抢票
直接使用以下命令进行抢票即可:
sudo python run.py
看到软件帮你自动抢票了
代码导读
总体而言这个抢票项目设计思路清昕, 有很多地方值得一读, 先给大家带来以下两部分
1, 使用 Selenium 得到 cookie 的 device_id, 具体在~/config/getCookie.py
- def getDrvicesID(session):
- """
- :return:
- """ print("cookie 获取中 ")
- if TickerConfig.COOKIE_TYPE is 1:
- from selenium import webdriver# 导入 Selenium 包
- cookies = []
- options = webdriver.ChromeOptions()
- options.add_argument('headless')
- driver = webdriver.Chrome(chrome_options=options,
- executable_path=TickerConfig.CHROME_PATH)# 设置的 chrome_driver 的地址
- driver.get("https://www.12306.cn/index/index.html")
- time.sleep(10)
- #根据 cookie 的 name 来获得
- for c in driver.get_cookies():
- cookie = dict()
- if c.get("name") == "RAIL_DEVICEID" or c.get("name") == RAIL_EXPIRATION":
- cookie[c.get("name")] = c.get("value")
- cookies.append(cookie)
- if cookies:
- session.httpClint.set_cookies(cookies)
- print("cookie 获取完成")
- elif TickerConfig.COOKIE_TYPE is 2:
- request_device_id(session)
2, 是自动打码的部分, 在~/verify/localVerifyCode.py
- def verify(fn):
- backend.clear_session()
- verify_titles = ['打字机', '调色板', '跑步机', '毛线', '老虎', '安全帽', '沙包', '盘子', '本子', '药片', '双面胶', '龙舟', '红酒', '拖把', '卷尺', '海苔', '红豆', '黑板', '热水袋', '烛台', '钟表', '路灯', '沙拉', '海报', '公交卡', '樱桃', '创可贴', '牌坊', '苍蝇拍', '高压锅', '电线', '网球拍', '海鸥', '风铃', '订书机', '冰箱', '话梅', '排风机', '锅铲', '绿豆', '航母', '电子秤', '红枣', '金字塔', '鞭炮', '菠萝', '开瓶器', '电饭煲', '仪表盘', '棉棒', '篮球', '狮子', '蚂蚁', '蜡烛', '茶盅', '印章', '茶几', '啤酒', '档案袋', '挂钟', '刺绣', '铃铛', '护腕', '手掌印', '锦旗', '文具盒', '辣椒酱', '耳塞', '中国结', '蜥蜴', '剪纸', '漏斗', '锣', '蒸笼', '珊瑚', '雨靴', '薯条', '蜜蜂', '日历', '口哨']
- # 读取并预处理验证码
- img = base64_to_image(fn)# 将 img 转换
- text = get_text(img)
- imgs = np.array(list(pretreatment._get_imgs(img)))
- imgs = preprocess_input(imgs)
- text_list = []
- # 识别文字
- model = models.load_model(PATH('../model.v2.0.h5'))# 使用之前的 model 识别文字
- label = model.predict(text)
- label = label.argmax()
- text = verify_titles[label]
- text_list.append(text)
- # 获取下一个词
- # 根据第一个词的长度来定位第二个词的位置
- if len(text) == 1:
- offset = 27
- elif len(text) == 2:
- offset = 47
- else:
- offset = 60
- text = get_text(img, offset=offset)
- if text.mean() < 0.95:
- label = model.predict(text)
- label = label.argmax()
- text = verify_titles[label]
- text_list.append(text)
- print("题目为 {}".format(text_list))
- # 加载图片分类器
- model = models.load_model(PATH('../12306.image.model.h5'))
- labels = model.predict(imgs)
- labels = labels.argmax(axis=1)
- results = []
- for pos, label in enumerate(labels):
- l = verify_titles[label]
- print(pos+1, l)
- if l in text_list:
- results.append(str(pos+1))
- return results
好了, 以上就是对于 12306 抢票工具项目的全部简介, 在这里也对项目的原作者 testerSunshine 表示感谢, 同时也祝各位早日抢到回家的票!
来源: https://www.qcloud.com/developer/article/1560222