背景
考虑最近要回家了,然后想起过去每次回家抢火车票的艰辛,就打算自己写一个抢票程序。转眼一想,这么高需求的东西,想来应该有人做过了,所以到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
715 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应该也是类似的。
- 下载源码并解压
创建conda环境
- 打开cmd环境,然后输入下面代码
1
conda create -n 12306 python=3.6 pip
- 打开cmd环境,然后输入下面代码
安装环境依赖
- 在cmd中 利用cd 命令进入到下载代码的工程目录中。
- 然后在命令行中依次输入如下代码:
1
2
3conda activate 12306
python -m pip install --upgrade pip
pip install -r requirements.txt
下载合适版本chromedriver
配置提醒服务
- 这里有两个选择,邮箱和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
3python run.py t
python run.py c
python run.py r