12306抢票程序配置使用

背景

考虑最近要回家了,然后想起过去每次回家抢火车票的艰辛,就打算自己写一个抢票程序。转眼一想,这么高需求的东西,想来应该有人做过了,所以到github搜索了一波,确实还真有不少。其中排行第一的已经有18.5k的stars了。想来star那么多,应该很稳,所以就以这个为基础,如果可行就直接用,不可行再修改。

事实证明确实还是有蛮大的问题的,代码本身的问题不多,但是毕竟林子大了什么鸟都有,每个人在配置环境的时候总会遇到各种奇奇怪怪的问题。所以直接按照给的教程来的话还是存在很多问题。中间也填了蛮多坑。

然后意外的是,今年回家的票异常好卖,所以觉得可能都差不多,也就没有想着写一个填坑的教程。直到看到朋友圈还在有人为抢票奔波,所以就把之前配置环境时遇到的一些问题整理出来。

在介绍解决方案之前,会先以流程和需求的技术为标准进行划分,介绍一下抢票程序逻辑。然后就是环境配置中遇到的问题和解决。最后根据用户需求,增加了一个购票时间区间的选择功能

抢票程序逻辑

可以简单的将抢票程序分为三个环节:登录,余票查询;下单。

登录环节,需要解决的就是验证码识别问题,(众所周知12306的图片验证码非常没有人性)。如果要自动识别的话,一般会用到图片识别技术,识别图像中存在的东西是什么,具体存在于图像的哪一个位置。然后结合用户名和密码登录就可。

登录之后需要根据用户想要的出发站,到站,实时刷新查看还有没有票。特别是在抢购不定期放票和用户随机退的票的时候。这一步的核心就是要能把余票情况爬下来。要用到的技术就是爬虫技术,想要了解到详细内容可以看这个余票查询介绍

然后根据爬下来的余票情况,再根据用户的需求,比如车次,车辆类型(高铁动车,快车,直达。。。)出发时间,位置情况(如一等,二等,卧铺,坐票。。。)。这就是下单过程,这一部分没有什么比较难的技术,就是条件匹配筛选。

抢票程序

在github上看了一圈后,选择了这个star数18.5k的抢票代码.虽然star数很高,但是环境配置的教程写的有些不够准确。而且代码本身还有一些需要的地方。不过代码的结构很好,修改很方便,而且因为经过了多次迭代,逻辑没有大的问题。

前言

我安装的方法是按照教程的流程来的,然后利用conda单独新建了一个虚拟环境,大家如果也是用虚拟环境的话应该差别不会很大。无论是windows还是ubuntu理论上应该都一样。其次就是不会受到之前装的包的影响。所以还是推荐大家使用虚拟环境配置。如果利用conda,利用虚拟环境配置的话,这篇教程应该能解决你的绝大部分,甚至所有问题。

所以教程是假设大家已经安装了anaconda3,并且使用conda 虚拟环境配置的前提下,对可能遇到的问题分析。如果不使用虚拟环境,也可能会遇到这些问题。但是可能就不止这些问题了。

其次不推荐使用docker安装!!!,虽然这个东西看起来很方便,但是好像docker镜像有问题,而且出了问题还不知道怎么修改。所以还是推荐大家自己配置环境。当然要是对docker很了解,觉得自己可以解决其中遇到任何的问题,可以使用docker。

还有,在安装下载ChromeDriver的时候,注意它和chrome浏览器的版本对应关系。我因为最开始就直接选好了版本,所以没有这个问题。但是如果版本选择不对,可能还是会出现问题。版本对应关系可以在这个链接查看

虽然有用到tensorflow,但是基本不需要看这一部分代码。模型在仓库中也自带了,不需要额外下载。其次也不需要GPU,不需要GPU,不需要GPU。重要的事情说三遍。靠CPU就可以跑这个模型。所以机器学习这一块,只要tensorflow装好,其他基本就没有问题了。

如果还遇到了其他问题,那就在issue中搜索一番,一般来说都能找到一些解决思路。而且还可以尝试去多个项目中搜索而不局限于我们选择的这个项目。github上搜索12306还是有很多可以参考的项目的,这个只是其中一个。

