温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python如何实现12306自动抢火车票功能

发布时间:2021-12-29 16:41:17 来源:亿速云 阅读:257 作者:小新 栏目:开发技术

这篇文章将为大家详细讲解有关Python如何实现12306自动抢火车票功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一、效果展示

在正式进入代码讲解之前,先来看下本文的实现效果。

如果不是为了演示效果,直接在最后确定阶段加一个延时点击确定,应该不到45秒可以锁定一张票,只要在30分钟之内付款即可。

二、代码详解

本小节会详细解锁抢票软件是如何模拟登录网站,进行自动买票的。为了更清晰地给大家展示,部分代码没有写成函数,直接裸代码运行,让需要买票的朋友可以自己应用软件进行购票。

1 导入库

首先导入本文需要加载的库,如果你有些库还没有安装,导致运行代码时报错,可以在Anaconda Prompt中用pip方法安装。

import json
import time
from captcha import * 
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import wait
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
#导入库

2 确定好购票基本信息

导入库后,在python代码中填写你购票的基本信息。

purpose = 'ADULT'               #购买成人票,如果是学生票,需调整代码
names = ['谢朝阳']              #填写购票人姓名
date = '2021-09-21'             #填写购票日期
start_station = '深圳'          #购票出发站
end_station = '长沙南'          #购票目的站
password = '11234567xyz'        #登录12306的秘密
username ='xiezhaoyang122700'   #登录12306的账号
trains = ['G1004', 'G80', 'G6028', 'G6182', 'G6016']  #你想买的班次
#填写基本信息

本文预订的是2021年9月21日从深圳到长沙南的高铁票,你可以根据自己的实际需要进行调整。由于有些班次的时间过早或过晚,买了也很不方便,所以可以在trains中挑选出你满意的班次进行购票。在这里需要提醒大家,我之前在尝试代码时碰到的坑,那就是时间中如果有个位数要在前面填0。比如2021年9月2日,你在填写购票日期date时要写成'2021-09-02',否则在运行代码时日期总是填不进去。

3 登录12306

确定好购票的基本信息后,就可以应用python模拟登录12306了,代码如下:

options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")  
browser = webdriver.Chrome(options=options)
browser.maximize_window()
login_url = 'https://kyfw.12306.cn/otn/resources/login.html'
#ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
browser.get(login_url)
time.sleep(0.5)
wait.WebDriverWait(browser, 5).until(EC.element_to_be_clickable((By.CLASS_NAME,'login-hd-account'))).click()
input_name = browser.find_element_by_id('J-userName')
input_pd = browser.find_element_by_id('J-password')
input_name.send_keys(username)
input_pd.send_keys(password)
login = browser.find_element_by_id('J-login')
login.click()
#登录12306

整体思路是: 

1.应用python模拟调用google浏览器;

2.输入12306网址;

3.等网页加载完全后点击账户密码登录;

4.找到账号密码的id,把账户密码信息填充进去;

5.找到登录id,模拟点击登录按钮。

在这一小节中要注意两个点。

一、要在python安装目录中放和google版本匹配的chromedriver,供python调用。

二、要学会找填写账户密码信息的id。

首先,在google浏览器中输入12306登录网址:

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

接着点击账户密码登录,会出现如下界面:

Python如何实现12306自动抢火车票功能

然后点击红框中的三个点,找到更多工具,点击开发者工具,会出现如下界面:

Python如何实现12306自动抢火车票功能

点击红框中的箭头,把鼠标移动到账户框上去,就会出现如下界面:

Python如何实现12306自动抢火车票功能

右边变灰的框里就会出现对应的id,点击账号框,再把鼠标移动到右边变灰的字符上去,点击右键,会出现copy element的选项,复制下来即可。

<input type="text" class="input" id="J-userName" placeholder="用户名/邮箱/手机号"  aria-label="请输入用户名/邮箱/手机号" title="请输入用户名/邮箱/手机号">

发现了吗?源代码input_name中要填写的browser.find_element_by_id('J-userName')内容,即为id="J-userName"中的信息。

4 模拟滑动滑块

输入完用户名和密码,点击立即登录后,会出现如下滑块验证要求。

Python如何实现12306自动抢火车票功能

运行如下代码即可拖动滑块进行验证。

