这是实现的结果,因为我一天只能取消三次,所以最后一步点击确认就评论了。1、首先实现使用selenium登录12306,关于使用selenium实现12306登录,可以看我的另一篇文章。这里是使用selenium登录12306的实现,这次是在上次修改代码的基础上实现自动购票和自动登录。12306个链接。2.按以上登录后,购买火车票分两步。这里只进行二等座查询和购票。如果要购买其他座椅,也可以自己改装。输入目的地和起点时,需要点击文本框browser.find_element_by_id('fromStationText').click(),否则输入的地址无效,日期的只读属性被去除。defsearch_railway_ticket(fromstation,tostation,train_date):#火车票页面查询urlsearch_url='https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc'#进入查询页面browser.get(search_url)time.sleep(2)#进入起点WebDriverWait(browser,1000).until(EC.presence_of_element_located((By.ID,'fromStationText')))#先点击浏览器.find_element_by_id('fromStationText').click()浏览器.find_element_by_id('fromStationText').send_keys(fromStation)browser.find_element_by_id('fromStationText').send_keys(Keys.ENTER)time.sleep(1)WebDriverWait(browser,1000).until(EC.presence_of_element_located((By.ID,'toStationText')))#Enterdestinationbrowser.find_element_by_id('toStationText').click()browser.find_element_by_id('toStationText').send_keys(tostation)browser.find_element_by_id('toStationText').send_keys(Keys.ENTER))time.sleep(5)#去掉日期的只读属性js='document.getElementById("train_date").removeAttribute("readonly")'browser.execute_script(js)#Rem超过原来的时间WebDriverWait(browser,1000).until(EC.presence_of_element_located((By.ID,'train_date')))browser.find_element_by_id("train_date").clear()#输入出发时间browser.find_element_by_id('train_date').send_keys(train_date)#等待查询按钮是否availableWebDriverWait(browser,1000).until(EC.element_to_be_clickable((By.ID,'query_ticket')))searBtn=browser.find_element_by_id('query_ticket')searBtn.click()print('点击按钮')2.买火车票在这个函数中需要注意的是最后一步最好注释掉browser.find_element_by_id('qr_submit_id').click()因为订单一天只能取消3次defbuy_ticket(fromstation,tostation,train_date,train_number,passenger):#查询火车票search_railway_ticket(fromstation,tostation,train_date)time.sleep(5)#获取每趟火车的信息tr_list=browser.find_elements_by_xpath('.//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')fortrintr_list:#获取车次number=tr.find_element_by_class_name('number').textifnumberintrain_number:#获取是否有车票left_ticket=tr.find_element_by_xpath('./td[4]').textifleft_ticket=='have'orleft_ticket.isdigit:print(f'{number}有票')#点击预定orderBtn=tr.find_element_by_class_name('btn72')orderBtn.click()time.sleep(5)#获取12306乘客信息passenger_list=browser.find_elements_by_xpath('//*[@id="normal_passenger_id"]/li')forliinpassenger_list:name=li.find_element_by_xpath('./label').textprint(name)#配对12306名字ifname==passenger:li.find_element_by_tag_name('input').click()#提交订单submit=browser.find_element_by_id('submitOrder_id')submit.click()WebDriverWait(browser,1000).until(EC.element_to_be_clickable((By.ID,'qr_submit_id')))#一天只能取消3次,所以最后一步最好注释一下browser.find_element_by_id('qr_submit_id').click()print('订单已提交')break下面是测试时的源代码#click_captcha()这个点击验证码去掉手动点击,这样就不用扣超级鹰的积分了(有钱我没说),留下贫穷的眼泪fromseleniumimportwebdriverfromselenium.webdriverimportActionchainsimporttimefromPILimportImageimportrequestsfromhashlibimportmd5fromselenium.webdriverimportChromeOptions#验证码识别处理fromselenium.webdriver.common.keysimportKeysfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.waitimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECclassChaojiying_Client(object):def__init__(self,username,password,soft_id):self.username=usernamepassword=password.encode('utf8')self.password=md5(password).hexdigest()self.soft_id=soft_idself.base_params={'user':self.username,'pass2':self.password,'softid':self.soft_id,}self.headers={'Connection':'Keep-Alive','User-Agent':'Mozilla/4.0(compatible;MSIE8.0;WindowsNT5.1;Trident/4.0)',}defPostPic(self,im,codetype):"""im:图片字母节codetype:题目类型参考http://www.chaojiying.com/price.html"""params={'codetype':codetype,}params.update(self.base_params)files={'用户文件':('ccc.jpg',im)}r=requests.post('http://upload.chaojiying.net/Upload/Processing.php',data=params,files=files,headers=self.headers)returnr.json()defReportError(self,im_id):"""im_id:错误主题图片的ID"""params={'id':im_id,}params.update(self.base_params)r=requests.post('http://upload.chaojiying.net/Upload/ReportError.php',data=params,headers=self.headers)returnr.json()deflogin(username,password):#填写账号密码browser.find_element_by_id('J-userName').send_keys(username)browser.find_element_by_id('J-password').send_keys(password)#获取验证码get_captcha()#填写验证码click_captcha()#点击登录time.sleep(4)browser.find_element_by_id('J-login').click()time.sleep(4)#滑动验证码slider()print('登录成功')time.sleep(5)defslider():#滑动验证码WebDriverWait(浏览器,1000)。直到(EC.presence_of_element_located((By.XPATH,'//*[@id="nc_1_n1z"]')))span=browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')#todiv_tag执行滑动操作action=Actionchains(browser)#点击并按住指定的标签action.click_and_hold(span).perform()action.drag_and_drop_by_offset(span,400,0).perform()defclick_captcha():#需要获取验证码的位置是点击位置chaojiying=Chaojiying_Client('你自己的用户名','password','Softwareid')#用户中心>>软件ID生成替换96001im=open('./captcha.png','rb').read()#本地图片文件路径替换a.jpg有时WIN系统需要//location=chaojiying.PostPic(im,9004)['pic_str']#1902验证码类型官网>>价格系统3.4+版本打印后要加上()print(chaojiying.PostPic(im,9004))#将位置拆分为[[],[],[]]类型location_list=[i.split(',')foriinlocation.split('|')]forlinlocation_list:x=l[0]y=l[1]Actionchains(浏览器).move_to_element_with_offset(browser.find_element_by_class_name('login-pwd-code'),int(x),int(y)).click().perform()time.sleep(0.5)defget_captcha():#获取网页截图allscreen=browser.get_screenshot_as_file('allscreen.png')#获取验证码captcha=browser.find_element_by_class_name('login-pwd-code')#获取验证码左上角位置location=captcha.location#获取图片大小size=captcha.size#截取captcharangle=(location['x'],location['y'],(location['x']+size['width']),(location['y']+size['height']))i=Image.open('./allscreen.png')captcha_img='./captcha.png'frame=i.crop(rangle)frame.save(captcha_img)defbuy_ticket(fromstation,tostation,train_date,train_number,passenger):#查询火车票search_railway_ticket(fromstation,tostation,train_date)time.sleep(5)tr_list=browser.find_elements_by_xpath('.//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')fortrintr_list:number=tr.find_element_by_class_name('number').textifnumberintrain_number:left_ticket=tr.find_element_by_xpath('./td[4]').textifleft_ticket=='有'orleft_ticket.isdigit:print(f'{number}还有票')orderBtn=tr.find_element_by_class_name('btn72')orderBtn.click()time.sleep(5)passenger_list=browser.find_elements_by_xpath('//*[@id="normal_passenger_id"]/li')forliinpassenger_list:name=li.find_element_by_xpath('./label').textifname==passenger:li.find_element_by_tag_name('input').click()submit=browser.find_element_by_id('submitOrder_id')submit.click()WebDriverWait(browser,1000).until(EC.element_to_be_clickable((By.ID,'qr_submit_id')))#一天只能取消3次,所以最后一步要注释掉#browser.find_element_by_id('qr_submit_id').click()print('订单已提交')breakdefsearch_railway_ticket(fromstation,tostation,train_date):#火车票页面查询urlsearch_url='https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc'#进入查询页面browser.get(search_url)time.sleep(2)#进入起始位置WebDriverWait(browser,1000).until(EC.presence_of_element_located((By.ID,'fromStationText')))#点击browser.find_element_by_id('fromStationText').click()browser.find_element_by_id('fromStationText').send_keys(fromstation)browser.find_element_by_id('fromStationText').send_keys(Keys.ENTER)time.sleep(1)WebDriverWait(browser,1000).直到(EC.presence_of_element_located((By.ID,'toStationText')))#Enterdestinationbrowser.find_element_by_id('toStationText').click()browser.find_element_by_id('toStationText').send_keys(tostation)browser.find_element_by_id('toStationText').send_keys(Keys.ENTER)时间。sleep(5)#去掉日期的只读属性js='document.getElementById("train_date").removeAttribute("readonly")'browser.execute_script(js)#去掉原来的时间WebDriverWait(browser,1000).until(EC.presence_of_element_located((By.ID,'train_date')))browser.find_element_by_id("train_date").clear()#输入出发时间browser.find_element_by_id('train_date').send_keys(train_date)#等待查询按钮是否可用WebDriverWait(browser,1000).until(EC.element_to_be_clickable((By.ID,'query_ticket')))searBtn=browser.find_element_by_id('query_ticket')searBtn.click()print('点击按钮')if__name__=='__main__':option=ChromeOptions()#实例化一个ChromeOptions对象option.add_experimental_option('excludeSwitches',['enable-automation'])#以键值对的形式添加参数option.add_experimental_option('useAutomationExtension',False)browser=webdriver.Chrome(options=option)#获取响应browser.get('https://kyfw.12306.cn/otn/resources/login.html')script='Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'browser.execute_script(script)browser.maximize_window()time.sleep(1)#点击账号登录browser.find_element_by_class_name('login-hd-account').click()#登录12306账号密码login('username','password')time.sleep(4)#examplebuy_ticket('南昌','福州北','2020-12-15','D2241','xx')buy_ticket('出发地','目的地','出发日期','车次','姓名')【小编推荐】2019Django全套教程【千峰Python】Spark大数据处理与机器学习【基于Python的Spark2.3**版】人工智能工程师-自然语言处理(Python版)OpencVPython零基础入门视频教程Python数据库视频教程MySQL数据库(7)
