python实现自动登录12306抢票 -- selenium
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
python实现自动登录12306抢票 -- selenium
- 前言
- 其实网上也出现了很多12306的代码,但是都不是最新的,我也是从网上找别人的帖子,看B站视频,然后写成了这个程序,想分享一下。其中我会说自己遇到的问题以及自己的一个改进。
- 一、遇到的问题?
- 1.url-正确的表头:就是首先url不要写错了,然后一定要加正确的表头,才可以拿到数据,就是我日期填写错误,然后生成的url就有问题,浪费了好多时间。日期:2024-01-09 ,不要加两个杠。。。
- 2.:注意用网页显示的user-agent:
- 3.拿到车票信息的json数据--代码展示
- 4. 12306的城市对应的代码json文件,大家可以去网上找下,然后自己编程写一下,我这个也花了一些时间锻炼自己
- 4.对拿到的车次json数据进行可视化处理,也生成一个列表信息,代码如下
- 5.程序进入到自动化代码 -- 自动登录 --自动抢票,这里要注意有些操作一定要有时间等待,time.sleep(2)等,是不可以删除的否则会报错,因为操作太快,浏览器没有反应过来。
- 至此,这个程序完全结束了。这也是最近春节要抢票我特意写的。主要都是学习别人的代码,但是有几个改进是自己学了爬虫,然后结合网页的变化(很多程序是2021,2022的,现在12306的网页有所改变),所写的。
- 二、改进
- 1.xpath语法中@id 或者说可以@元素,但是selenium不可以要拆成两部来写。,而且新的selenium语法和前几年的也有所区别。
- 2.预定按钮的元素定位我没有写死可以自己定义,也就是可以自己选择预定那躺车,比如1,3,4,11等,随便选择。因为这里是用了xpath语法去找到了所有的预订按钮。这个num你也可以放在login.json当中,这样更方面抢票。login.json就是一个字典序列,我是将要填写的东西都放进去。这样不用手动填写。
- 3.源代码完整展示
- 三、进阶--展望
- 1.首先可以将自动化操作用try--except,这样不会一直报错,更为规范。
- 2.免登录:因为登录其实要验证码,这样抢票也不方便。于是我就又继续学习了一些,发现了两种方法一是可以保存浏览器的数据,因为selenium每次打开的是一个新的程序,但是我们可以通过设置参数,让他打开是有记忆的,但是没有用。第二种,是cookie,是没有什么问题的,目前已经实现,接下尝试各种方法的cookie看行不行。后续我会发此程序。
- 3.多线程多进程:主要我已经实现cookie免登录,我想着是否可以打开多个页面,然后多个账号,一起抢他们所需要的票呢。
- 总结
- 1.最开始跟着写这个程序只会照着抄,然后根本不懂,后面就是差了一点点成功,也不会找错误。
- 2.后面学习了一下爬虫,更明白一点语法以及自己也更会如何定位元素了。还有就是request的一个请求,这些代码也更看得懂了
- 3.想着结合多线程然后实现批量抢票,同时也希望代价的容错率高,也就是说在自动化不用点几下程序就不行了,让它可以有更好的性能。-- 未来学习的一个点。加油!!!
前言
其实网上也出现了很多12306的代码,但是都不是最新的,我也是从网上找别人的帖子,看B站视频,然后写成了这个程序,想分享一下。其中我会说自己遇到的问题以及自己的一个改进。
提示:以下是本篇文章正文内容,下面案例可供参考
一、遇到的问题?
1.url-正确的表头:就是首先url不要写错了,然后一定要加正确的表头,才可以拿到数据,就是我日期填写错误,然后生成的url就有问题,浪费了好多时间。日期:2024-01-09 ,不要加两个杠。。。
2.:注意用网页显示的user-agent:
3.拿到车票信息的json数据–代码展示
import requests
from prettytable import PrettyTable
# 下面的模块就是打开浏览器的操作模块
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 获取浏览器的用户数据
# chrome ==> chrome://version/
# 个人资料路径 C:\Users\hl\AppData\Local\Temp\scoped_dir18416_1206036739\Default
# 路径的Default要去掉
path = r'D:\game\chromedriver.exe'
user_data_dir = r'C:\Users\hl\AppData\Local\Temp\scoped_dir18416_1206036739'
from pypinyin import pinyin, Style
import json
import time
"""
发送请求:模拟浏览器对于url地址发送请求
"""
"""根据用户自行输入相关信息,进行查票搜索"""
# 读取城市文件
f = open('city_all.json', encoding='utf-8').read()
city_data = json.loads(f)
print(city_data)
# 输入出发和目的城市
# 输入时间
train_date = '2025-01-09'
from_city = input('请输出你出发的城市:')
to_city = input('请输出你要出行的城市:')
print(city_data[from_city])
print(city_data[to_city])
headers = {
'user-agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36',
}
# 请求网址
# https://kyfw.12306.cn/otn/leftTicket/queryG?leftTicketDTO.train_date=2025-01-06&leftTicketDTO.from_station=SZQ&leftTicketDTO.to_station=EFG&purpose_codes=ADULT
url = f'https://kyfw.12306.cn/otn/leftTicket/queryG?leftTicketDTO.train_date={train_date}&leftTicketDTO.from_station={city_data[from_city]}&leftTicketDTO.to_station={city_data[to_city]}&purpose_codes=ADULT'
# 发送请求 使用request
response = requests.get(url=url, headers=headers)
print(url)
print(response.status_code)
print(response.text)
# 获取数据
json_data = response.json()
4. 12306的城市对应的代码json文件,大家可以去网上找下,然后自己编程写一下,我这个也花了一些时间锻炼自己
4.对拿到的车次json数据进行可视化处理,也生成一个列表信息,代码如下
import requests
from prettytable import PrettyTable
# 下面的模块就是打开浏览器的操作模块
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 获取浏览器的用户数据
# chrome ==> chrome://version/
# 个人资料路径 C:\Users\hl\AppData\Local\Temp\scoped_dir18416_1206036739\Default
# 路径的Default要去掉
path = r'D:\game\chromedriver.exe'
user_data_dir = r'C:\Users\hl\AppData\Local\Temp\scoped_dir18416_1206036739'
from pypinyin import pinyin, Style
import json
import time
"""
发送请求:模拟浏览器对于url地址发送请求
"""
"""根据用户自行输入相关信息,进行查票搜索"""
# 读取城市文件
f = open('city_all.json', encoding='utf-8').read()
city_data = json.loads(f)
print(city_data)
# 输入出发和目的城市
# 输入时间
train_date = '2025-01-09'
from_city = '深圳'
to_city = '广州'
print(city_data[from_city])
print(city_data[to_city])
headers = {
'cookie':f'_uab_collina=173526990403562156621352; JSESSIONID=1B8F19FC6675BDA9782FEA7B06BDC256; route=9036359bb8a8a461c164a04f8f50b252; BIGipServerotn=1725497610.24610.0000; BIGipServerpassport=1005060362.50215.0000; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; _jc_save_fromStation=%u6DF1%u5733%2CSZQ; _jc_save_toStation=%u4FE1%u4E30%2CEFG; _jc_save_fromDate={train_date}; _jc_save_wfdc_flag=dc; _jc_save_toDate=2024-12-28',
'user-agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36',
}
# 请求网址
# https://kyfw.12306.cn/otn/leftTicket/queryG?leftTicketDTO.train_date=2025-01-06&leftTicketDTO.from_station=SZQ&leftTicketDTO.to_station=EFG&purpose_codes=ADULT
url = f'https://kyfw.12306.cn/otn/leftTicket/queryG?leftTicketDTO.train_date={train_date}&leftTicketDTO.from_station={city_data[from_city]}&leftTicketDTO.to_station={city_data[to_city]}&purpose_codes=ADULT'
# 发送请求 使用request
response = requests.get(url=url, headers=headers)
print(url)
print(response.status_code)
print(response.text)
# 获取数据
json_data = response.json()
# 解析数据--字典取值:
result = json_data['data']['result']
# 实例化对象
tb = PrettyTable()
tb.field_names = [
'序号',
'车次',
'出发时间',
'到达时间',
'耗时',
'特等座',
'一等座',
'二等座',
'软卧',
'硬卧',
'硬座',
'无座',
]
# 定义一个打印序号page
page = 1
# for循环遍历,提取列表里面的元素
for i in result:
# 字符串分割,返回列表
index = i.split('|')
# 通过列表索引位置取值
num = index[3] # 车次
star_time = index[8] # 出发时间
arrive_time = index[9] # 到达时间
use_time = index[10] # 耗时
special_class = index[32] # 特等座
frist_class = index[31] # 一等座
second_class = index[30] # 二等座
hard_sleeper = index[28] # 硬卧
hard_seat = index[29] # 硬座
no_seat = index[26] # 无座
soft_sleeper = index[23]# 软卧
dict = {
'序号':'page',
'车次':'num',
'出发时间':'star_time',
'到达时间':'arrive_time',
'耗时':'use_time',
'特等座':'special_class',
'一等座':'frist_class',
'二等座':'second_class',
'软卧':'soft_sleeper',
'硬卧':'hard_sleeper',
'硬座':'hard_seat',
'无座': 'no_seat'
}
tb.add_row([
page, #序号索引
num, # 车次
star_time,# 出发时间
arrive_time,# 到达时间
use_time, # 耗时
special_class, # 特等座
frist_class, # 一等座
second_class,# 二等座
soft_sleeper, # 软卧
hard_sleeper,# 硬卧
hard_seat, # 硬座
no_seat,# 无座
])
page += 1
print(tb)
5.程序进入到自动化代码 – 自动登录 --自动抢票,这里要注意有些操作一定要有时间等待,time.sleep(2)等,是不可以删除的否则会报错,因为操作太快,浏览器没有反应过来。
def selenium_login():
# 0.配置谷歌浏览器加载项
options = webdriver.ChromeOptions()
options.add_argument(f'--user-data-dir={user_data_dir}') # 添加浏览器数剧
# 1.将加载项配置到启动浏览器中 打开/创建浏览器对象
driver = webdriver.Chrome(executable_path=r'D:\game\chromedriver.exe', options=options)
# 2.输入网址
driver.get('https://kyfw.12306.cn/otn/view/index.html')
# 3.输入账号 -- > 找到账号的输入框 selenium 通过元素面板去定位元素
driver.find_element(by="css selector", value="#J-userName").send_keys(login['account'])
# 4.输入密码 -- > 找到密码的输入框
driver.find_element(by="css selector", value="#J-password").send_keys(login['password'])
# 5.点击登录按钮
driver.find_element(by="css selector", value="#J-login").click()
time.sleep(0.5)
# 6.输入身份证后4位
driver.find_element(by="css selector", value="#id_card").send_keys(login['id_card'])
# 7.点击获取验证码
driver.find_element(by="css selector", value="#verification_code").click()
# 8.输入验证码
code = input("请输入验证码:")
driver.find_element(by="css selector", value="#code").send_keys(code)
driver.find_element(by="css selector", value="#verification_code").click()
# 9.点击确认按钮
driver.find_element(by="css selector", value="#sureClick").click()
# 有时候报错是需要延时等待 用 driver.implicitly_wait(10)代码 可以实现加载完就就进行下一步,
# 而time.sleep(5)则必须等我规定的时间
driver.implicitly_wait(5)
# 10,点击车票预定按钮
driver.find_element(by="css selector", value="#link_for_ticket").click()
# 11.1 选择出发的城市--点击那个框
driver.find_element(by="css selector", value="#fromStationText").click()
# 11.2 选择出发的城市--选择城市
driver.find_element(by="css selector", value="#fromStationText").send_keys(from_city)
# 11.3 选择出发的城市--回车确定
driver.find_element(by="css selector", value="#fromStationText").send_keys(Keys.ENTER)
# 12.1 选择目的的城市--点击那个框
driver.find_element(by="css selector", value="#toStationText").click()
# 12.2 选择目的的城市--选择城市
driver.find_element(by="css selector", value="#toStationText").send_keys(to_city)
# 12.3 选择目的的城市--回车确定
driver.find_element(by="css selector", value="#toStationText").send_keys(Keys.ENTER)
# 13.1 选择出发的日期--点击那个框
driver.find_element(by="css selector", value="#train_date").clear()
# 12.2 选择出发的日期--选择城市
driver.find_element(by="css selector", value="#train_date").send_keys(train_date)
# 12.3 选择出发的日期--回车确定
driver.find_element(by="css selector", value="#train_date").send_keys(Keys.ENTER)
# # 12.4 点击--显示全部可预订的车次
# driver.find_element(by="css selector", value="avail_ticket").click()
# 12.5 点击查询
driver.implicitly_wait(5)
driver.find_element(by="css selector", value="#query_ticket").click()
num = int(input('请输入您想要的车次:'))
# 点击预订按钮 -- 选择要预定的是第几躺车 -- 这个代码没有问题
# driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()
# //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
ticket_num = ticket_list[num].get_attribute("id")
ticket_pre = ticket_num + ' > td.no-br'
# 12.6 点击想要车次的预定按钮
driver.find_element(by="css selector", value=f"#{ticket_pre}").click()
# 13.1 勾选想要的乘车人
driver.find_element(by="css selector", value='#normalPassenger_0').click()
# 13.2 提交订单
driver.find_element(by="css selector", value='#submitOrder_id').click()
driver.implicitly_wait(5)
# 13.3 选择靠窗的1F的位置
# driver.find_element(by="css selector", value='#1F').click() --这种行不通,只能下方这种
driver.find_element(by="css selector", value='#erdeng1 > ul:nth-child(4) > li:nth-child(2)').click()
# 13.4 再次确认提交
time.sleep(2)
driver.find_element(by="css selector", value='#qr_submit_id').click()
# driver.find_element(by="css selector", value='#qr_submit_id').click()
# # 14. 网上支付 -- payButton
# driver.find_element(by="css selector", value='#payButton').click()
# # 15. 取消订单 -- cancelButton
# driver.find_element(by="css selector", value='#cancelButton').click()
至此,这个程序完全结束了。这也是最近春节要抢票我特意写的。主要都是学习别人的代码,但是有几个改进是自己学了爬虫,然后结合网页的变化(很多程序是2021,2022的,现在12306的网页有所改变),所写的。
二、改进
1.xpath语法中@id 或者说可以@元素,但是selenium不可以要拆成两部来写。,而且新的selenium语法和前几年的也有所区别。
# 点击预订按钮 -- 选择要预定的是第几躺车 -- 这个代码没有问题
# driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()
# //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
ticket_num = ticket_list[num].get_attribute("id")
ticket_pre = ticket_num + ' > td.no-br'
2.预定按钮的元素定位我没有写死可以自己定义,也就是可以自己选择预定那躺车,比如1,3,4,11等,随便选择。因为这里是用了xpath语法去找到了所有的预订按钮。这个num你也可以放在login.json当中,这样更方面抢票。login.json就是一个字典序列,我是将要填写的东西都放进去。这样不用手动填写。
num = int(input('请输入您想要的车次:'))
# 点击预订按钮 -- 选择要预定的是第几躺车 -- 这个代码没有问题
# driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()
# //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
ticket_num = ticket_list[num].get_attribute("id")
ticket_pre = ticket_num + ' > td.no-br'
login.json的内容展示
3.源代码完整展示
import requests
from prettytable import PrettyTable
# 下面的模块就是打开浏览器的操作模块
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 获取浏览器的用户数据
# chrome ==> chrome://version/
# 个人资料路径 C:\Users\hl\AppData\Local\Temp\scoped_dir18416_1206036739\Default
# 路径的Default要去掉
path = r'D:\game\chromedriver.exe'
user_data_dir = r'C:\Users\hl\AppData\Local\Temp\scoped_dir18416_1206036739'
from pypinyin import pinyin, Style
import json
import time
"""
发送请求:模拟浏览器对于url地址发送请求
"""
"""根据用户自行输入相关信息,进行查票搜索"""
# 读取城市文件
f = open('city_all.json', encoding='utf-8').read()
city_data = json.loads(f)
print(city_data)
# 输入出发和目的城市
# 输入时间
train_date = '2025-01-09'
from_city = '深圳'
to_city = '广州'
print(city_data[from_city])
print(city_data[to_city])
headers = {
'cookie':f'_uab_collina=173526990403562156621352; JSESSIONID=1B8F19FC6675BDA9782FEA7B06BDC256; route=9036359bb8a8a461c164a04f8f50b252; BIGipServerotn=1725497610.24610.0000; BIGipServerpassport=1005060362.50215.0000; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; _jc_save_fromStation=%u6DF1%u5733%2CSZQ; _jc_save_toStation=%u4FE1%u4E30%2CEFG; _jc_save_fromDate={train_date}; _jc_save_wfdc_flag=dc; _jc_save_toDate=2024-12-28',
'user-agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36',
}
# 请求网址
# https://kyfw.12306.cn/otn/leftTicket/queryG?leftTicketDTO.train_date=2025-01-06&leftTicketDTO.from_station=SZQ&leftTicketDTO.to_station=EFG&purpose_codes=ADULT
url = f'https://kyfw.12306.cn/otn/leftTicket/queryG?leftTicketDTO.train_date={train_date}&leftTicketDTO.from_station={city_data[from_city]}&leftTicketDTO.to_station={city_data[to_city]}&purpose_codes=ADULT'
# 发送请求 使用request
response = requests.get(url=url, headers=headers)
print(url)
print(response.status_code)
print(response.text)
# 获取数据
json_data = response.json()
# 解析数据--字典取值:
result = json_data['data']['result']
def print_ticketlist():
# 实例化对象
tb = PrettyTable()
tb.field_names = [
'序号',
'车次',
'出发时间',
'到达时间',
'耗时',
'特等座',
'一等座',
'二等座',
'软卧',
'硬卧',
'硬座',
'无座',
]
# 定义一个打印序号page
page = 1
# for循环遍历,提取列表里面的元素
for i in result:
# 字符串分割,返回列表
index = i.split('|')
# 通过列表索引位置取值
num = index[3] # 车次
star_time = index[8] # 出发时间
arrive_time = index[9] # 到达时间
use_time = index[10] # 耗时
special_class = index[32] # 特等座
frist_class = index[31] # 一等座
second_class = index[30] # 二等座
hard_sleeper = index[28] # 硬卧
hard_seat = index[29] # 硬座
no_seat = index[26] # 无座
soft_sleeper = index[23]# 软卧
dict = {
'序号':'page',
'车次':'num',
'出发时间':'star_time',
'到达时间':'arrive_time',
'耗时':'use_time',
'特等座':'special_class',
'一等座':'frist_class',
'二等座':'second_class',
'软卧':'soft_sleeper',
'硬卧':'hard_sleeper',
'硬座':'hard_seat',
'无座': 'no_seat'
}
tb.add_row([
page, #序号索引
num, # 车次
star_time,# 出发时间
arrive_time,# 到达时间
use_time, # 耗时
special_class, # 特等座
frist_class, # 一等座
second_class,# 二等座
soft_sleeper, # 软卧
hard_sleeper,# 硬卧
hard_seat, # 硬座
no_seat,# 无座
])
page += 1
print(tb)
# def change_chinese(chinese):
# """把中文自动转换为拼音"""
# text = pinyin(chinese, style=Style.NORMAL)
# string = ''.join(t[0] for t in text)
# return string
def selenium_login():
# 0.配置谷歌浏览器加载项
options = webdriver.ChromeOptions()
options.add_argument(f'--user-data-dir={user_data_dir}') # 添加浏览器数剧
# 1.将加载项配置到启动浏览器中 打开/创建浏览器对象
driver = webdriver.Chrome(executable_path=r'D:\game\chromedriver.exe', options=options)
# 2.输入网址
driver.get('https://kyfw.12306.cn/otn/view/index.html')
# 3.输入账号 -- > 找到账号的输入框 selenium 通过元素面板去定位元素
driver.find_element(by="css selector", value="#J-userName").send_keys(login['account'])
# 4.输入密码 -- > 找到密码的输入框
driver.find_element(by="css selector", value="#J-password").send_keys(login['password'])
# 5.点击登录按钮
driver.find_element(by="css selector", value="#J-login").click()
time.sleep(0.5)
# 6.输入身份证后4位
driver.find_element(by="css selector", value="#id_card").send_keys(login['id_card'])
# 7.点击获取验证码
driver.find_element(by="css selector", value="#verification_code").click()
# 8.输入验证码
code = input("请输入验证码:")
driver.find_element(by="css selector", value="#code").send_keys(code)
driver.find_element(by="css selector", value="#verification_code").click()
# 9.点击确认按钮
driver.find_element(by="css selector", value="#sureClick").click()
# 有时候报错是需要延时等待 用 driver.implicitly_wait(10)代码 可以实现加载完就就进行下一步,
# 而time.sleep(5)则必须等我规定的时间
driver.implicitly_wait(5)
# 10,点击车票预定按钮
driver.find_element(by="css selector", value="#link_for_ticket").click()
# 11.1 选择出发的城市--点击那个框
driver.find_element(by="css selector", value="#fromStationText").click()
# 11.2 选择出发的城市--选择城市
driver.find_element(by="css selector", value="#fromStationText").send_keys(from_city)
# 11.3 选择出发的城市--回车确定
driver.find_element(by="css selector", value="#fromStationText").send_keys(Keys.ENTER)
# 12.1 选择目的的城市--点击那个框
driver.find_element(by="css selector", value="#toStationText").click()
# 12.2 选择目的的城市--选择城市
driver.find_element(by="css selector", value="#toStationText").send_keys(to_city)
# 12.3 选择目的的城市--回车确定
driver.find_element(by="css selector", value="#toStationText").send_keys(Keys.ENTER)
# 13.1 选择出发的日期--点击那个框
driver.find_element(by="css selector", value="#train_date").clear()
# 12.2 选择出发的日期--选择城市
driver.find_element(by="css selector", value="#train_date").send_keys(train_date)
# 12.3 选择出发的日期--回车确定
driver.find_element(by="css selector", value="#train_date").send_keys(Keys.ENTER)
# # 12.4 点击--显示全部可预订的车次
# driver.find_element(by="css selector", value="avail_ticket").click()
# 12.5 点击查询
driver.implicitly_wait(5)
driver.find_element(by="css selector", value="#query_ticket").click()
num = int(input('请输入您想要的车次:'))
# 点击预订按钮 -- 选择要预定的是第几躺车 -- 这个代码没有问题
# driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()
# //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
ticket_num = ticket_list[num].get_attribute("id")
ticket_pre = ticket_num + ' > td.no-br'
# 12.6 点击想要车次的预定按钮
driver.find_element(by="css selector", value=f"#{ticket_pre}").click()
# 13.1 勾选想要的乘车人
driver.find_element(by="css selector", value='#normalPassenger_0').click()
# 13.2 提交订单
driver.find_element(by="css selector", value='#submitOrder_id').click()
driver.implicitly_wait(5)
# 13.3 选择靠窗的1F的位置
# driver.find_element(by="css selector", value='#1F').click() --这种行不通,只能下方这种
driver.find_element(by="css selector", value='#erdeng1 > ul:nth-child(4) > li:nth-child(2)').click()
# 13.4 再次确认提交
time.sleep(2)
driver.find_element(by="css selector", value='#qr_submit_id').click()
# driver.find_element(by="css selector", value='#qr_submit_id').click()
# # 14. 网上支付 -- payButton
# driver.find_element(by="css selector", value='#payButton').click()
# # 15. 取消订单 -- cancelButton
# driver.find_element(by="css selector", value='#cancelButton').click()
f = open('login.json', encoding='utf-8').read()
login = json.loads(f)
if __name__ == "__main__":
print_ticketlist()
selenium_login()