python实现自动登录12306抢票 -- selenium

news2025/5/15 19:15:41

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

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()

三、进阶–展望

1.首先可以将自动化操作用try–except,这样不会一直报错,更为规范。

2.免登录:因为登录其实要验证码,这样抢票也不方便。于是我就又继续学习了一些,发现了两种方法一是可以保存浏览器的数据,因为selenium每次打开的是一个新的程序,但是我们可以通过设置参数,让他打开是有记忆的,但是没有用。第二种,是cookie,是没有什么问题的,目前已经实现,接下尝试各种方法的cookie看行不行。后续我会发此程序。

3.多线程多进程:主要我已经实现cookie免登录,我想着是否可以打开多个页面,然后多个账号,一起抢他们所需要的票呢。

总结

1.最开始跟着写这个程序只会照着抄,然后根本不懂,后面就是差了一点点成功,也不会找错误。

2.后面学习了一下爬虫,更明白一点语法以及自己也更会如何定位元素了。还有就是request的一个请求,这些代码也更看得懂了

3.想着结合多线程然后实现批量抢票,同时也希望代价的容错率高,也就是说在自动化不用点几下程序就不行了,让它可以有更好的性能。-- 未来学习的一个点。加油!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2270046.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙1.2:第一个应用

1、create Project,选择Empty Activity 2、配置项目 project name 为项目名称,建议使用驼峰型命名 Bundle name 为项目包名 Save location 为保存位置 Module name 为模块名称,即运行时需要选择的模块名称,见下图 查看模块名称&…

Docker安装(Docker Engine安装)

一、Docker Engine和Desktop区别 Docker Engine 核心组件:Docker Engine是Docker的核心运行时引擎,负责构建、运行和管理容器。它包括守护进程(dockerd)、API和命令行工具客户端(docker)。适用环境&#…

Ceph 手动部署(CentOS9)

#Ceph手动部署、CentOS9、squid版本、数字版本19.2.0 #部署服务:块、对象、文件 一、部署前规划 1、兼容性确认 2、资源规划 节点类型节点名称操作系统CPU/内存硬盘网络组件安装集群节点CephAdm01CentOS94U/8GOS:40G,OSD:2*100GIP1:192.169.0.9(管理&集群),IP2:…

springboot-启动流程

by shihang.mai 1. 启动流程图 查看springboot2.3.7源码后绘制下图。 springboot启动流程图 main启动,new SpringApplication()构造方法里面 判断当前应用程序类型reactive、servlet、none获取所有的ApplicationListener对应的对象获取所有的ApplicationContextInit…

Flutter:打包apk,详细图文介绍(一)

困扰了一天,终于能正常打包apk安装了,记录下打包的流程。建议参考我这篇文章时,同时看下官网的构建说明。 官网构建并发布 Android 应用详情 1、AS创建Flutter项目 2、cmd执行命令 生成一个sunluyi.jks的文件,可以自行把sunluyi替…

linux下安装tun模块详细教程

原本是要看tcp/ip协议栈,找到了https://github.com/chobits/tapip这个。然后需要支持tun,完了开始安装。 TUN/TAP是一个虚拟网络设备,用于实现用户态程序和内核网络协议栈之间的数据交互。 1、安装环境 我的系统是ubuntu16.04 VMWare虚拟机&a…

Ajax数据爬取

有时我们用requests 抓取页面得到的结果,可能和在浏览器中看到的不一样:在浏览器中可以看到正常显示的页面数据,而使用requests 得到的结果中并没有这些数据。这是因为 requests 获取的都是原始 HTML 文档,而浏览器中的页面是JavaScript 处理…

Docker 安装与配置 Nginx

摘要 1、本文全面介绍了如何在 Docker 环境中安装和配置 Nginx 容器。 2、文中详细解释了如何设置 HTTPS 安全连接及配置 Nginx 以实现前后端分离的代理服务。 2、同时,探讨了通过 IP 和域名两种方式访问 Nginx 服务的具体配置方法 3、此外,文章还涵…

SpringCloud微服务架构

