概述
上一篇写了12306的自动登录破解验证图https://blog.csdn.net/weixin_38283159/article/details/86498159
这篇算是它的后续部分加上了简单的刷票和预订功能,毕竟登录一下没什么实际价值嘛
博主曾被黄牛挣过一百大洋至今还耿耿于怀,不清楚他们到达是如何抢票的,我能想到的简单方案就是不断的刷新判断了…
效果图(自动登录部分gif见上篇)
思路就是用selenium模拟我们买票的流程,所以就不详细说了
代码
说明:代码只处理了二等座(一等座也适用,EF位置不能选),和无需选位置的(关于硬卧等类型是否能够选上下铺我也不知道)
#coding:u8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import requests
import base64
import re
import time
import os
class Demo():
def __init__(self,user_name="531218020@qq.com",pass_word="***********"):
self.coordinate=[[-105,-20],[-35,-20],[40,-20],[110,-20],[-105,50],[-35,50],[40,50],[110,50]]
self.position=["A","B","C","D","E","F"]
self.type=["一等座","二等座","硬座","硬卧","软卧","商务座"]
self.type_code=["M","0","1","3","4","9"]
self.user_name=user_name
self.pass_word=pass_word
with open("code.json", 'r') as file:
code=eval(file.read())
self.from_station=code[input("From station:")]
self.to_station=code[input("To station:")]
self.train_date=input("出发时间(年-月-日):")
self.is_student=bool(input("Is student(0/1):"))
login_url="https://kyfw.12306.cn/otn/resources/login.html"
driver = webdriver.Chrome()
driver.set_window_size(1200, 900)
driver.get(login_url)
self.driver=driver
if not os.path.exists("verify"):
os.mkdir("verify")
if os.path.exists("verify.jpg"):
name=os.path.join("verify",str(len(os.listdir("verify")))+".jpg")
os.rename("verify.jpg",name)
def login(self):
account=self.driver.find_element_by_class_name("login-hd-account")
account.click()
userName=self.driver.find_element_by_id("J-userName")
userName.send_keys(self.user_name)
password=self.driver.find_element_by_id("J-password")
password.send_keys(self.pass_word)
def getVerifyImage(self):
try:
img_element =WebDriverWait(self.driver, 100).until(
EC.presence_of_element_located((By.ID, "J-loginImg"))
)
except Exception as e:
print(u"网络开小差,请稍后尝试")
base64_str=img_element.get_attribute("src").split(",")[-1]
imgdata=base64.b64decode(base64_str)
with open('verify.jpg','wb') as file:
file.write(imgdata)
self.img_element=img_element
def getVerifyResult(self):
url="http://littlebigluo.qicp.net:47720/"
response=requests.request("POST",url,data={"type":"1"},files=files={'pic_xxfile':open('verify.jpg','rb')})
result=[]
#print(response.text)
try:
for i in re.findall("<B>(.*)</B>",response.text)[0].split(" "):
result.append(int(i)-1)
except Exception as e:
print(u"图像处理服务器繁忙,请稍后尝试")
self.result=result
def moveAndClick(self):
try:
self.Action=ActionChains(self.driver)
for i in self.result:
self.Action.move_to_element(self.img_element).move_by_offset(self.coordinate[i][0],self.coordinate[i][1]).click()
self.Action.perform()
except Exception as e:
print(e.message())
def submit(self):
self.driver.find_element_by_id("J-login").click()
def queryTicket(self):
query_url="https://kyfw.12306.cn/otn/leftTicket/init"
self.driver.get(query_url)
self.driver.execute_script("document.getElementById('fromStation').removeAttribute('type')")
fromStation=self.driver.find_element_by_id("fromStation")
fromStation.send_keys(self.from_station)
self.driver.execute_script("document.getElementById('toStation').removeAttribute('type')")
toStation=self.driver.find_element_by_id("toStation")
toStation.send_keys(self.to_station)
self.driver.execute_script("document.getElementById('train_date').removeAttribute('readonly')")
trainDate=self.driver.find_element_by_id("train_date")
trainDate.clear()
trainDate.send_keys(self.train_date)
if self.is_student:
self.driver.find_element_by_id("sf2").click()
self.driver.find_element_by_id("query_ticket").click()
def ticketOrder(self):
trains=self.driver.find_elements_by_class_name("number")
for i,item in enumerate(trains):
print("【{}】{}".format(i,item.text))
num=input("请输入预定车次编号:")
self.driver.find_elements_by_class_name("btn72")[int(num)].click()
ul=WebDriverWait(self.driver, 100).until(
EC.presence_of_element_located((By.ID, "normal_passenger_id"))
)
time.sleep(1)
lis=ul.find_elements_by_tag_name("li")
for i,item in enumerate(lis):
print("【{}】{}".format(i,item.find_elements_by_tag_name("label")[0].text))
num=input("请输入购票人编号:")
buy_num=int(num)
lis[int(num)].find_elements_by_tag_name('input')[0].click()
if self.is_student:
self.driver.find_element_by_id("dialog_xsertcj_ok").click()
else:
self.driver.find_element_by_id("dialog_xsertcj_cancel").click()
seatType=self.driver.find_element_by_id("seatType_1")
for i,item in enumerate(self.type):
print("【{}】{}".format(i,item))
num=input("请输入座位类型:")
code=self.type_code[int(num)]
print("=======余票查询=======")
count=1
flag=False
while 1:
print("第{}次查询".format(count))
count+=1
for i,item in enumerate(seatType.find_elements_by_tag_name("option")):
if item.get_attribute("value") is code:
flag=True
item.click()
break;
if flag:
break;
self.driver.back()
time.sleep(1)
self.driver.forward()
#================================================
ul=WebDriverWait(self.driver, 100).until(
EC.presence_of_element_located((By.ID, "normal_passenger_id"))
)
time.sleep(1.5)
lis=ul.find_elements_by_tag_name("li")
lis[buy_num].find_elements_by_tag_name('input')[0].click()
if self.is_student:
self.driver.find_element_by_id("dialog_xsertcj_ok").click()
else:
self.driver.find_element_by_id("dialog_xsertcj_cancel").click()
seatType=self.driver.find_element_by_id("seatType_1")
#================================================
self.driver.find_element_by_id("submitOrder_id").click()
if code is "M" or code is"0":
num=input("请输入座位编号:")
for i,item in enumerate(self.position):
print("【{}】{}".format(i,item))
num=input("请输入座位编号:")
id="1"+self.position[int(num)]
self.driver.find_element_by_id(id).click()
time.sleep(1)
isorder=input("已有余票,是否预订(【0】取消 【1】预定):")
if int(isorder):
self.driver.find_element_by_id("qr_submit_id").click()
print("预定成功,请及时付款")
else:
print("Bye~")
def __call__(self):
self.login()
time.sleep(2)
self.getVerifyImage()
time.sleep(1)
self.getVerifyResult()
time.sleep(1)
self.moveAndClick()
time.sleep(1)
self.submit()
time.sleep(10)
self.queryTicket()
time.sleep(2)
self.ticketOrder()
time.sleep(10000)
Demo()()
两点说明
1、代码中使用的code.json外部文件获取见https://blog.csdn.net/weixin_38283159/article/details/86490978
中的trainService.py 中crawlCodeMess方法
2、如果登录图片验证失败,在十秒内可以手动点击验证图让程序继续下去
写在最后
刚接触selenium,一边查一边写,应该有很多不规范和漏洞,欢迎指正
最后
以上就是粗犷飞机为你收集整理的python+selenium实现12306自动登录刷票抢票(自己做黄牛?!)的全部内容,希望文章能够帮你解决python+selenium实现12306自动登录刷票抢票(自己做黄牛?!)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复