browser.implicitly_wait(5)
print('=====开始处理滑动验证码=====')
track = [300, 400, 500]  
for i in track:
    try:
        btn = browser.find_element_by_xpath('//*[@id="nc_1__scale_text"]/span')
        ActionChains(browser).drag_and_drop_by_offset(btn,i,0).perform()
    except:
        time.sleep(2)  
#拉动滑块验证

其中,browser.implicitly_wait(5)表示隐性等待5秒,track中放的是滑块拉动的距离。

5 处理疫情特殊要求

完成滑块验证要求后,会出现如下疫情特殊要求提示:

Python如何实现12306自动抢火车票功能

用如下代码点击确认即可。

browser.implicitly_wait(5)
browser.find_element_by_xpath('/html/body/div[5]/div[2]/div[3]/a').click()
time.sleep(2)  
#疫情特殊要求

browser.find_element_by_xpath和id的区别是,在右键复制时要copy XPath或copy full XPath。

6 点击购票并填写出发地、目的地、出发时间

接下来是选择买票,并将出发地、目的地、出发时间等信息填写进去。

browser.find_element_by_xpath('//*[@id="J-chepiao"]/a').click()
browser.find_element_by_xpath('//*[@id="megamenu-3"]/div[1]/ul/li[1]/a').click()
browser.find_element_by_xpath('//*[@id="qd_closeDefaultWarningWindowDialog_id"]').click()
#选择买票
def input_info():
    print('=====开始买票=====')
    from_station = browser.find_element_by_xpath('//*[@id="fromStationText"]')
    from_station.send_keys(Keys.ENTER)
    from_station.send_keys(Keys.CONTROL, 'a')
    from_station.send_keys(start_station, Keys.ENTER)
    browser.implicitly_wait(5)
    to_station = browser.find_element_by_xpath('//*[@id="toStationText"]')
    to_station.send_keys(Keys.ENTER)
    to_station.send_keys(Keys.CONTROL, 'a')
    to_station.send_keys(end_station, Keys.ENTER)
    browser.implicitly_wait(5)
    start_date = browser.find_element_by_xpath('//*[@id="train_date"]')
    start_date.send_keys(Keys.ENTER)
    start_date.send_keys(Keys.CONTROL, 'a')
    start_date.send_keys(Keys.CONTROL, 'x')
    start_date.send_keys(date, Keys.ENTER)
    browser.implicitly_wait(5)
    wait.WebDriverWait(browser, 3).until(EC.element_to_be_clickable((By.ID,'query_ticket'))).click()
input_info()
input_info()
#将出发地、目的地、出发日期填进去

得到结果如下:

Python如何实现12306自动抢火车票功能

这里需要注意的是我调用了两遍input_info函数,因为12306可能采取了一些反爬措施,一遍输入进去后查不出东西,显示为灰色。

7 锁定车票

最后是依次查找trains中的车次是否有票,有的话点击购买锁定车票。

trList = browser.find_elements_by_xpath(".//tbody[@id='queryLeftTable']/tr[not(@datatran)]")
for tr in trList:
    trainNum = tr.find_element_by_class_name("number").text
    if trainNum in trains:
        leftTicket = tr.find_element_by_xpath(".//td[4]").text
        print('leftTicket', leftTicket)
        if leftTicket == '有' or leftTicket.isdigit():
            orderBtn = tr.find_element_by_class_name("btn72")
            orderBtn.click()
            browser.implicitly_wait(5)
            passengerLabels = browser.find_elements_by_xpath(".//ul[@id='normal_passenger_id']/li/label")
            for passengerLabel in passengerLabels: 
                name = passengerLabel.text
                if name in names: 
                    passengerLabel.click() 
            browser.implicitly_wait(20)
            # 获取提交按钮
            submitBtn = browser.find_element_by_id("submitOrder_id")
            submitBtn.click()
            browser.implicitly_wait(20)
            confirmBtn = browser.find_element_by_id("qr_submit_id")
            confirmBtn.click()
            time.sleep(2)
            browser.implicitly_wait(20)
            confirmBtn = browser.find_element_by_id("qr_submit_id")
            confirmBtn.click()
            break 
#依次查找trains中的车次是否有票,有的话点击购买

关于“Python如何实现12306自动抢火车票功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI