python+selenium实现12306抢票
一、准备工作
1、要先下载相关的包,selenium、interval。最好使用国内清华源
pip install (which package) -i https://pypi.tuna.tsinghua.edu.cn/simple
2、还要下载对应浏览器的驱动:
2.1 安装chromedriver
谷歌浏览器驱动的网址为link
注意:谷歌浏览器的驱动版本要匹配谷歌浏览器的版本
随机点击一个版本:
点击notes.txt
文章来源:https://www.toymoban.com/news/detail-427668.html
2.2 安装FireFox驱动(我用的是这个)
火狐驱动下载网址:link
然后一样的下载对应的驱动版本文章来源地址https://www.toymoban.com/news/detail-427668.html
2.3 最后把下载好的驱动解压,移动到/usr/bin文件夹(linux系统)中或者放入python一级目录下就好了
二、具体实现过程(代码有具体注释)
from selenium import webdriver
from time import sleep#页面等待时间
from selenium.webdriver.common.by import By#定位元素
from selenium.webdriver import ActionChains#完成一系列自动化操作
from selenium.webdriver.common.keys import Keys#完成键盘上的操作
from collections import defaultdict#初始化字典,value为列表
import re#用于正则表达式
# from datetime import datetime
from interval import IntervalSet#用于定义时间区间
# import json
class TrainTicketLogin(object):
def __init__(self):
#12306登录网页的网址
self.url='https://kyfw.12306.cn/otn/resources/login.html'
#你自己的用户名
self.userName='XXXXXXXXXXX'
#你自己的密码
self.passWord='XXXXXX'
#我用的是火狐浏览器,如果用的是谷歌,要提前下载好对应浏览器的驱动,这里实例化一个浏览器操作对象
self.options=webdriver.Firefox()
def login(self,url):
self.options.get(self.url)
login_method=self.options.find_element(By.XPATH,'//div[@class="login-box"]/ul/li[1]/a')
login_method.click()
userName_tag=self.options.find_element(By.ID,"J-userName")
passWord_tag=self.options.find_element(By.ID,"J-password")
userName_tag.send_keys(self.userName)
passWord_tag.send_keys(self.passWord)
btn=self.options.find_element(By.ID,"J-login")
btn.click()
sleep(3)
slide_btn=self.options.find_element(By.XPATH,'//*[@id="nc_1_n1z"]')
self.Verification(slide_btn)
def Verification(self,button):
action1=ActionChains(self.options)
# 防止12306网站禁止selenium而出现的error
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
self.options.execute_script(script)
action1.click_and_hold(button)
action1.move_by_offset(300,0).perform()
#释放鼠标
action1.release().perform()
sleep(1)
def get_ticket(self):
chepiao_button=self.options.find_element(By.XPATH,'//a[@id="link_for_ticket"]')
chepiao_button.click()
sleep(3)
origin=self.options.find_element(By.ID,"fromStationText")
arrival=self.options.find_element(By.ID,"toStationText")
date=self.options.find_element(By.ID,"train_date")
my_chufa=IntervalSet.between(self.l_time_interval_left,self.l_time_interval_right)
my_daoda=IntervalSet.between(self.a_time_interval_left,self.a_time_interval_right)
#出发地键入
origin.click()
origin.send_keys(self.loc_l)
origin.send_keys(Keys.ARROW_DOWN)
origin.send_keys(Keys.ENTER)
sleep(1)
#目的地键入
arrival.click()
arrival.send_keys(self.loc_a)
arrival.send_keys(Keys.ARROW_DOWN)
arrival.send_keys(Keys.ENTER)
sleep(1)
#出发日期键入
date.clear()
date.send_keys(self.go_date)
date.send_keys(Keys.ENTER)
#是否选择学生票(若为普通票则注释掉以下代码)
# self.options.find_element(By.ID,"sf2").click()
#点击查询操作
query_button=self.options.find_element(By.XPATH,'//div[@class="btn-area"]/a')
query_button.click()
#请输入选择的train型号(K字头还是G字头还是D字头还是其他)
sleep(5)
#进行正则匹配
ex='<tr id="ticket_(.*?)" class.*?>'
train_info=defaultdict(list)
train_type=re.findall(ex,self.options.page_source)
for train in train_type:
xpath_1='//tr[@id=\"{}\"]/td[1]/div/div[3]/strong[1]'.format('ticket_'+train)
xpath_2='//tr[@id=\"{}\"]/td[1]/div/div[3]/strong[2]'.format('ticket_'+train)
origin_time=self.options.find_element(By.XPATH,xpath_1).text
arrive_time=self.options.find_element(By.XPATH,xpath_2).text
train_info[train]=[origin_time,arrive_time]
#预览一下火车的信息
# print(train_info)
#请输入你理想的乘车时间区间和到达时间区间
for key,value in train_info.items():
if self.train_ in key.split('_')[0]:
xpath_3='//*[@id=\"{}\"]'.format(self.type+'_'+key.split('_')[0])
left_tickets=self.options.find_element(By.XPATH,xpath_3).text
if value[0] in my_chufa and value[1] in my_daoda and \
(left_tickets.isdigit() or left_tickets=='有'):
xpath_4='//tr[@id=\"{}\"]//*[@class="btn72"]'.format('ticket_'+key)
self.options.find_element(By.XPATH,xpath_4).click()
#请选择乘车人,这里选择默认乘车人(第一个人)
sleep(2)
self.options.find_element(By.XPATH,'//*[@id="normalPassenger_0"]').click()
sleep(2)
self.options.find_element(By.XPATH,'//*[@id="submitOrder_id"]').click()
#确定买票(等待较长时间才能锁定席位)
sleep(2)
self.options.find_element(By.XPATH,'//*[@id="qr_submit_id"]').click()
#返回修改
# sleep(2)
# self.options.find_element(By.XPATH,'//*[@id="back_edit_id"]').click()
def run(self):
self.login(self.url)
sleep(5)
hint=self.options.find_element(By.XPATH,'//div[@class="modal-ft"]/a')
hint.click()
sleep(3)
self.loc_l=input("请输入出发地:")
self.loc_a=input("请输入目的地:")
self.go_date=input("请输入出发日期(格式为%Y-%m-%d的形式):")
self.l_time_interval_left=input("请输入理想出发时间的左端点:")
self.l_time_interval_right=input("请输入理想出发时间的右端点:")
self.a_time_interval_left=input("请输入理想到达时间的左端点:")
self.a_time_interval_right=input("请输入理想到达时间的右端点:")
self.train_=input("你想坐高铁还是火车还是动车(G、K、D、T):")
if self.train_ in ['K','T']:
# 如果选择火车(软卧、硬卧、硬座)
self.type=input("请输入你要乘坐的类型(RW、YW、YZ):")
else:
self.type=input("请输入你要乘坐的类型(SWZ(商务座)、ZY(一等座)、ZE(二等座)):")
self.get_ticket()
# self.options.quit()
if __name__=='__main__':
Spider=TrainTicketLogin()
Spider.run()
到了这里,关于python+selenium实现12306抢票的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!