⼿把⼿教你⽤python抢票回家过年(代码简单)
⾸先看看如何快速查看剩余⽕车票?
当你想查询⼀下⽕车票信息的时候,你还在上12306官⽹吗?或是打开你⼿机⾥的APP?下⾯让我们来⽤Python写⼀个命令⾏版的⽕车票查看器, 只要在命令⾏敲⼀⾏命令就能获得你想要的⽕车票信息!如果你刚掌握了Python基础,这将是个不错的⼩练习。
接⼝设计
⼀个应⽤写出来最终是要给⼈使⽤的,哪怕只是给你⾃⼰使⽤。所以,⾸先应该想想你希望怎么使⽤它?让我们先给这个⼩应⽤起个名字吧,既然及查询票务信息,那就叫它tickets好了。我们希望⽤户只要输⼊出发站,到达站以及⽇期就让就能获得想要的信息,所以tickets应该这样被使⽤:
$ tickets from to date
另外,⽕车有各种类型,⾼铁、动车、特快、快速和直达,我们希望可以提供选项只查询特定的⼀种或⼏种的⽕车,所以,我们应该有下⾯这些选项:
-g  ⾼铁
-d  动车
-t    特快
-k  快速
-z  直达
这⼏个选项应该能被组合使⽤,所以,最终我们的接⼝应该是这个样⼦的:
$ tickets [-gdtkz] from to date
接⼝已经确定好了,剩下的就是实现它了。
开发环境
写Python程序的⼀个良好实践是使⽤virtualenv这个⼯具建⼀个虚拟的环境。我们的程序使⽤Python3开发,下⾯在你的⼯作⽬录下建⼀个⽂件夹tickets,进去创建⼀个虚拟环境:
$ virtualenv -p /usr/bin/python3 venv
通过下⾯的命令激活它:
$ . venv/bin/activate
解析参数
Python有很多写命令⾏应⽤的⼯具,如argparse, docopt, 这⾥,我们选⽤docopt这个简单易⽤的⼯具,我们先安装它:
$ pip3 install docopt
docopt可以按我们在⽂档字符串中定义的格式来解析参数,在tickets.py中:
下⾯我们运⾏⼀下这个程序:
$ python3 tickets.py 上海北京 2016-07-01
我们得到下⾯的参数解析结果:
获取数据
参数已经解析好了,下⾯就是如何获取数据了,这也是最主要的部分。⾸先我们打开12306,进⼊余票查询页⾯,如果你使⽤chrome,那么按F12打开开发者⼯具,选中Network⼀栏,在查询框钟我们输⼊上海到北京,⽇期2016-07-01, 点击查询,我们在调试⼯具发现,查询系统实际上请求了这个URL
并且返回的是Json格式的数据!接下来问题就简单了,我们只需要构建请求URL然后解析返回的Json数据就可以了。但是我们发现,URL⾥⾯from_station和to_station并不是汉字,⽽是⼀个代号,⽽⽤户输⼊的是汉字,我们要如何获取代号呢?我们打开⽹页源码看看有没有什么发现。
这⾥⾯貌似是包含了所有车站的中⽂名,拼⾳,简写和代号等信息, 我们在项⽬⽬录下将它保存为stations.html。但是这些信息挤在⼀起,⽽我们只想要中⽂名和⼤写字母的代号信息,怎么办呢?
BINGO!正则表达式,我们写个⼩脚本来匹配提取出想要的信息吧, 在parse.py中:
我们运⾏这个脚本,它将以字典的形式返回所有车站和它的⼤写字母代号, 我们将结果重定向到stations.py中,
$ python3 parse.py > stations.py
我们为这个字典加名字,stations, 最终,stations.py⽂件是这样的:
现在,⽤户输⼊车站的中⽂名,我们就可以直接从这个字典中获取它的字母代码了:
万事俱备,下⾯我们来请求这个URL获取数据吧!这⾥我们使⽤requests这个库, 先安装它:
$ pip3 install requests
python代码画图
它提供了⾮常简单易⽤的接⼝,
从结果中,我们可以观察到,与车票有关的信息需要进⼀步提取:
显⽰结果
数据已经获取到了,剩下的就是提取我们要的信息并将它显⽰出来。prettytable这个库可以让我们它像MySQL数据库那样格式化显⽰数据。
$ pip3 install prettytable
这样使⽤它:
其次我们看看如何⾃动抢:
作者:marvin,互联⽹从业者,现居上海张江
使⽤Python+Splinter⾃动刷新抢票,可以成功抢到。(依赖⾃⼰的⽹络环境太厉害,还有机器的好坏)
Splinter是⼀个使⽤Python开发的开源Web应⽤测试⼯具,它可以帮你实现⾃动浏览站点和与其进⾏交互,Splinter执⾏的时
候会⾃动打开你指定的浏览器,访问指定的URL。然后你所开发的模拟的任何⾏为,都会⾃动完成,你只需要坐在电脑⾯前,像看电影⼀样看着屏幕上各种动作⾃动完成然后收集结果即可。
12306抢票Python代码⽚段
实现⾃动登录的函数:
开始购票的函数
附源代码:
# -*- coding: utf-8 -*-
"""
三花玳瑁猫多少钱一只@author: liuyw
"""
from splinter.browser import Browser
from time import sleep
import traceback
import time, sys
class huoche(object):
"""docstring for huoche"""
driver_name=''
executable_path=''
#⽤户名,密码
username = u"xxx@qq"
passwd = u"xxxx"
# cookies值得⾃⼰去, 下⾯两个分别是上海, 太原南
starts = u"%u4E0A%u6D77%2CSHH"
ends = u"%u592A%u539F%2CTYV"
# 时间格式2018-01-19
dtime = u"2018-01-19"
# 车次,选择第⼏趟,0则从上之下依次点击
order = 0
重定向与转发的区别以及实现###乘客名
users = [u"xxx",u"xxx"]
##席位
xb = u"⼆等座"
pz=u"成⼈票"
"""⽹址"""
ticket_url = "kyfw.12306/otn/leftTicket/init"
login_url = "kyfw.12306/otn/login/init"
initmy_url = "kyfw.12306/otn/index/initMy12306"
buy="kyfw.12306/otn/confirmPassenger/initDc"
login_url='kyfw.12306/otn/login/init'
def __init__(self):
self.driver_name='chrome'
def login(self):
self.driver.visit(self.login_url)
self.driver.fill("loginUserDTO.user_name", self.username)
# sleep(1)
self.driver.fill("userDTO.password", self.passwd)
print u"等待验证码,⾃⾏输⼊..."
while True:
if self.driver.url != self.initmy_url:
python请求并解析json数据sleep(1)
else:
break
def start(self):
self.driver=Browser(driver_name=self.driver_name,executable_utable_path) self.driver.driver.set_window_size(1400, 1000)
self.login()
# sleep(1)
self.driver.visit(self.ticket_url)
try:
print u"购票页⾯开始..."
# sleep(1)
# 加载查询信息
kies.add({"_jc_save_fromStation": self.starts})
kies.add({"_jc_save_toStation": ds})
kies.add({"_jc_save_fromDate": self.dtime})
load()
count=0
der!=0:
while self.driver.url==self.ticket_url:
self.driver.find_by_text(u"查询").click()
count += 1
print u"循环点击查询... 第 %s 次" % count
# sleep(1)
try:
self.driver.find_by_text(u"预订")[der - 1].click()
except Exception as e:
print e
print u"还没开始预订"
continue
else:
while self.driver.url == self.ticket_url:
self.driver.find_by_text(u"查询").click()
count += 1
print u"循环点击查询... 第 %s 次" % count
# sleep(0.8)
try:
for i in self.driver.find_by_text(u"预订"):
i.click()
sleep(1)
except Exception as e:
print e
print u"还没开始预订 %s" %count
continue
print u"开始预订..."
# sleep(3)
# load()
sleep(1)
print u'开始选择⽤户...'
for user in self.users:
求反码和补码self.driver.find_by_text(user).last.click()
print u"提交订单..."
sleep(1)
# self.driver.find_by_text(self.pz).click()
# self.driver.find_by_id('').select(self.pz)
# # sleep(1)
# self.driver.find_by_text(self.xb).click()
# sleep(1)
self.driver.find_by_id('submitOrder_id').click()
# print u"开始选座..."
# self.driver.find_by_id('1D').last.click()
# self.driver.find_by_id('1F').last.click()
sleep(1.5)
>江西理工大学宿舍

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。