针对这个话题,我为您提供以下完整攻略。
目标
使用 Python 抢购过年期间的火车票
准备
- Python3 环境
- 12306 的账户和密码
- chromedriver.exe 驱动程序
方法
第一步:获取 cookies
由于火车票系统需要登录才能进行查询和购票,我们需要使用 selenium
来模拟浏览器操作。
打开 12306 首页,手动登录账户,然后进入浏览器的 Console (F12),输入如下代码,来获取 cookies:
JSON.stringify(document.cookie)
这个命令将会返回一个 JSON 对象,里面包含了我们之后代码将要使用的 cookies。
第二步:跳转到查询页面
登录之后,我们需要点击左侧“车票预订”菜单,然后进入查询页面。
以下是一个简单的 Python 代码,用于跳转到火车票查询页面:
from selenium import webdriver
# 初始化一个 Chrome driver 实例
driver = webdriver.Chrome(r'path/to/chromedriver.exe')
# 打开 12306 网站
driver.get('https://www.12306.cn/index/')
# 等待登录完成之后,手动点击“车票预订”菜单
# 等待页面加载完成
driver.implicitly_wait(10)
# 跳转到查询页面
driver.get('https://kyfw.12306.cn/otn/leftTicket/init')
这段代码使用 webdriver.Chrome
初始化了一个 Chrome 浏览器的驱动实例。然后打开了 12306 的首页,并等待用户手动完成登录操作。
等页面加载完成后,使用 driver.get
接口跳转到查询页面。
第三步:查询余票
在 12306 的查询页面上,我们需要填写起始站点、终点站点、以及出发时间,然后点击“查询”按钮来查询余票信息。
以下是 Python 代码的示例,用于查询从上海到北京的余票信息:
from selenium.webdriver.common.keys import Keys
# 定义出发地、目的地、出发时间
from_station = 'SHH'
to_station = 'BJP'
date = '2022-01-02'
# 填写查询信息
driver.find_element_by_id('fromStationText').send_keys(from_station)
driver.find_element_by_id('toStationText').send_keys(to_station)
driver.find_element_by_id('train_date').clear()
driver.find_element_by_id('train_date').send_keys(date)
driver.find_element_by_id('train_date').send_keys(Keys.RETURN)
# 等待查询结果返回
driver.implicitly_wait(10)
# 查询余票
tickets = driver.find_elements_by_xpath('//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
# 处理查询结果
for ticket in tickets:
print(ticket.text)
这段代码使用 find_element_by_id
和 send_keys
方法,填写了查询表单上的信息,并通过 Keys.RETURN
模拟了用户单击“查询”按钮。
等待查询结果返回后,我们使用 find_elements_by_xpath
选择器,来获取所有查询结果的 DOM 元素。
最后我们使用一个 for
循环,遍历所有的查询结果,并输出到控制台上,这里我们只是简单地将结果打印到控制台上,实际应该根据自己的需要,做出更复杂的处理操作。
第四步:提交订单
当查询到有余票之后,我们需要立即执行下一步操作 - 提交订单。以下是一个 Python 代码的示例,它用于选择指定的车次,然后提交订单:
# 找到指定车次
target_train = None
for ticket in tickets:
if ticket.find_element_by_class_name('number').text == 'G101':
# 找到了需要的车次
target_train = ticket
break
if target_train is not None:
# 选择座位,并加入购物车
target_train.find_element_by_css_selector('td.no-br>a').click() # 点击预订按钮
driver.implicitly_wait(10)
driver.find_element_by_id('seatType_1').click() # 选择二等座
driver.find_element_by_id('submitOrder_id').click() # 加入购物车
# 等待提交窗口
driver.implicitly_wait(10)
# 点击进入下一步
driver.find_element_by_id('qr_submit_id').click()
这段代码首先找到指定的车次,然后选择座位类型,并加入购物车。
然后,我们通过 driver.find_element_by_id('qr_submit_id').click()
模拟了用户点击“提交订单”按钮。
第五步:填写订单信息
在提交订单之后,我们需要填写订单信息,然后才能进行支付。
以下是一个 Python 代码的示例,用于填写订单信息并提交:
from selenium.webdriver.common.by import By
# 等待订单信息窗口出现
driver.find_element(By.ID, 'normal_passenger_id0').click()
driver.find_element(By.NAME, 'submitOrder').click()
# 等待页面加载完成
driver.implicitly_wait(10)
# 填写联系人信息
name = 'XXX'
id_type = '1'
id_number = 'XXXXXXXXXXXXXXXXXX'
phone_number = 'XXXXXXXXXXX'
driver.find_element(By.ID, 'normalPassenger_0').click()
driver.implicitly_wait(1)
driver.find_element(By.ID, 'lianxiren').send_keys(name)
driver.find_element(By.ID, 'sfz_number').send_keys(id_number)
driver.find_element(By.ID, 'mobile_no').send_keys(phone_number)
driver.find_element(By.ID, 'submitOrder').click()
# 等待加载完成
driver.implicitly_wait(10)
# 点击同意协议并提交订单
driver.find_element(By.ID, 'qr_submit_id').click()
这段代码首先在页面加载之后,尝试点击“提交订单”按钮。然后,填写乘客信息,并勾选“同意协议”,最后点击“提交订单”按钮。
示例
示例一:查询从上海到北京的余票信息
我们使用如下 Python 代码的示例来查询从上海到北京的余票信息:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 初始化一个 Chrome driver 实例
driver = webdriver.Chrome(r'path/to/chromedriver.exe')
# 打开 12306 网站
driver.get('https://www.12306.cn/index/')
# 等待登录完成之后,手动点击“车票预订”菜单
# 等待页面加载完成
driver.implicitly_wait(10)
# 跳转到查询页面
driver.get('https://kyfw.12306.cn/otn/leftTicket/init')
# 定义出发地、目的地、出发时间
from_station = 'SHH'
to_station = 'BJP'
date = '2022-01-02'
# 填写查询信息
driver.find_element_by_id('fromStationText').send_keys(from_station)
driver.find_element_by_id('toStationText').send_keys(to_station)
driver.find_element_by_id('train_date').clear()
driver.find_element_by_id('train_date').send_keys(date)
driver.find_element_by_id('train_date').send_keys(Keys.RETURN)
# 等待查询结果返回
driver.implicitly_wait(10)
# 查询余票
tickets = driver.find_elements_by_xpath('//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
# 处理查询结果
for ticket in tickets:
print(ticket.text)
# 关闭浏览器
driver.close()
这段代码首先打开了 12306 的网站,并跳转到了查询页面。然后,使用 find_element_by_id
和 send_keys
方法填写查询表单信息,并通过 Keys.RETURN
模拟单击“查询”按钮。
等待查询结果之后,我们通过 find_elements_by_xpath
获取了所有的查询结果,然后将它们输出到了控制台上。
示例二:预定从上海到北京的火车票
以下是一个 Python 代码的示例,用于预定从上海到北京的火车票:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
# 初始化一个 Chrome driver 实例
driver = webdriver.Chrome(r'path/to/chromedriver.exe')
# 打开 12306 网站
driver.get('https://www.12306.cn/index/')
# 等待登录完成之后,手动点击“车票预订”菜单
# 等待页面加载完成
driver.implicitly_wait(10)
# 跳转到查询页面
driver.get('https://kyfw.12306.cn/otn/leftTicket/init')
# 定义出发地、目的地、出发时间
from_station = 'SHH'
to_station = 'BJP'
date = '2022-01-02'
# 填写查询信息
driver.find_element_by_id('fromStationText').send_keys(from_station)
driver.find_element_by_id('toStationText').send_keys(to_station)
driver.find_element_by_id('train_date').clear()
driver.find_element_by_id('train_date').send_keys(date)
driver.find_element_by_id('train_date').send_keys(Keys.RETURN)
# 等待查询结果返回
driver.implicitly_wait(10)
# 查询余票
tickets = driver.find_elements_by_xpath('//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
# 处理查询结果
for ticket in tickets:
if ticket.find_element_by_class_name('number').text == 'G101':
# 找到了需要的车次
target_train = ticket
break
# 选择座位,并加入购物车
target_train.find_element_by_css_selector('td.no-br>a').click() # 点击预订按钮
driver.implicitly_wait(10)
driver.find_element_by_id('seatType_1').click() # 选择二等座
driver.find_element_by_id('submitOrder_id').click() # 加入购物车
# 等待提交窗口
driver.implicitly_wait(10)
# 点击进入下一步
driver.find_element_by_id('qr_submit_id').click()
# 等待订单信息窗口出现
driver.find_element(By.ID, 'normal_passenger_id0').click()
driver.find_element(By.NAME, 'submitOrder').click()
# 等待页面加载完成
driver.implicitly_wait(10)
# 填写联系人信息
name = 'XXX'
id_type = '1'
id_number = 'XXXXXXXXXXXXXXXXXX'
phone_number = 'XXXXXXXXXXX'
driver.find_element(By.ID, 'normalPassenger_0').click()
driver.implicitly_wait(1)
driver.find_element(By.ID, 'lianxiren').send_keys(name)
driver.find_element(By.ID, 'sfz_number').send_keys(id_number)
driver.find_element(By.ID, 'mobile_no').send_keys(phone_number)
driver.find_element(By.ID, 'submitOrder').click()
# 等待加载完成
driver.implicitly_wait(10)
# 点击同意协议并提交订单
driver.find_element(By.ID, 'qr_submit_id').click()
# 关闭浏览器
driver.close()
这段代码首先打开了 12306 的网站,并跳转到了查询页面。然后,使用 find_element_by_id
和 send_keys
方法填写查询表单信息,并通过 Keys.RETURN
模拟单击“查询”按钮。
等待查询结果之后,我们通过 find_elements_by_xpath
获取了所有的查询结果,并找到了指定的车次。
接下来,我们选择了二等座,并添加到购物车中。然后,我们点击“提交订单”按钮,并填写了订单信息。最后,我们点击“同意协议”按钮并提交订单。
结论
本方法主要利用 Python 的 selenium
库来模拟浏览器操作,实现了自动查询余票、预定火车票等功能。在实际应用中,我们需要对代码进行优化和改进,来确保系统的稳定性和可靠性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:用Python抢过年的火车票附源码 - Python技术站