文章目录 认识微服务:SpringCloud 服务拆分及远程调用实现夸远程服务调用使用RestTemplateEureka注册中心 搭建EruekaServer注册服务服务发现 Ribbon负载均衡 修改负载均衡规则解饿加载 Nacos注册中心(nacos一部分功能) 服务注册到nacosnacos…

WireShark4.4.2浏览器网络调试指南:TCP传输包分析(七)

概述 在使用Wireshark进行网络分析时,理解每一个数据包的组成部分对于网络分析非常重要。特别是在TCP协议中的“三次握手”过程中,每个数据包会包含多个层次的信息,从帧信息到TCP协议的详细内容。下面是对TCP握手过程中第一个SYN数据包的详细…

kafka使用常见问题

连接不上kafka,报下边的错 org.apache.kafka.common.KafkaException: Producer is closed forcefully.at org.apache.kafka.clients.producer.internals.RecordAccumulator.abortBatches(RecordAccumulator.java:760) [kafka-clients-3.0.2.jar:na]at org.apache.kafka.client…

用uniapp写一个播放视频首页页面代码

效果如下图所示 首页有导航栏&#xff0c;搜索框&#xff0c;和视频列表&#xff0c; 导航栏如下图 搜索框如下图 视频列表如下图 文件目录 视频首页页面代码如下 <template> <view class"video-home"> <!-- 搜索栏 --> <view class…

深入浅出:从入门到精通大模型Prompt、SFT、RAG、Infer、Deploy、Agent

阅读原文 渐入佳境 我们都知道&#xff0c;通过编写一个提示词&#xff08;prompt&#xff09;&#xff0c;我们可以引导大模型生成回答&#xff0c;从而开启愉快的人工智能对话&#xff0c;比如让模型介绍一下卡皮巴拉。上边简图描述了这个过程&#xff0c;我们拆成两部分 pr…

Unity-Mirror网络框架-从入门到精通之Basic示例

文章目录 前言Basic示例场景元素预制体元素代码逻辑BasicNetManagerPlayer逻辑SyncVars属性Server逻辑Client逻辑 PlayerUI逻辑 最后 前言 在现代游戏开发中&#xff0c;网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架&#xff0c;专为多人…

【新方法】通过清华镜像源加速 PyTorch GPU 2.5安装及 CUDA 版本选择指南

下面详细介绍所提到的两条命令&#xff0c;它们的作用及如何在你的 Python 环境中加速 PyTorch 等库的安装。 1. 设置清华镜像源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple这条命令的作用是将 pip &#xff08;Python 的包管理工具&#xf…

自动化测试-Pytest测试

目录 pytest简介 基本测试实例 编写测试文件 执行测试 pytest运行时参数 mark标记 Fixture pytest插件 Allure测试报告 测试步骤 pytest简介 Pytest‌是一个非常流行的Python测试框架&#xff0c;它支持简单的单元测试和复杂的功能测试&#xff0c;具有易于上手、功…

Java-33 深入浅出 Spring - FactoryBean 和 BeanFactory BeanPostProcessor

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

MySQL 服务器简介

通常所说的 MySQL 服务器指的是mysqld程序&#xff0c;当运⾏mysqld后对外提供MySQL 服务&#xff0c;这个专题的内容涵盖了以下关于MySQL 服务器以及相关配置的内容&#xff0c;包括&#xff1a; 服务器⽀持的启动选项。可以在命令⾏和配置⽂件中指定这些选项。 服务器系统变…

分布式版本管理工具——Git关联远程仓库(github+gitee)

Git远程仓库&#xff08;Github&#xff09;的基本使用 一、前言二、Git远程仓库介绍三、演示1. 关联github远程仓库2. 关联gitee&#xff08;码云&#xff09;远程仓库3. 重命名远程仓库名4. 移除远程仓库 四、结束语 一、前言 古之立大事者&#xff0c;不惟有超世之才&#x…

ZLib库使用详细教程 以及标准ZLib函数和QT自带压缩函数比较

1. 下载Zlib 官网下载地址如下&#xff1a;http://www.zlib.net/ 2. 利用cmake编译zlib 有两种方法可以打开cmake-gui winR输入cmd打开命令行&#xff0c;在命令行中输入cmake-gui可以直接打开应用界面找到你一开始安装cmake的文件夹&#xff0c;在bin子文件夹中双击cmake-…