python之12306自动查票

一、导读
本篇文章所采用的技术仅用于学习、研究,任何其他用途请自行承担后果。
12306自动查票使用到的python库主要是splinter,同时也涉及到查票的城市编码,具体的城市编码请在网络上搜索,基本格式如下:
北京北:VAP
北京东:BOP
北京: BJP
北京南:VNP
北京西:BXP
实现的功能包括:
(1)自动打开Google浏览器,进入12306登录页面
(2)命令行手动输入账号、密码、出发、目的地,时间等相关信息,登录验证图片需要手动选择。
(3)自动填充输入,完成查询和页面跳转。
后续可以优化的功能:
(1)从配置文件中读取账号、密码、出发、目的地,时间等相关信息。
(2)从配置文件中获取城市编码
(3)登录验证图片可以使用第三方识别自动选择
二、初识Splinter
1.简介
Splinter 是用 Python 开发的一个开源web自动化测试的工具集。 它可以帮你自动化浏览器的行为,比如浏览 URLs 并和页面进行交互。
Splinter是现有浏览器之上抽象层自动化工具(如 Selenium, PhantomJS 和 zope.testbrowser )。它具有 高级API ,这使得它很容易去编写Web应用程序的自动化测试。
例如, 用Splinter填写一个表单项:
browser.fill('username', 'janedoe')
在Selenium中, 等效代码会是:
elem =browser.find_element.by_name('username') elem.send_keys('janedoe')
2.安装
命令行下执行以下命令: sudo pip install splinter
3.快速上手
(1)导入Browser类
from splinter.browser import Browser
(2)创建一个实例
指定driver为chrome浏览器,如果你不为 Browser 指定 driver, 那么会默认使用 firefox。
browser = Browser(driver_name='chrome',executable_path='xxx')
其中executable_path为对应浏览器driver的本地目录。
(3)访问百度搜索页面
使用 browser.visit 方法可访问任意网站:
browser.visit('http://baidu.com')
(4)输入搜索关键词
页面加载完毕后,可以在输入框填充字段,大过年的我们就搜索一下2018年新年祝福吧:
browser.fill('wd', '2018年新年祝福')
(5)点击搜索按钮
Splinter 可以通过按钮的css, xpath, id, tag 或 name来识别,百度搜素按钮使用以下来操作:
button = browser.find_by_xpath('//input[@type="submit"]').click()
(6)匹配结果
使用is_text_present查看匹配结果:
if browser.is_text_present('春节'): print("找到了") else: print("没找到")
(7)关闭浏览器
结束测试后,我们需要使用 browser.quit 关闭浏览器:
browser.quit()
完整代码如下:
# -*- coding: utf-8 -*- #导入Browser类 from splinter.browser import Browser #创建一个实例, 指定driver为chrome浏览器,如果你不为 Browser 指定 driver, 那么会默认使用 firefox。 browser = Browser(driver_name='chrome',executable_path='/Users/xxx/Downloads/chromedriver') browser.visit('http://baidu.com') browser.fill('wd', '2018年新年祝福') button = browser.find_by_xpath('//input[@type="submit"]').click() if browser.is_text_present('春节'): print("找到了") else: print("没找到") browser.quit()
三、12306自动查票
1、流程分析
(1)执行python脚本后,能够自动打开浏览器,进入12306登录页面。因此需要加载浏览器驱动并打开登录页面。
(2)命令行提示用户输入用户名、密码,并等待用户手动在浏览器选择验证码完成登录。
(3)命令行提示用户输入出发地、目的地以及出发时间。
(4)根据输入查询车次信息
2、示例代码
代码均有详细注释,根据上面的流程分析,我们简化为三步。
第一步是加载基本信息,包括浏览器、url等。第二步是输入个人信息登录。第三步是输入查询条件查询车次信息。
# -*- coding: utf-8 -*- from splinter.browser import Browser from time import sleep class TicketsUtil(object): def __init__(self): self.loadBasicInfo() def loadBasicInfo(self): # 登录的url self.loginUrl = 'https://kyfw.12306.cn/otn/login/init' #登录成功后的url self.myUrl = 'https://kyfw.12306.cn/otn/index/initMy12306' #余票查询页面 self.ticketUrl = 'https://kyfw.12306.cn/otn/leftTicket/init' # 初始化驱动 self.driver=Browser(driver_name='chrome',executable_path='/Users/xxx/Downloads/chromedriver') # 初始化浏览器窗口大小 self.driver.driver.set_window_size(1400, 1000) def login(self): print("开始登录...") # 登录 self.driver.visit(self.loginUrl) self.username = input("\n请输入用户名,输入按回车...") #合法性判断 while True: if self.username == '': self.username = input("\n请输入用户名,输入按回车...") else: break self.password = input("\n请输入密码,输入按回车...") #合法性判断 while True: if self.password == '': self.password = input("\n请输入密码,输入按回车...") else: break # 自动填充用户名 self.driver.fill("loginUserDTO.user_name", self.username) # 自动填充密码 self.driver.fill("userDTO.password", self.password) print(u"等待验证码,自行输入...") # 验证码需要自行输入,程序自旋等待,直到验证码通过,点击登录 while True: if self.driver.url != self.myUrl: sleep(1) else: break print(u"登录成功...") def query(self): self.source = input("\n请输入出发地(格式为:北京,BJP),输入按回车...") #合法性判断 while True: if self.source == '': self.source = input("\n请输入出发地(格式为:北京,BJP),输入按回车...") else: break self.destination = input("\n请输入目的地(格式为:深圳,SZQ),输入按回车...") while True: if self.destination == '': self.destination = input("\n请输入目的地(格式为:深圳,SZQ),输入按回车...") else: break self.date = input("\n请输入出发日期(格式为:2018-02-14),输入按回车...") while True: if self.date == '': self.date = input("\n请输入出发日期,输入按回车...") else: break #转换输入的出发地成"武汉,WHN",再进行编码 self.source = self.source.encode('unicode_escape').decode("utf-8").replace("\\u", "%u").replace(",", "%2c") #转换输入的目的地 self.destination = self.destination.encode('unicode_escape').decode("utf-8").replace("\\u", "%u").replace(",", "%2c") # 加载出发地 self.driver.cookies.add({"_jc_save_fromStation": self.source}) # 加载目的地 self.driver.cookies.add({"_jc_save_toStation": self.destination}) # 加载出发日 self.driver.cookies.add({"_jc_save_fromDate": self.date}) # 带着查询条件,重新加载页面 self.driver.reload() # 查询余票 self.driver.find_by_text(u"查询").click() sleep(0.1) # 防止超时再次查询余票 self.driver.find_by_text(u"查询").click() print('查询成功') """入口函数""" def start(self): self.loadBasicInfo() # 登录,自动填充用户名、密码,自旋等待输入验证码,输入完验证码,点登录后,访问 tick_url(余票查询页面) self.login() # 登录成功,访问余票查询页面 self.driver.visit(self.ticketUrl) self.query() if __name__ == '__main__': print(u"===========自动查票开启===========") ticketsUtil = TicketsUtil() ticketsUtil.start()
python之12306自动查票的更多相关文章
- Python实现12306自动查票程序
这是在网上扒拉过来的,原文链接: http://blog.csdn.net/An_Feng_z/article/details/78631290 目前时间2018/01/04 文中各种接口均为可用,亲 ...
- 利用Python实现12306爬虫--查票
在上一篇文章(http://www.cnblogs.com/fangtaoa/p/8321449.html)中,我们实现了12306爬虫的登录功能,接下来,我们就来实现查票的功能. 其实实现查票的功能 ...
- Python实例--12306的抢票功能
基础知识学习 目标: 通过python程序实现自动登录下单功能 知识点: Selenium + 云打码 + Python 学习链接: 1. Python学习--Selenium模块 2. Python ...
- python+selenium实现自动抢票
使用说明 程序运行开始,需要输入出发地,目的地,出发时间,乘客信息,车次:乘客信息和车次可以输入多个 刚刚开始学习爬虫,selenium仅仅是解放了双手,运行效率不是很高: 程序运行时会打开chrom ...
- 基于selenium+java的12306自动抢票
import java.util.concurrent.TimeUnit; import org.openqa.selenium.By;import org.openqa.selenium.Keys; ...
- vue+node+mongoDB火车票H5(七)-- nodejs 爬12306查票接口
菜鸟一枚,业余一直想做个火车票查票的H5,前端页面什么的已经写好了,node+mongoDB 也写了一个车站的接口,但 接下来的爬12306获取车次信息数据一直卡住,网上的爬12306的大部分是pyt ...
- 利用Python攻破12306的最后一道防线
各位同学大家好,我是强子,好久没跟大家带来最新的技术文章了,最近有好几个同学问我12306自动抢票能否实现,我就趁这两天有时间用Python做了个12306自动抢票的项目,在这里我来带着大家一起来看看 ...
- python写12306抢票
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' 利用splinter写的一个手动过验证及自动抢票的例子, 大家可以自己扩展或者弄错窗体.web端. ...
- 【java下午茶】12306的双人票
明天下午就要和客户谈需求了,今天还在列车上假象着明天的情景,由于这是一个旅游的项目,所以想尽可能设计得人性化一些. 不过有件很不爽的事情就是和老公的位子是分开的,虽然我们订的是连坐号.就这个问题也是我 ...
随机推荐
- spring+mybaits多数据源使用
一.在利用spring管理mybatis时可以同时配置多个数据源,并且数据源可以随时切换,但在多线程中多数据源的事务需要一定的配置. 多数据源配置: <bean id="postgre ...
- web报表工具finereport常用函数的用法总结(数组函数)
ADD2ARRAY ADDARRAY(array,insertArray, start):在数组第start个位置插入insertArray中的所有元素,再返回该数组. 示例: ADDARRAY([3 ...
- LeetCode刷题之合并排序链表
合并两个有序链表并返回一个新的列表.新列表应该由连接在一起的节点前两个列表 给定实例:Input: 1->2->4, 1->3->4Output: 1->1->2- ...
- C#编译器优化那点事
使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置和debug配置,有一个关键区别,就是release的编译器优化默认是启用的. 优化代码开关即optimize开 ...
- 我的sql数据库存储过程分页- -
以前用到数据库存储过程分页的时候都是用 not in 但是最近工作的时候,随着数据库记录的不断增大,发现not in的效率 真的不行 虽然都设置了索引,但是当记录达到10w的时候就发现不行了,都是需要 ...
- classes目录中没有class文件的一个原因
可能是你的build设置有问题:比如本来有的jar被删除的情况下.build不会报错,但是classes目录下什么都没有.
- Python Django开发中XSS内容过滤问题的解决
from:http://stackoverflow.com/questions/699468/python-html-sanitizer-scrubber-filter 通过下面这个代码就可以把内容过 ...
- 模仿天猫实战【SSM】——总结
第一篇文章链接:模仿天猫实战[SSM版]--项目起步 第二篇文章链接:模仿天猫实战[SSM版]--后台开发 总结:项目从4-27号开始写,到今天5-7号才算真正的完工,有许多粗糙的地方,但总算完成了, ...
- mysql经典面试题
数据库优化:这个优化法则归纳为5个层次:1. 减少数据访问(减少磁盘访问)2. 返回更少数据(减少网络传输或磁盘访问)3. 减少交互次数(减少网络传输)4. 减少服务器CPU开销(减少CPU及内存开销 ...
- RDC去省赛玩前の日常训练 Chapter 2
2018.4.9 施展FFT ing! 马上就要和前几天学的斯特林数双剑合璧了!