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
2.2 安装FireFox驱动(我用的是这个)
火狐驱动下载网址:link
然后一样的下载对应的驱动版本
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 datetimefrom interval import IntervalSet#用于定义时间区间# import jsonclassTrainTicketLogin(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()deflogin(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)defVerification(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)defget_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()defrun(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()
本文转载自: https://blog.csdn.net/weixin_43209121/article/details/126664792
版权归原作者 TAO-LaVine 所有, 如有侵权,请联系我们删除。
版权归原作者 TAO-LaVine 所有, 如有侵权,请联系我们删除。