问题和解决

  • a

    • 错误

      1
      sendServerChanUrls["req_url"] += f'{secret}.send'
    • 原因

      f函数在python3中才支持,如果python 运行,一般默认是python2,如果你只装了python3那就当我没说。然后教程给出直接是python run.py,就可能会出这个错。

    • 解决
      1
      sudo python3 run.py
  • b

    • 错误

      tensorflow安装错误

    • 原因

      在requestments中用到的tensorflow版本是1.15rc01,但是好像安装的时候是没有这个版本的,不知道是不是后来被删除了。

    • 解决

      采用一个接近的版本就好了,比如我安装了1.14rc01

  • c

    • 错误

      安装tensorflow报错Memory error

    • 原因

      未知

    • 解决

      pip install --no-cache-dir tensorflow==1.14rc01
      
  • d

    • 错误

      unknown error: DevToolsActivePort file 
      
    • 原因

      服务器没有图形化界面运行错误

    • 解决

      修改config/getCookie.py,向webdriver.chrome()函数传入额外参数,关闭沙箱模式、无头运行chrome。代码如下图所示

      1
      2
      3
      4
      5
      6
      7
      15         from selenium import webdriver
      16 options= webdriver.ChromeOptions()
      17 options.add_argument('--headless')
      18 options.add_argument('--no-sandbox')
      19
      20 cookies = []
      21 driver = webdriver.Chrome(executable_path=TickerConfig.CHROME_PATH,chrome_options=options)
  • e

    • 错误

      1
      Non-ASCII character '\xe5
    • 原因

      字符格式问题

    • 解决

      在TickerConfig.py开头 增加 # -- coding=utf-8 --,好像新的版本已经解决了这个问题

  • f

    • 错误

      1
      WebDriverException:Message:'chromedriver' executable needs to be in PATH
    • 原因

      使用docker时候出现的问题,而且自己单独利用官方测试代码测试了,如果不在docker环境内使用是没有问题的。猜测是docker环境本事是一个独立容器,所以可能和系统完全隔离开了,访问不了系统中文件。

      或者如果是windows用户,可能是没有把chromedriver.exe执行文件放到chrome浏览器目录下。至于为什么这样会报错,也不是很清楚。

    • 解决

      不使用docker镜像,然后自己建立一个虚拟环境,配置环境,同样的指定路径的方式,就没有这个问题。

      将chromedriver.exe放到chrome浏览器目录下,如((如 C:\Program Files\Google\Chrome\Application))

  • g

    • 错误

      /passport/web/login返回参数为空, 接口状态码: 302

    • 原因

      如果是登录时候遇到这个问题,可以先等上几分钟,做些其他事情。如果还是不行。可能就是ip被封了。如果是登录成功了,但是爬虫尝试去爬取余票情况的时候遇到这个问题。估计是查询的接口变了,12306为了防止恶意刷票,一般一天或者几天就会把查票接口改一下。

    • 解决

      如果是登录遇到这个问题,而且等了几分钟还不行就换一台电脑或者在局域网环境下改一个IP,再去尝试了最简单的就是换一个wifi。如果这样还不行,那封的可能就是你的账号了,就只能等官网解封了。这时候你如果还想买票只能用12306 app了。

      如果是查询余票的时候遇到这个问题。可以自己先登录12306官网,随便选择一个出发站,达到站,点击查询。然后按F12查看网页源码。点击 init?linktypeid=dc 文件,看第14行查票接口是什么。然后在源代码 select_ticket_info.py的第45行将查票接口改成现在的接口。

      如果改了接口还不行,注意看看自己的时间格式是不是正确的,注意如果要买1月16号的票,不能写成 “2020-1-16”,需要写成“2020-01-16”。否则就算改了查询接口,还是会报错,我最开始就在这里卡住了半天

修补

原程序中没有时间区间的限制。也就是,将余票情况都爬取下来,按照时间顺序来检索。然后就有可能出现,抢到了早上六点的票,但是实际上你并不想要这个票,所以基于这个需求,在原始代码的基础上增加了时间区间的限制。

配置的方式和其他限制条件一样,都在TickerConfig.py中配置

实践

如果大家对对相关内容都不怎么了解的,而又想使用的话,可以按照下面的流程进行配置。唯一需要的是装好一个anaconda3,以及一点点的python知识。如果你连这些都没有,那么再见。。。

下面的配置流程是在win10上进行的,ubuntu应该也是类似的。

  • 下载源码并解压
    • 我的仓库中下载源码.大家也可以在原始仓库中下载最新源码,可能会增加新功能,也可能会增加新bug,所以如果是小白,还是推荐到我的仓库中下载,而不是去下载最新的代码。至少就目前的版本而言功能已经很充分了。
  • 创建conda环境

    • 打开cmd环境,然后输入下面代码
      1
      conda create -n 12306 python=3.6 pip
  • 安装环境依赖

    • 在cmd中 利用cd 命令进入到下载代码的工程目录中。
    • 然后在命令行中依次输入如下代码:
      1
      2
      3
      conda activate 12306
      python -m pip install --upgrade pip
      pip install -r requirements.txt
  • 下载合适版本chromedriver

    • 在Chrome浏览器设置–关于chrome中查看chrome版本
    • 版本对应关系 这个链接中查看版本对应关系
    • 在这个下载链接中下载对应版本的chromedriver
    • 解压放到chrome浏览器目录下,放到chrome浏览器目录下,放到chrome浏览器目录下,重要的是说三遍((如 C:\Program Files\Google\Chrome\Application))
  • 配置提醒服务

    • 这里有两个选择,邮箱和sever酱,如果有github账户的话,其实两个配置复杂程度差不多。不然邮件配置应该会相对简单一些。
    • 以QQ邮箱为例
      • 登录QQ邮箱—设置—常规—STMP服务—开启
      • 如果本来已经开启了,就直接看下面有获取授权码的提示,获取授权码。
      • 然后剩下的就简单了,TickerConfig.py的82行处,email,note_email,username 都填你的邮箱,password填授权码
      • 邮箱的配置就结束了
    • 下面的是sever酱配置流程
    • 注册一个github账号
      • 如果有了直接跳过,如果没有也很简单
      • 按照这个教程完成第一大步就可以
    • 到这个链接中进行配置
    • 最好直接再测试一下是否成功
      • python run.py t
  • 修改 TickerConfig.py信息

    • 修改个人信息
    • 94行填入你的server酱的secret
    • 123行,修改你的chromedriver路径,你放在哪就填哪
    • 其他的配置用默认配置就可以,如果你还想修改,可以跑通之后再修改
  • 修改查询余票接口

    • 在这个连接中,随机选择出发站,终点站,日期,然后查询
    • 按下F12,或者设置–更多工具,开发者工具
    • 在弹出界面中找到 /init?linktypeid开头文件,点击
    • 第14行查看查票接口,特别关注最后一个大写字母
    • 和/init/select_ticket_info.py的46行对比,看看最后一个大写字母是否一样,不一样的话改成现在网页的这个大写字母
  • 运行

    1
    2
    3
    python run.py t
    python run.py c
    python run.py r