精华内容
下载资源
问答
  • 总体设计所谓抢票软件,本质上就是基于浏览器驱动,实现登录、预定、确认信息的自动化。购买列车票涉及4个网页,相应的基本流程如下:登录:输入用户名、密码,识别验证码,点击“登录”;基本信息填写:出发地,...

    总体设计

    所谓抢票软件,本质上就是基于浏览器驱动,实现登录、预定、确认信息的自动化。购买列车票涉及4个网页,相应的基本流程如下:

    image-8.png

    登录:输入用户名、密码,识别验证码,点击“登录”;

    基本信息填写:出发地,目的地,出发日期,车票类型(普通或学生),车次类型选择,点击“查询”,如果目标车次尚有余票则点击“预定”,否则再次点击查询……;

    订单信息填写:乘车人选择,席别选择,票种选择,点击“提交订单”;

    订单确认:选择座位位置,点击“确认”。

    详细设计

    总体设计理清了抢票的主要步骤,进一步需要明确每个步骤中需要注意的问题。

    1. 登录

    登录过程中,自动输入用户名和密码比较简单,难点在于识别验证码。截至目前,各种自动识别验证码的方案准确率都不高,因此,本文采用“人工辅助”识别验证码,即:识别验证码由人工完成,选择图形验证码后点击“登录”。

    image-9.png

    2. 基本信息填写、查询、预定

    整体上没有难点,但需要注意,出发地和目的地可能有多个车次,每个车次有多种席别,乘车方案可能比较复杂,比如:路途较远的情况下,对于 G 字头、D字头列车,二等座及以上可接受;对于 K 字头、T 字头列车,硬卧及以上可接受……。如此,在抢票的时候,需要按优先级轮询各种方案。以杭州 -> 成都为例,有 5 个车次可选,如下所示:

    image-10.png

    3. 订单信息填写

    乘车人列表中可能有多个人的信息(如果你曾经帮别人买过车票的话,注册信息会保留),需要选择正确的乘车人、票种和席别,如下例子所示:

    image-11.png

    4. 订单确认

    这一步很简单,点击“确认”即可,毕竟春运期间抢票,一般不会在意位置,能抢到已是幸运。

    image-12.png

    准备工作

    根据总体设计,可以将抢票程序规划为 5 个主要函数:

    __init__():初始化

    login_proc():登录模块

    filling_proc():基本信息填写模块

    booking_proc():查询、预订、订单信息填写模块

    confirm_proc():订单确认模块

    1. 浏览器驱动

    本文介绍的抢票软件基于 Chrome 浏览器,因此,需要下载与之版本匹配的驱动 chromedriver(附:下载网址)。注意与自己的 Chrome 版本对应,步骤如下:

    首先,查看 Chrome 的版本,选择“设置” -> “关于 Chrome”,如下图版本为 66.x。

    image-13.png

    然后,进入 chromedriver 下载网址,根据 notes.txt 文件提供的信息选择正确版本的驱动。如下图,chromedriver2.38 支持 Chrome 版本为65-67:

    image-14.png

    2. Selenium 模块准备

    Selenium 是一个用于 Web 应用程序自动化测试的工具,可直接运行在浏览器中,模拟真实用户操作。支持的浏览器包括 IE、Mozilla Firefox、Safari、Chrome、Opera 等。由于其功能强大,被广泛应用于网络爬虫的开发,本文将用它作为抢票程序的核心模块(附:下载及安装方法)。

    3. 必要信息准备

    列车购票官网经过数次改革,出发地、目的地、车次、席别等都不是明文,而是以编码表示,因此,需要提前准备好这些信息。信息获取方法:谷歌浏览器打开 12306 官网购票页面,鼠标右键“查看”可以获取到上述信息,以杭州 -> 成都为例:

    #自定义变量区

    value_fromstation = '%u676D%u5DDE%2CHZH' # 始发站(杭州)

    value_tostation = '%u6210%u90FD%2CCDW' # 终点站(成都)

    value_date = '2018-05-10' # 出发时间

    username=u"username" # 用户名

    password="password" # 密码

    #杭州-成都:车次&席别&预定

    #车次信息字典,数据分别表示车次、一等座ID、二等座ID、无座ID、对应车次的预定按钮ID

    train_info = {"D2222":[['ZY_56000D222251', 'ZE_56000D222251', 'WZ_56000D222251'], 'ticket_56000D222251'],

    "D2262":[['ZY_56000D226251', 'ZE_56000D226251', 'WZ_56000D226251'], 'ticket_56000D226251']}

    车次、票种编码,主要网页 URL 是固定的,如下:

    #车票类型字典,"学生票"和"普通票"对应的ID

    ticket_type_dict = {'student': '//input[@name="sf" and @id="sf1"]',

    'common': '//input[@name="sf" and @id="sf2"]'}

    #车次类型字典

    train_type_dict = {'T': '//input[@name="cc_type" and @value="T"]', # 特快

    'G': '//input[@name="cc_type" and @value="G"]', # 高铁

    'D': '//input[@name="cc_type" and @value="D"]', # 动车

    'Z': '//input[@name="cc_type" and @value="Z"]'} # 直达

    #登陆页面url

    login_url = 'https://kyfw.12306.cn/otn/login/init'

    #个人信息页面url

    initmy_url = "https://kyfw.12306.cn/otn/index/initMy12306"

    #订票页面url

    book_url = 'https://kyfw.12306.cn/otn/leftTicket/init'

    #乘客选择页面url

    confirm_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'

    登陆模块 login_proc() 设计

    请参见下面代码:

    def __init__(self):

    """

    Info:构造函数,创建一个浏览器对象

    """

    print(u"欢迎使用列车订票工具")

    self.driver = webdriver.Chrome(self.driver_path)

    self.driver.implicitly_wait(300)

    def login_proc(self):

    """

    Info:登陆过程处理函数,其中图形验证码需要手动选择

    """

    self.driver.get(self.login_url)

    # sign in the user name

    try:

    self.driver.find_element_by_id("username").send_keys(self.username)

    self.driver.find_element_by_id("password").send_keys(self.password)

    except Exception as err:

    print(u"输入用户名或密码失败!",err)

    #点击验证码,人工辅助,目前识别图形验证码比较困难,因此选择人工辅助

    print(u"请自行选择验证码,点击登陆")

    while True:

    if(self.driver.current_url != self.initmy_url):

    time.sleep(1)

    else:

    print('Login finished!')

    break

    基本信息填写模块 filling_proc() 设计

    请参见下面代码:

    def filling_proc(self,train_type,ticket_type):

    """

    Info:填写起始站,终点站,出发时间,车次类型,车票类型等信息

    """

    print (u'列车类型:', train_type)

    print (u'车票类型:', ticket_type)

    # 打开订票网页

    self.driver.get(self.book_url)

    # 选择始发站

    self.driver.add_cookie({"name": "_jc_save_fromStation", "value": self.value_fromstation})

    # 选择终点站

    self.driver.add_cookie({"name": "_jc_save_toStation", "value": self.value_tostation})

    # 选择出发日期

    self.driver.add_cookie({"name": "_jc_save_fromDate", "value": self.value_date})

    self.driver.refresh()

    # 选择车次类型

    if (train_type == 'T' or train_type == 'G' or train_type == 'D' or train_type == 'Z'):

    self.driver.find_element_by_xpath(self.train_type_dict[train_type]).click()

    else:

    print (u"车次类型异常或未选择!(train_type=%s)" % train_type)

    # 选择车票类型

    if (ticket_type == 'student' or ticket_type == 'common'):

    self.driver.find_element_by_xpath(self.ticket_type_dict[ticket_type]).click()

    else:

    print (u"车票类型异常或未选择!(train_type=%s)" % ticket_type)

    查询、预订、订单信息填写模块 booking_proc() 设计

    请参见下面代码:

    def booking_proc(self,refresh_interval=0):

    """

    Info:订票处理过程,循环查询符合条件的车次,如果存在则点击“预定”

    """

    book_ticket_flag = False

    # 循环查询

    while True:

    time.sleep(refresh_interval)

    # 点击“查询”按钮,刷新页面开始查询,查询按钮的ID="query_ticket"

    search_btn = WebDriverWait(self.driver, 10).until(

    EC.presence_of_element_located((By.XPATH, '//*[@id="query_ticket"]')))

    search_btn.click()

    # 扫描查询结果,根据自定义车次字典train_info提供的信息,逐一查询

    try:

    for train in self.train_info:

    print(u"当前查询车次为:"+train)

    # 根据车次查询对应的席别:商务,一等,二等,无座等

    seat_list= self.train_info.get(train)

    for seat in seat_list[0]:

    ticket_seat_id = '//*[@id="' + seat + '"]'# 席别ID

    tic_tb_item = 'default'

    # 获取车票数量信息:"-","无","数字"

    tic_tb_item = WebDriverWait(self.driver, 2).until(

    EC.presence_of_element_located((By.XPATH, ticket_seat_id)))

    tic_ava_num = tic_tb_item.text

    # 无票或未开售,则结束当前查询

    if(tic_ava_num == u'无' or tic_ava_num == u'*'):

    continue

    # 如果车次有票,则点击对应车次的“预定”按钮

    else:

    book_ticket_btn = '//*[@id="' + seat_list[1] + '"]/td[13]/a'

    self.driver.find_element_by_xpath(book_ticket_btn).click()

    book_ticket_flag = True

    print(u"开始预定")

    break

    if (book_ticket_flag):

    break

    except Exception as err:

    print(err)

    # 网络状态不好的时候,点击查询按钮,可能返回查询结果失败,对此异常可再次点击

    search_btn.click()

    if (book_ticket_flag):

    break

    订单确认模块 confirm_proc() 设计

    请参见下面代码:

    def confirm_proc(self):

    """

    Info:点击“预定”之后,需要确认乘客信息和座位信息

    """

    # 判断页面跳是否转至乘客选择页面

    while True:

    if (self.driver.current_url == self.confirm_url):

    print (u'页面跳转成功!')

    break

    else:

    print (u'等待页面跳转...')

    time.sleep(1)

    # 乘车人选择:针对乘车人列表多于一人的情况

    print(u"选择乘客")

    while True:

    try:

    # 选择乘车人列表中的第二个人

    self.driver.find_element_by_xpath('//*[@id="normalPassenger_1"]').click()

    break

    except Exception as err:

    print (u'等待常用联系人列表。。。',err)

    time.sleep(0.5)

    try:

    print(u"提交订票信息")

    self.driver.find_element_by_xpath('//*[@id="submitOrder_id"]').click()

    time.sleep(1.5)

    print(u"确认订票信息")

    self.driver.find_element_by_xpath('//*[@id="qr_submit_id"]').click()

    except Exception as err:

    print (err)

    展开全文
  • 通过程序自动化去刷新并点击抢票,就...推荐参考学习:《Python教程》自动抢票流程1.首先,梳理下本次优化后的抢票流程。2.自动启动浏览器,自动化输入程序里设置好的 12306 的登录账号和密码。3.自己手动输入验证码...

    通过程序自动化去刷新并点击抢票,就有了这个 Python 抢票程序。这个程序是 Python 模拟手工去操作浏览器的,所以会因为各种网络或者其他因素导致程序终止。本文主要讲解增加车次选择功能和座次选择功能这两个优化点。

    5c45376bf0361607.jpg

    推荐参考学习:《Python教程》

    自动抢票流程

    1.首先,梳理下本次优化后的抢票流程。

    2.自动启动浏览器,自动化输入程序里设置好的 12306 的登录账号和密码。

    3.自己手动输入验证码,图形验证码设别功能太复杂,涉及到人工智能的图像识别,自己做的话成功率不高,所以我这里让大家手动输入,输入验证码后手动点击「登录」按钮。

    4.登录成功后页面会自动校验,确认登录成功后会自动跳转到查票页面。根据自己程序代码里输入的出发地和目的地进行查票。

    5.根据自己输入的车次进行查询右边「预定」按钮是否高亮可点,不可点的话会一直点击「查询」按钮不断的刷新页面直到出现有票点击「按钮」按钮。

    6.提交订单页面,选择乘客,选择座位类型,如果没有自己想要的类型,比如,二等座,页面会重新回到火车票查询页面,重新查询,如此循环。

    7.抢到你想要的票后,提交订单,发送邮件,完成!

    登录页面

    这部分我把浏览器窗口最大化了,之前没设置全屏,大家电脑显示屏大小不一样,可能出现有些元素被遮挡无法点击。

    登录之后可能会出现网络可能出现的问题的提示,估计是服务器的问题,这时手动点一下左上角的返回,一般就可以恢复正常,如果点一次还是这个提示,那就点两次吧。

    1548038878825913.jpg

    查询页面

    查询火车票页面,这个页面峰值时间时也会出现超时的提示,估计是访问的人数过多导致服务器异常导致的,有时候很快就能查到票,具体什么时候我也没找到规律。

    1548038912528250.jpg

    这个我们也无法避免,程序会自动的帮我们刷新直到刷新出有票的页面,刷新频率:1 秒/次。

    车次选择功能是大家比较关心的功能,之前是 order = 0 默认是全部车次,这次大家可以根据车次的位置输入相应的数字,比如要预定的车在第 5 行,你把 order = 5 就行,关于这些参数配置,下面会专门给大家列出来。

    提交订单页面

    提交订单页面程序会做两件事,第一个是根据你输入的乘客姓名进行选择,第二件事是根据是输入的座次进行判断,你想要的座次有票的话就会选择并提交订单,你想要的座次没票的话就会返回到上一级页面,重复查询车票,检查座次,如此循环,直到订到你想要的票。

    1548039005713889.png

    重要参数修改说明

    重点来了,前面看不懂没关系,想直接拿源码运行的务必仔细看这里,拿到抢票源码后以下事项需要注意并配置。

    Python 环境配置

    本次程序我用的 Python 环境是 Python 3.6 的版本,其实 3.5 以上的应该都可以。官网上下载 Python3 的安装包,安装时记得勾选 Add Python 3.x to PATH 这个选项,勾选这个选项的好处是安装完成后它会自动帮你配置环境变量,不用像安装 Python2.x 时需要手动去配置。接下来都是傻瓜式安装,安装完成后终端下输入 Python 显示版本的话表示安装成功。还不会的话建议上网查查,网上教程很多。

    1548039045936277.jpg

    pip 工具

    pip 是通用的 Python 库管理工具,使用 pip 很方便的安装、管理库。第一步完成后这个 pip 工具是自带的,你可以在终端下输入 pip list 命令查看你当前安装的所有 Python 库。

    1548039132513968.png

    安装导入相应的库

    本程序主要用到的库是 splinter,主要用这个库来驱动浏览器进行操作页面的,用 pip 命令直接安装。pip install splinter

    Splinter 相关的教程中文文档地址如下,如有兴趣的话可以学习一下。https://splinter-docs-zh-cn.readthedocs.io/zh/latest/tutorial.html

    安装完成后在 IDE 中用 import 导入这个库,如果还不能用的话记得在编辑器中安装引入一下,我用的是 Pycharm 编辑器,在设置中引入安装,见下图。

    1548039224593522.png

    Python 发送邮件需要用到 Python 自带的两个模块,smtplib 和 email。直接 import 导入,无需下载。

    所以,真正需要安装的只有 splinter 库,其他直接导入就可用,在编辑器中导入。from splinter.browser import Browser

    from time import sleep

    import smtplib

    from email.mime.text import MIMEText

    from email.utils import formataddr

    from email.header import Header

    浏览器驱动下载并指定路径

    这个问题大家也出现比较多,为什么要下载浏览器驱动呢?因为 splinter 库的底层原理是通过 WebDriver 去驱动浏览器做相应的操作的,所以使用对应的浏览器必须要下载对应的浏览器驱动。我用的是 chrome 浏览器,所以我下载的是 chromedriver,这里还有个坑,chromedriver 和 chrome 浏览器有映射关系,你必须下载对应的版本。映射关系如下ChromeDriver v2.43 (2018-10-16)----------Supports Chrome v69-71

    ChromeDriver v2.42 (2018-09-13)----------Supports Chrome v68-70

    ChromeDriver v2.41 (2018-07-27)----------Supports Chrome v67-69

    ChromeDriver v2.40 (2018-06-07)----------Supports Chrome v66-68

    ChromeDriver v2.39 (2018-05-30)----------Supports Chrome v66-68

    ChromeDriver v2.38 (2018-04-17)----------Supports Chrome v65-67

    ChromeDriver v2.37 (2018-03-16)----------Supports Chrome v64-66

    ChromeDriver v2.36 (2018-03-02)----------Supports Chrome v63-65

    ChromeDriver v2.35 (2018-01-10)----------Supports Chrome v62-64

    (Chrome 和ChromeDriver 映射表)

    chromedriver 下载解压完成后把他的路径复制下来,替换源码 33 行中的路径。

    1548039337391107.jpg

    邮件通知功能设置

    上面安装了对应的库后,需要填写的信息如下:发件人和收件人邮箱、发件人的授权码。所以需要修改的位置是 sendMail 函数中的 51 行和 52 行的发件人邮箱账号和收件人邮箱账号,61 行的发件人邮箱的授权码。

    1548039365621455.jpg

    授权码获取方法参考文章 30行Python代码实现自动收发邮件,我用的发邮件的邮箱是我的小号 QQ 邮箱,收件人邮箱是我的大号 QQ邮箱。我试了下,QQ 邮箱里发件人和收件人可以是一样的,也就是可以自己给自己发邮件,大家自行选择,建议先独立把发邮件的代码运行下,查看是否发送成功,一般运行失败就是因为授权码不对造成的,重新获取一次授权码好了。

    座次对应的数值

    经过调试查看,不同的座次对应的 value 值不一样。

    1548039400283007.jpg

    多次调试之后,我把不同座次对应的 value 值整理成了表格。

    1548039429180144.jpg

    代码修改位置在源码 112 行和 113 两行,两行都要改动,改动成你想要的座次对应的 value 就行。

    12306 用户名和 12306 登录密码

    这两项在 main 函数中修改成自己的就行,把源码 114 和 145 行修改成自己的即可。

    车次选择

    车次用了 order 字段来表示,

    0 代表所有车次,1 表示第一行的车次,2 表示第二行的车次,以此类推。一般你输入出发点和目的地后,所有的车次位置是固定的,你输入你想订的车次的位置数字即可。源码修改位置也是在 main 函数里,第 146 行。

    乘客名格式

    乘客名,比如 passengers = ['XXX', 'XXX'],支持多选,注意下学生票需注明,注明方式为:passengers = ['XXX(学生)', 'XXX'],不然会报错,源码修改位置也是在 main 函数里,第 149 行。

    乘车日期格式

    乘车日期,格式为:'2019-01-28',源码修改位置也是在 main 函数里,第 151 行。

    出发地和目的地 cookie 获取

    这个由于时间问题,没有优化,目前只能手动去查找获取出发地和目的地,打开自己的 12306 查询火车票页面,输入出发地和目的地。将页面的调试模式打开,用快捷键 F12 或者鼠标右键「检查」打开调试模式,选择 Network,点击「查询」按钮,这样就能获取对应出发地和目的地的 cookie。源码修改位置也是在 main 函数里,第 153 行和 155 行。

    1548039463482021.jpg

    总结下,以上需要修改的地方,chromedriver 路径:在初始化函数 init 里面、邮件通知功能收发邮箱账号和发件人授权码在 sendMail 函数中修改、修改对应座次 value 值在 check_ticket 函数中修改、其他信息包括:12306用户名、12306密码、车次选择、乘客名、乘车日期、出发日期、出发地和目的地 cookie 值,都在源码最下方的 main 函数中修改。

    1548039504806202.jpg

    重要说明:本程序由于时间有限,配置项也挺多的,但是为了抢到票,我们只能多尝试一种方法了,本程序是模拟人工操作浏览器,还是会存在很多问题的,比如说由于网络关系导致页面长时间停留从而找不到元素而程序停止,其他各种预想不到的问题也会出现,程序停止的话也只能重启下程序继续抢,后期大家需要的话我也会慢慢优化。

    article_wechat2021.jpg?1111

    本文转载于:Python知识圈,如有侵犯,请联系a@php.cn删除

    展开全文
  • 12306自动抢票软件代码实现

    万次阅读 热门讨论 2018-02-03 20:33:14
    昨天我发的是抓取的12306数据包,然后分析了一下,今天按照昨天的分析 用代码实现了,如果有需要的同学们可以看一下 ,实现的功能有,登录,验证码识别,自动查票,有余票点击预定, 差了最后一步提交订单。同学们...

    昨天我发的是抓取的12306数据包,然后分析了一下,今天按照昨天的分析 用代码实现了,如果有需要的同学们可以看一下

    实现的功能有,登录,验证码识别,自动查票,有余票点击预定, 差了最后一步提交订单。同学们可以自己研究一下。


    import requests
    import time
    import dmpt
    import re
    import random
    from copyheaders import headers_raw_to_dict
    
    DEFAULT_HEADERS={
    'Host':'kyfw.12306.cn',
    'Connection':'keep-alive',
    'Upgrade-Insecure-Requests':'1',
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Referer':'https://kyfw.12306.cn/otn/index/init',
    'Accept-Language':'zh-CN,zh;q=0.9',
    }
    def get_random():
        return str(random.random()) #生产一个18位的随机数
    def get_13_time():  #一个十三位的时间戳
        return str(int(time.time()*1000))
    class CN12306(object):
        def __init__(self):
            self.chufa='2018-02-03'
            self.s=requests.session()
            self.s.verify = False   # 忽略https 证书验证
        def get_init(self):  #请求了一个首页
            url='https://kyfw.12306.cn/otn/login/init'
            r=self.s.get(url)
            print('首页获取成功,状态码:',r)
    
        def get_newpasscode(self):  #这个页面不知道是干啥的,但是12306 请求了,咱们为了模仿的像一点也去请求
            url='https://kyfw.12306.cn/otn/resources/js/newpasscode/captcha_js.js?_={}'.format(get_13_time())
            r=self.s.get(url)
            print('newpasscode获取成功,状态码:',r)
    
        def get_auth_code(self):  #获取验证码
            url='https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{}'.format(get_random())
            r=self.s.get(url)
            with open('auth_code.png', 'wb') as auth:
                auth.write(r.content)
                auth.flush()
                auth.close()
            return str(r) == '<Response [200]>'
    
        def analysis_auth_code(self):  # 调用打码平台,返回验证码坐标
            dmt = dmpt.DamatuApi("打码平台帐号", "打码平台密码")
            analysis_auth = dmt.decode('auth_code.png', 287)  # 上传打码
            analysis_auth = re.sub('\|', ',', analysis_auth)
            li = analysis_auth.split(',')
            for i in range(len(li)):
                if i % 2 == 0:
                    pass
                else:
                    li[i] = str(int(li[i]) - 30)
            analysis_auth = str(li)
            analysis_auth = re.sub("'", '', analysis_auth)
            analysis_auth = re.sub("\]", '', analysis_auth)
            analysis_auth = re.sub("\[", '', analysis_auth)
            analysis_auth = re.sub(" ", '', analysis_auth)
            print('验证码坐标', analysis_auth)
            self.analysis_auth= analysis_auth  # 验证码坐标
    
        def auth_auth_code(self): #验证验证码是否正确提交方式post
            url='https://kyfw.12306.cn/passport/captcha/captcha-check'
            data={
                'answer':self.analysis_auth ,
                'login_site':'E',
                'rand':'sjrand',
            }
            r=self.s.post(url=url,data=data)
            print(r.text)
            if r.text == '''{"result_message":"验证码校验成功","result_code":"4"}''': #验证码校验成功
                return True
            else:  #如果验证码校验失败
                print('验证码错误,刷新验证码,重新提交')
                if self.get_auth_code():   #获取验证码
                    self.analysis_auth_code() #调用打码平台
                    self.auth_auth_code()  #重新校验验证码
    
        def login(self):
            url='https://kyfw.12306.cn/passport/web/login'
            data={
            'username' : '12306帐号',
            'password' : '12306密码',
            'appid' : 'otn',
            }
            r=self.s.post(url=url,data=data)
            self.uamtk=r.json()["uamtk"]
    
            print(r.text)
    
        def userLogin(self):
            url='https://kyfw.12306.cn/otn/login/userLogin'
            r=self.s.post(url=url)
            # print(r.text)
        def getjs(self):   #不知道是干啥的,但是也提交吧
            url='https://kyfw.12306.cn/otn/HttpZF/GetJS'
            r=self.s.get(url)
        def post_uamtk(self):
            url='https://kyfw.12306.cn/passport/web/auth/uamtk'
            data={ 'appid':'otn'}
            r=self.s.post(url=url,data=data,allow_redirects=False)
            self.newapptk=r.json()["newapptk"]
            r.encoding='utf-8'
            print(r.text)
        def post_uamauthclient(self):
            url='https://kyfw.12306.cn/otn/uamauthclient'
            data={
                'tk':self.newapptk
            }
            r=self.s.post(url=url,data=data)
            self.apptk = r.json()["apptk"]
            r.encoding='utf-8'
            print(r.text)
        def get_userLogin(self):
            url='https://kyfw.12306.cn/otn/login/userLogin'
            r=self.s.get(url)
            r.encoding='utf-8'
            # print(r.text)
        def get_leftTicket(self):
            url='https://kyfw.12306.cn/otn/leftTicket/init'
            r=self.s.get(url)
            r.encoding='utf-8'
            # print(r.text)
        def get_GetJS(self):
            url='https://kyfw.12306.cn/otn/HttpZF/GetJS'
            self.s.get(url)
    
        def get_qufzjql(self):
            url = 'https://kyfw.12306.cn/otn/dynamicJs/qufzjql'
            self.s.get(url)
    
        def get_queryZ(self):
            url='https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes={}'.format(self.chufa,'BJP','TBP','ADULT')
            r=self.s.get(url)
            r.encoding='utf-8'
            # print(r.text)
            cheliang=r.json()["data"]["result"]
            for i in cheliang:
                dandulist=str(i).split('|')
                if len(str(dandulist[0]))>=100:
                    self.secretStr=dandulist[0]
                    # secretStr = str(x[0])
                    车次=str(dandulist[3])
                    出发时间=str(dandulist[8])
                    到达时间 = str(dandulist[9])
                    历时=str(dandulist[10])
                    软卧 = str(dandulist[23])
                    硬卧=str(dandulist[28])
                    print(i)
                    print('可预订车次列表,','车次:',车次,'出发时间:', 出发时间,'到达时间:', 到达时间,'历时:', 历时,'软卧剩余:  ',软卧,'  硬卧剩余:  ',硬卧)
                    if (软卧 != '' and  软卧 != '0'  and 软卧 != '无' and 软卧 != '空') or (硬卧 != '' and  硬卧 != '0'  and 硬卧 != '无' and 硬卧 != '空'):
                        #执行下单操作
                        self.post_submitOrderRequest()
                        self.post_initDc()
                        self.post_getPassengerDTOs()
                        return False
    
                print('*****************************************************')
            return True
    
    
        # 点击预定下单
        def post_submitOrderRequest(self):
            url='https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
            data={
                'secretStr':self.secretStr,
                'train_date':self.chufa,  #出发时间
                'back_train_date':self.chufa ,#返回时间
                'tour_flag':'dc',
                'purpose_codes':'ADULT',
                'query_from_station_name':'北京',
                'query_to_station_name':'天津北',
                'undefined':''
                  }
            r=self.s.post(url=url,data=data)
            print(r.text)
        def post_initDc(self):
            url='https://kyfw.12306.cn/otn/confirmPassenger/initDc'
            r=self.s.post(url)
            # r.text
            self.REPEAT_SUBMIT_TOKEN=re.findall("globalRepeatSubmitToken = '(.*?)';",r.text)[0]
        def post_getPassengerDTOs(self): #获取乘客信息
            url='https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs'
            data={
                'REPEAT_SUBMIT_TOKEN':self.REPEAT_SUBMIT_TOKEN,
                '_json_att':''
            }
            r=self.s.post(url=url,data=data)
            r.encoding='utf-8'
            print(r.text)
    
    if __name__ == '__main__':
        print(get_random())
        cn=CN12306()
        cn.get_init()
        cn.get_newpasscode()
        if cn.get_auth_code():
            #如果验证码获取成功,就调用打码平台
            print('验证码获取成功')
            print('正在调用打码平台...')
            cn.analysis_auth_code()
            if cn.auth_auth_code():  #验证验证码是否正确
                cn.login()
                cn.userLogin()
                cn.getjs()
                cn.post_uamtk()
                cn.post_uamauthclient()
                cn.get_userLogin()
                cn.get_leftTicket()
                cn.get_GetJS()
                cn.get_qufzjql()
    
                while cn.get_queryZ():
                    time.sleep(30)
    
    

    展开全文
  • [Python] 纯文本查看 复制代码#_*_coding:utf-8_*_import urllib2,urllibimport sslimport cookielibimport simplejsonimport imgimport refrom youjian import sendfrom station import station_namesstationDict={...

    [Python] 纯文本查看 复制代码#_*_coding:utf-8_*_

    import urllib2,urllib

    import ssl

    import cookielib

    import simplejson

    import img

    import re

    from youjian import send

    from station import station_names

    stationDict={}

    for i in station_names.split('@')[1:]:

    stationList=i.split('|')

    stationDict[stationList[1]]=stationList[2]

    c=cookielib.LWPCookieJar()

    cookie=urllib2.HTTPCookieProcessor(c)

    opener=urllib2.build_opener(cookie)

    urllib2.install_opener(opener)

    headers={

    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0',

    'Referer':'https://kyfw.12306.cn/otn/resources/login.html'

    }

    ssl._create_default_https_context=ssl._create_unverified_context

    #v出发时间

    train_date='2019-01-25'

    #起始站

    fromStation='深圳'

    from_station=stationDict[fromStation]

    #终点站

    toStation='武汉'

    to_station=stationDict[toStation]

    #登陆操作

    def login():

    req=urllib2.Request(

    'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand'

    )

    req.headers

    imgCode=opener.open(req).read()

    with open('code.png','wb') as fn:

    fn.write(imgCode)

    req=urllib2.Request(

    'https://kyfw.12306.cn/passport/captcha/captcha-check'

    )

    req.headers

    #code=img.code()

    code=raw_input('请输入验证码位置:')

    date={

    'callback':'jQuery1910948054855148424_1546424454404',

    'answer':code,

    'rand':'sjrand',

    'login_site':'E',

    '_':'1546424454425'

    }

    date=urllib.urlencode(date)

    html=opener.open(req,date).read()

    req=urllib2.Request(

    'https://kyfw.12306.cn/passport/web/login'

    )

    req.headers

    data={

    'username':'账号',#12306账号密码

    'password':'密码',

    'appid':'otn',

    }

    data = urllib.urlencode(data)

    html = opener.open(req, data).read()

    result=simplejson.loads(html)

    if result['result_code']==0:

    print '登陆成功'

    #登陆成功后的第一次访问

    req = urllib2.Request(

    'https://kyfw.12306.cn/passport/web/auth/uamtk'

    )

    data = {

    'appid':'otn'

    }

    data = urllib.urlencode(data)

    req.headers = headers

    html = opener.open(req,data=data).read()

    result=simplejson.loads(html)

    tk=result['newapptk']

    # ?第二次访问

    req = urllib2.Request(

    'https://kyfw.12306.cn/otn/uamauthclient'

    )

    data = {

    'tk':tk

    }

    data = urllib.urlencode(data)

    req.headers = headers

    html = opener.open(req,data=data).read()

    #查询是否登录成功

    '''req = urllib2.Request(

    'https://kyfw.12306.cn/otn/index/initMy12306Api'

    )

    req.headers=headers

    html = opener.open(req).read()

    print html

    return True'''

    return True

    print '登陆失败,正在重新登录...'

    展开全文
  • .net抢票软件,c#抢票软件,抢票软件,12306抢票软件源码
  • 抢票软件代码 delphi

    热门讨论 2010-02-02 10:57:24
    软件在这里:http://download.csdn.net/source/2040877 编译不过可能是丢了七七八八的第三方包,自己去google一下,都是常用的包
  • 火车票抢票软件代码

    热门讨论 2010-02-02 10:35:06
    delphi写得老东西,放硬盘里一年多了,昨天为了抢票又拿出来改了改,bug还一大堆,有人愿意改的话,改好给我一个,资源分有点高,我比较懒,不发帖,不传资源,自己下东西分不够用了
  • 我们现将上面代码的r.text进行打印,看看我们请求之后,返回了什么样的信息,然后决定我们应该如何解析 这样看着不方便,我们粘贴到记事本中,进行详细的分析: 可以与12306显示的信息进行对比,K829是车次,CDW与...
  • 本资源既有我的代码,也有我的学习视频。基础差可以根据教程手把手教你实现12306登录用户、余...本代码基于Python2.7 实现12306抢票,我的代码与视频有些不同,希望有助于你的学习。有问题请私信,共同学习,共同进步!
  • 市场上很多火车票抢票软件大家应该非常熟悉,但很少有人研究具体是怎么实现的,所以觉得很神秘,其实很简单。下面使用Python模拟抢票程序,给大家揭秘抢票到底是怎么回事。 该代码仅供参考,主要用于大家沟通交流,...
  • 12306 火车票 抢票 软件,具有快速和强大的抢票能力; 12306 火车票 抢票 软件 功能完善,设计美观
  • 抢票软件的12306java实现,抢票软件的12306java实现,抢票软件的12306java实现,抢票软件的12306java实现,抢票软件的12306java实现,抢票软件的12306java实现,
  • 最近这段时间频频看到微信群里发什么 抢票加速,智行、携程、飞猪、美团,对于我这能坐客车就不坐火车的人来说,无所谓靠谱不靠谱突发奇想的整理了下整个抢票加速的逻辑,写了这个小程序,代码很low,拒绝批评,求...
  • 抢票软件12306java版

    千次阅读 2018-04-06 08:02:58
    1、抢票软件的原理2、12306抓包分析
  • [转]抢票工具代码

    2019-09-26 12:29:54
    var page = "https://dynamic.12306.cn/otsweb/loginAction.do?method=init";var url = "https://dynamic.12306.cn/otsweb/loginAction.do?method=login";var queryurl = "https://dynamic.12306.cn/otsweb/o...
  • c#版12306抢票软件源码分享,保证可以正常运行,不过目前不能用于抢票,因为12306网站修改了验证码规则(点击图片的验证码)以后就不能用了,但可以在此源码基础上加以改进,达到可以使用的目标。
  • 一步一步编写12306抢票软件

    万次阅读 热门讨论 2016-12-23 20:41:15
    本文在Linux平台上,以Python为开发工具,介绍12306抢票软件的基本原理,并引入示例,讲解如何自己编写一个12306抢票软件。对于Windows平台的读者,可以安装Crywin软件模拟UNIX的命令行界面。图形界面采用Python封装...
  • 本文转自农历八月十五日是中秋节。南宋吴自牧的《梦粱录》记载:“八月十五中秋节,此日三秋恰...十一假期也快要临近,大家每天都在抢票,最近出现了一个Python抢票工具,送到了star 12K, GitHub趋势榜第一:项目名...
  • 分流抢票软件浅谈

    千次阅读 2019-02-09 02:39:00
    其实,我不是很想写这篇文章的,因为现在有很多抢票的软件,即我们所说的第三方抢票软件,也有很多抢票的心得在网上,但是,我今天在微信晒了一个抢票成功的图片,就有很多人来问我,说要我分享这个软件,我在微信也...
  • 2014 抢票软件,源码也分享在我的用户下,可购票,供分享使用
  • 自动抢票软件 java 控制台版本 用java编写的实用自动抢票软件文件里面包含有jar文件可直接用dos命令启动!
  • 这届抢票软件为什么不行?

    千次阅读 2020-01-24 10:00:00
    燃财经(ID:rancaijing)原创作者 | 唐亚华编辑 | 魏佳一年一度人口大迁移——春运已经暂时告一段落。虽然12306近日已经宣称屏蔽了部分抢票软件,并推出官方候补功能,但市...
  • 12306自动抢票软件

    千次阅读 2018-12-18 13:45:27
    with open(r'H:\pictures\12306自动抢票\code.png', 'wb') as f: f.write(response.content) def generate_code_list(self, code_str): code_str = code_str.strip() groups = code_str.split(',') codes = ...
  • 相信绝大多数的小伙伴都曾有过离开过,或现在是,独在异乡的情况吧,拿小编来说,小编现在就是这种状况,回家次数不多,不是因为没有时间,而是因为没有车票,每次都需要拿抢票软件,于是,脑海中,就印出这么个奇怪...
  • python 学习笔记一 自动抢票软件

    千次阅读 2018-07-25 09:49:58
    这篇是一个抢票软件,有登录,自动选座,自动下单功能。用的splinter.browser 测试库实现主要功能 class huoche(object): &amp;quot;&amp;quot;&amp;quot;docstring for huoche&amp;quot;&...
  • 代码源自CSDN ,本不支持 2016最新的 验证码方式,本人修改后支持 最新验证码。
  • 网上抢票软件

    2013-01-22 15:06:40
    现在一直在玩一款网游,在搜“作弊”工具的时候 认识了greasemonkey这个神器,后来在很多不是自己的网站,却需要重复操作的时候,都会祭出greasemonkey来动动代码。 想想如果自己要买火车票,我或许也会开发一...
  • 锁 与抢票软件的应用

    2018-09-19 20:45:00
    模拟一个简单的抢票软件 import time import json from multiprocessing import Process,Lock def search(person): with open('ticket') as f: dic = json.load(f) time.sleep(0.2) print('...
  • 号称“史上一票难求”的春运抢票季今日开启,抢票软件也自然成为抢客们的获胜利器。然而,很多抢票软件表面上标榜着高成功率,实际上却是山寨软件,一旦感染消费者操作系统,就会窃取联系人、短信、通话记录等个人...
  • 代码使用Python+Splinter开发,Splinter是一个使用Python开发的开源Web应用测试工具,它可以帮你实现自动浏览站点和与其进行交互。二. 安装好Python 3或2都可以,然后安装Splinter `pip install Splinter三. ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,114
精华内容 1,245
关键字:

抢票软件代码