一、导读

本篇文章所采用的技术仅用于学习、研究,任何其他用途请自行承担后果。

12306自动查票使用到的python库主要是splinter,同时也涉及到查票的城市编码,具体的城市编码请在网络上搜索,基本格式如下:

北京北:VAP

北京东:BOP

北京: BJP

北京南:VNP

北京西:BXP

实现的功能包括:
(1)自动打开Google浏览器,进入12306登录页面
(2)命令行手动输入账号、密码、出发、目的地,时间等相关信息,登录验证图片需要手动选择。
(3)自动填充输入,完成查询和页面跳转。

后续可以优化的功能:
(1)从配置文件中读取账号、密码、出发、目的地,时间等相关信息。
(2)从配置文件中获取城市编码
(3)登录验证图片可以使用第三方识别自动选择

二、初识Splinter

1.简介

Splinter 是用 Python 开发的一个开源web自动化测试的工具集。 它可以帮你自动化浏览器的行为,比如浏览 URLs 并和页面进行交互。

Splinter是现有浏览器之上抽象层自动化工具(如 SeleniumPhantomJS 和 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自动查票的更多相关文章

  1. Python实现12306自动查票程序

    这是在网上扒拉过来的,原文链接: http://blog.csdn.net/An_Feng_z/article/details/78631290 目前时间2018/01/04 文中各种接口均为可用,亲 ...

  2. 利用Python实现12306爬虫--查票

    在上一篇文章(http://www.cnblogs.com/fangtaoa/p/8321449.html)中,我们实现了12306爬虫的登录功能,接下来,我们就来实现查票的功能. 其实实现查票的功能 ...

  3. Python实例--12306的抢票功能

    基础知识学习 目标: 通过python程序实现自动登录下单功能 知识点: Selenium + 云打码 + Python 学习链接: 1. Python学习--Selenium模块 2. Python ...

  4. python+selenium实现自动抢票

    使用说明 程序运行开始,需要输入出发地,目的地,出发时间,乘客信息,车次:乘客信息和车次可以输入多个 刚刚开始学习爬虫,selenium仅仅是解放了双手,运行效率不是很高: 程序运行时会打开chrom ...

  5. 基于selenium+java的12306自动抢票

    import java.util.concurrent.TimeUnit; import org.openqa.selenium.By;import org.openqa.selenium.Keys; ...

  6. vue+node+mongoDB火车票H5(七)-- nodejs 爬12306查票接口

    菜鸟一枚,业余一直想做个火车票查票的H5,前端页面什么的已经写好了,node+mongoDB 也写了一个车站的接口,但 接下来的爬12306获取车次信息数据一直卡住,网上的爬12306的大部分是pyt ...

  7. 利用Python攻破12306的最后一道防线

    各位同学大家好,我是强子,好久没跟大家带来最新的技术文章了,最近有好几个同学问我12306自动抢票能否实现,我就趁这两天有时间用Python做了个12306自动抢票的项目,在这里我来带着大家一起来看看 ...

  8. python写12306抢票

    #!/usr/bin/env python # -*- coding: utf-8 -*- ''' 利用splinter写的一个手动过验证及自动抢票的例子, 大家可以自己扩展或者弄错窗体.web端. ...

  9. 【java下午茶】12306的双人票

    明天下午就要和客户谈需求了,今天还在列车上假象着明天的情景,由于这是一个旅游的项目,所以想尽可能设计得人性化一些. 不过有件很不爽的事情就是和老公的位子是分开的,虽然我们订的是连坐号.就这个问题也是我 ...

随机推荐

  1. vs2010修改状态栏的CStatusBar指针的的SetPaneText()方法时死活不对问题

    vs2010的mfc在有些地方不太一样不容易注意到,今天在修改状态栏的时候,就碰见了问题,死活修改不了. 参照下面的帖子: 点击打开链接 : 使用VS2010更改MFC程序的状态栏 2011-04-1 ...

  2. Mac OS X 10.10优胜美地如何完美接管iphone上的电话和短信

    自从今年苹果第一次的发布会上毛猫就特别注意这个功能,感觉特别Cool,特别方便.但直到今天毛猫才第一次成功测试出这个功能呀!虽然handoff功能还未测出来,但是觉得在mac上发短信和打电话也已经足够 ...

  3. PyCharm导入pymysql包运行报错问题解决:No module named 'PyMySQL'

    import pymysql # 导入包 # 报错问题显示: ImportError: No module named 'PyMySQL' 出现该问题提示:找不到该包名. 解决办法如下: ①先下载Py ...

  4. % 与 format 进行字符串格式化

    字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 1.百分号方式 %[(name)][flags][width].[precision]typecode (name) ...

  5. Selenium高级篇Web自动化测试框架

    现在常用的是对象模型PO(Page Object), 从过去要知道具体的定位,返回使用现在只需要知道所在页面的名称即可访问页面对象即可看到该页面的元素 PageObject实现了对页面对象及方法的抽离 ...

  6. 关于django migrations的使用

    django 1.8之后推出的migrations机制使django的数据模式管理更方便容易,现在简单谈谈他的机制和一些问题的解决方法: 1.谈谈机制:migrations机制有两个指令,第一个是ma ...

  7. redis安装、使用

    官网:http://redis.io/ github地址:https://github.com/antirez/redis 简介:         redis是一个key-value存储系统.和Mem ...

  8. 利用nginx解决cookie跨域

    一.写在前面 最近需要把阿里云上的四台服务器的项目迁移到客户提供的新的项目中,原来的四台服务器中用到了一级域名和二级域名.比如aaa.abc.com 和bbb.abc.com 和ccc.abc.com ...

  9. [ SSH框架 ] Struts2框架学习之三(OGNl和ValueStack值栈学习)

    一.OGNL概述 1.1 什么是OGNL OGNL的全称是对象图导航语言( object-graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可 ...

  10. Python_数据整理与写入

    ''' 假设文件data.txt中有若干整数,整数之间使用英文逗号分隔.编写程序读取所有整数,将其按升序后再写入文本文件datta_asc.txt中 ''' import random countNu ...