mirror of https://github.com/testerSunshine/12306
parent
d0754e4fcd
commit
e538371e85
|
@ -72,6 +72,11 @@
|
||||||
- 开始抢票:`docker-compose up --build -d`
|
- 开始抢票:`docker-compose up --build -d`
|
||||||
- 停止抢票:`docker-compose down`
|
- 停止抢票:`docker-compose down`
|
||||||
- 查看抢票log: `docker logs --follow ticket`
|
- 查看抢票log: `docker logs --follow ticket`
|
||||||
|
- 关于滑块验证
|
||||||
|
- 下单模式3采用pyppeteer模拟鼠标操作下单,可以过放票时的滑块验证。但目前还不稳定,可能出现进入订单页面时仍需要登陆的情况,原因未知。
|
||||||
|
- 建议将headless设置为False,如果出现问题可以手动操作,特别是在进入订单页面显示需要登陆时,可以手动登陆。
|
||||||
|
- 该功能还在完善中,目前肯定有BUG,请不要过于依赖此功能
|
||||||
|
- **注意:pyppeteer 需要安装hromium (~100MB).脚本会在第一次运行时自动安装,你也可以在跑脚本之前执行pyppeteer-install进行安装**
|
||||||
|
|
||||||
#### 目录对应说明
|
#### 目录对应说明
|
||||||
- agency - cdn代理
|
- agency - cdn代理
|
||||||
|
|
|
@ -9,7 +9,7 @@ TICKET_TYPE = 1
|
||||||
|
|
||||||
# 出发日期(list) "2018-01-06", "2018-01-07"
|
# 出发日期(list) "2018-01-06", "2018-01-07"
|
||||||
STATION_DATES = [
|
STATION_DATES = [
|
||||||
"2020-01-18"
|
"2020-02-09"
|
||||||
]
|
]
|
||||||
|
|
||||||
# 填入需要购买的车次(list),"G1353"
|
# 填入需要购买的车次(list),"G1353"
|
||||||
|
@ -18,10 +18,10 @@ STATION_DATES = [
|
||||||
STATION_TRAINS = []
|
STATION_TRAINS = []
|
||||||
|
|
||||||
# 出发城市,比如深圳北,就填深圳就搜得到
|
# 出发城市,比如深圳北,就填深圳就搜得到
|
||||||
FROM_STATION = "广州南"
|
FROM_STATION = "海口"
|
||||||
|
|
||||||
# 到达城市 比如深圳北,就填深圳就搜得到
|
# 到达城市 比如深圳北,就填深圳就搜得到
|
||||||
TO_STATION = "隆回"
|
TO_STATION = "三亚"
|
||||||
|
|
||||||
# 座位(list) 多个座位ex:
|
# 座位(list) 多个座位ex:
|
||||||
# "商务座",
|
# "商务座",
|
||||||
|
@ -33,7 +33,7 @@ TO_STATION = "隆回"
|
||||||
# "硬座",
|
# "硬座",
|
||||||
# "无座",
|
# "无座",
|
||||||
# "动卧",
|
# "动卧",
|
||||||
SET_TYPE = ["二等座"]
|
SET_TYPE = ["二等座","软卧","硬卧"]
|
||||||
|
|
||||||
# 当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交
|
# 当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交
|
||||||
# bool
|
# bool
|
||||||
|
@ -56,7 +56,7 @@ IS_AUTO_CODE = True
|
||||||
|
|
||||||
# 设置2本地自动打码,需要配置tensorflow和keras库,3为云打码,由于云打码服务器资源有限(为2h4C的cpu服务器),请不要恶意请求,不然只能关闭服务器
|
# 设置2本地自动打码,需要配置tensorflow和keras库,3为云打码,由于云打码服务器资源有限(为2h4C的cpu服务器),请不要恶意请求,不然只能关闭服务器
|
||||||
# ps: 请不要一直依赖云服务器资源,在此向所有提供服务器同学表示感谢
|
# ps: 请不要一直依赖云服务器资源,在此向所有提供服务器同学表示感谢
|
||||||
AUTO_CODE_TYPE = 3
|
AUTO_CODE_TYPE = 2
|
||||||
|
|
||||||
# 此处设置云打码服务器地址,如果有自建的服务器,可以自行更改
|
# 此处设置云打码服务器地址,如果有自建的服务器,可以自行更改
|
||||||
HOST = "120.77.154.140:8000"
|
HOST = "120.77.154.140:8000"
|
||||||
|
@ -80,12 +80,12 @@ HTTP_TYPE = "http"
|
||||||
# password: "授权码"
|
# password: "授权码"
|
||||||
# host: "smtp.qq.com"
|
# host: "smtp.qq.com"
|
||||||
EMAIL_CONF = {
|
EMAIL_CONF = {
|
||||||
"IS_MAIL": True,
|
"IS_MAIL": False,
|
||||||
"email": "",
|
"email": "",
|
||||||
"notice_email_list": "",
|
"notice_email_list": "",
|
||||||
"username": "",
|
"username": "",
|
||||||
"password": "",
|
"password": "",
|
||||||
"host": "smtp.qq.com",
|
"host": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
# 是否开启 server酱 微信提醒, 使用前需要前往 http://sc.ftqq.com/3.version 扫码绑定获取 SECRET 并关注获得抢票结果通知的公众号
|
# 是否开启 server酱 微信提醒, 使用前需要前往 http://sc.ftqq.com/3.version 扫码绑定获取 SECRET 并关注获得抢票结果通知的公众号
|
||||||
|
@ -97,12 +97,17 @@ SERVER_CHAN_CONF = {
|
||||||
# 是否开启cdn查询,可以更快的检测票票 1为开启,2为关闭
|
# 是否开启cdn查询,可以更快的检测票票 1为开启,2为关闭
|
||||||
IS_CDN = 1
|
IS_CDN = 1
|
||||||
|
|
||||||
# 下单接口分为两种,1 模拟网页自动捡漏下单(不稳定),2 模拟车次后面的购票按钮下单(稳如老狗)
|
# 下单接口分为两种,1 模拟网页自动捡漏下单(不稳定),2 模拟车次后面的购票按钮下单(稳如老狗),3 pyppeteer模拟下单(可以模拟鼠标拖动滑块,但速度较慢,且不稳定)
|
||||||
ORDER_TYPE = 2
|
ORDER_TYPE = 3
|
||||||
|
|
||||||
|
# 如果采用pyppeteer下单,可以选择浏览器在前台显示(Flase) 或后台运行(True),前台运行的话,如果有啥BUG可以手动操作,后台显示尚未测试
|
||||||
|
IS_HEADLESS = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 下单模式 1 为预售,整点刷新,刷新间隔0.1-0.5S, 然后会校验时间,比如12点的预售,那脚本就会在12.00整检票,刷新订单
|
# 下单模式 1 为预售,整点刷新,刷新间隔0.1-0.5S, 然后会校验时间,比如12点的预售,那脚本就会在12.00整检票,刷新订单
|
||||||
# 2 是捡漏,捡漏的刷新间隔时间为0.5-3秒,时间间隔长,不容易封ip
|
# 2 是捡漏,捡漏的刷新间隔时间为0.5-3秒,时间间隔长,不容易封ip
|
||||||
ORDER_MODEL = 1
|
ORDER_MODEL = 2
|
||||||
|
|
||||||
# 是否开启代理, 0代表关闭, 1表示开始
|
# 是否开启代理, 0代表关闭, 1表示开始
|
||||||
# 开启此功能的时候请确保代理ip是否可用,在测试放里面经过充分的测试,再开启此功能,不然可能会耽误你购票的宝贵时间
|
# 开启此功能的时候请确保代理ip是否可用,在测试放里面经过充分的测试,再开启此功能,不然可能会耽误你购票的宝贵时间
|
||||||
|
@ -117,19 +122,17 @@ OPEN_TIME = "12:59:57"
|
||||||
# 1=使用selenium获取devicesID
|
# 1=使用selenium获取devicesID
|
||||||
# 2=使用网页端/otn/HttpZF/logdevice获取devicesId,这个接口的算法目前可能有点问题,如果登录一直302的请改为配置1
|
# 2=使用网页端/otn/HttpZF/logdevice获取devicesId,这个接口的算法目前可能有点问题,如果登录一直302的请改为配置1
|
||||||
# 3=自己打开浏览器在headers-Cookies中抓取RAIL_DEVICEID和RAIL_EXPIRATION,这个就不用配置selenium
|
# 3=自己打开浏览器在headers-Cookies中抓取RAIL_DEVICEID和RAIL_EXPIRATION,这个就不用配置selenium
|
||||||
COOKIE_TYPE = 3
|
COOKIE_TYPE = 1
|
||||||
# 如果COOKIE_TYPE=1,则需配置chromeDriver路径,下载地址http://chromedriver.storage.googleapis.com/index.html
|
# 如果COOKIE_TYPE=1,则需配置chromeDriver路径,下载地址http://chromedriver.storage.googleapis.com/index.html
|
||||||
# chromedriver配置版本只要和chrome的大版本匹配就行
|
# chromedriver配置版本只要和chrome的大版本匹配就行
|
||||||
CHROME_PATH = "/usr/src/app/chromedriver"
|
CHROME_PATH = "/home/homura/12306/12306dev/12306/chromedriver"
|
||||||
|
|
||||||
# 为了docker37 准备的环境变量,windows环境可以不用管这个参数
|
# 为了docker37 准备的环境变量,windows环境可以不用管这个参数
|
||||||
CHROME_CHROME_PATH = "/opt/google/chrome/google-chrome"
|
CHROME_CHROME_PATH = "/opt/google/chrome/google-chrome"
|
||||||
|
|
||||||
# 如果COOKIE_TYPE=3, 则需配置RAIL_EXPIRATION、RAIL_DEVICEID的值
|
# 如果COOKIE_TYPE=3, 则需配置RAIL_EXPIRATION、RAIL_DEVICEID的值
|
||||||
RAIL_EXPIRATION = ""
|
RAIL_EXPIRATION = "1577034103293"
|
||||||
RAIL_DEVICEID = ""
|
RAIL_DEVICEID = "CDno29Erc_Pf3FSXb4dzq-Op64EhWrsi5yUZKVIKR1MAfYo2qFlCeXD8VkexY7_1qg-ClV-fE8j9jgVlPZxRh3wVc2iqLe_5A8sdr62qZx4B22JPF8lFCjpgTKZ5ODW90HJd5tiQsJ1KR9nOqHRxHj1FT5LEIwfw"
|
||||||
# RAIL_EXPIRATION = "1577034103293"
|
|
||||||
# RAIL_DEVICEID = "CDno29Erc_Pf3FSXb4dzq-Op64EhWrsi5yUZKVIKR1MAfYo2qFlCeXD8VkexY7_1qg-ClV-fE8j9jgVlPZxRh3wVc2iqLe_5A8sdr62qZx4B22JPF8lFCjpgTKZ5ODW90HJd5tiQsJ1KR9nOqHRxHj1FT5LEIwfw"
|
|
||||||
|
|
||||||
|
|
||||||
# 1=>为一直随机ua,2->只启动的时候随机一次ua
|
# 1=>为一直随机ua,2->只启动的时候随机一次ua
|
||||||
|
@ -154,4 +157,4 @@ MAX_TIME = 3
|
||||||
MIN_TIME = 1
|
MIN_TIME = 1
|
||||||
|
|
||||||
# 软件版本
|
# 软件版本
|
||||||
RE_VERSION = "1.2.004"
|
RE_VERSION = "1.2.005"
|
||||||
|
|
Binary file not shown.
|
@ -429,6 +429,19 @@ urls = {
|
||||||
"is_cdn": True,
|
"is_cdn": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
|
"leftTicketPage":{ #车票查询页面
|
||||||
|
"req_url": "otn/leftTicket/init?linktypeid=dc&fs={0}&ts={1}&date={2}&flag=N,N,Y",
|
||||||
|
"req_type":"get",
|
||||||
|
"Referer":"",
|
||||||
|
"Content-Type": 1,
|
||||||
|
"Host": "kyfw.12306.cn",
|
||||||
|
"re_try": 10,
|
||||||
|
"re_time": 0.01,
|
||||||
|
"s_time": 0.1,
|
||||||
|
"is_logger": False,
|
||||||
|
"is_cdn": True,
|
||||||
|
"is_json": False
|
||||||
|
},
|
||||||
"Pushbear": { # push通知
|
"Pushbear": { # push通知
|
||||||
"req_url": "/sub",
|
"req_url": "/sub",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
|
|
|
@ -21,6 +21,7 @@ from inter.GetPassengerDTOs import getPassengerDTOs
|
||||||
from inter.LiftTicketInit import liftTicketInit
|
from inter.LiftTicketInit import liftTicketInit
|
||||||
from inter.Query import query
|
from inter.Query import query
|
||||||
from inter.SubmitOrderRequest import submitOrderRequest
|
from inter.SubmitOrderRequest import submitOrderRequest
|
||||||
|
from inter.SimulateOrderRequest import SimulateOrderRequest
|
||||||
from myException.PassengerUserException import PassengerUserException
|
from myException.PassengerUserException import PassengerUserException
|
||||||
from myException.UserPasswordException import UserPasswordException
|
from myException.UserPasswordException import UserPasswordException
|
||||||
from myException.ticketConfigException import ticketConfigException
|
from myException.ticketConfigException import ticketConfigException
|
||||||
|
@ -211,6 +212,26 @@ class select:
|
||||||
self.passengerTicketStrList, self.oldPassengerStr, train_date,
|
self.passengerTicketStrList, self.oldPassengerStr, train_date,
|
||||||
TickerConfig.TICKET_PEOPLES)
|
TickerConfig.TICKET_PEOPLES)
|
||||||
sor.sendSubmitOrderRequest()
|
sor.sendSubmitOrderRequest()
|
||||||
|
elif TickerConfig.ORDER_TYPE == 3: # selenium模拟下单
|
||||||
|
sele = SimulateOrderRequest(selectObj=self,
|
||||||
|
from_station=from_station,
|
||||||
|
to_station=to_station,
|
||||||
|
from_station_h=TickerConfig.FROM_STATION,
|
||||||
|
to_station_h=TickerConfig.TO_STATION,
|
||||||
|
_station_seat=self._station_seat,
|
||||||
|
station_trains=TickerConfig.STATION_TRAINS,
|
||||||
|
station_dates=TickerConfig.STATION_DATES,
|
||||||
|
ticke_peoples_num=len(TickerConfig.TICKET_PEOPLES),
|
||||||
|
train_no = train_no,
|
||||||
|
secretStr = secretStr,
|
||||||
|
set_type = self.set_type,
|
||||||
|
train_date=train_date,
|
||||||
|
passengerTicketStr=self.passengerTicketStrList,
|
||||||
|
oldPassengerStr=self.oldPassengerStr,
|
||||||
|
start_time = queryResult.get("start_time"),
|
||||||
|
)
|
||||||
|
sele.Do_simulate()
|
||||||
|
|
||||||
elif secretList: # 候补订单
|
elif secretList: # 候补订单
|
||||||
c = chechFace(self, secretList, train_no)
|
c = chechFace(self, secretList, train_no)
|
||||||
c.sendChechFace()
|
c.sendChechFace()
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from inter.GetQueueCount import getQueueCount
|
from inter.GetQueueCount import getQueueCount
|
||||||
from inter.GetRepeatSubmitToken import getRepeatSubmitToken
|
from inter.GetRepeatSubmitToken import getRepeatSubmitToken
|
||||||
|
import sys
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
|
||||||
class checkOrderInfo:
|
class checkOrderInfo:
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ class liftTicketInit:
|
||||||
# 获取初始化的结果
|
# 获取初始化的结果
|
||||||
result = self.session.httpClint.send(urls)
|
result = self.session.httpClint.send(urls)
|
||||||
# 用正则表达式查出CLeftTicketUrl的值
|
# 用正则表达式查出CLeftTicketUrl的值
|
||||||
|
#print(result)
|
||||||
matchObj = re.search('var CLeftTicketUrl = \'(.*)\'', result, re.M|re.I);
|
matchObj = re.search('var CLeftTicketUrl = \'(.*)\'', result, re.M|re.I);
|
||||||
if matchObj:
|
if matchObj:
|
||||||
# 如果有值,替换queryUrl
|
# 如果有值,替换queryUrl
|
||||||
|
|
|
@ -150,6 +150,7 @@ class query:
|
||||||
"is_more_ticket_num": is_more_ticket_num,
|
"is_more_ticket_num": is_more_ticket_num,
|
||||||
"cdn": self.httpClint.cdn,
|
"cdn": self.httpClint.cdn,
|
||||||
"status": True,
|
"status": True,
|
||||||
|
"start_time":start_time
|
||||||
}
|
}
|
||||||
elif is_ticket_pass == '无' and ticket_info[37] == "1" and TickerConfig.TICKET_TYPE is 2:
|
elif is_ticket_pass == '无' and ticket_info[37] == "1" and TickerConfig.TICKET_TYPE is 2:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -0,0 +1,214 @@
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import random
|
||||||
|
import wrapcache
|
||||||
|
from config import urlConf
|
||||||
|
from config.TicketEnmu import ticket
|
||||||
|
from config.emailConf import sendEmail
|
||||||
|
from config.serverchanConf import sendServerChan
|
||||||
|
from myUrllib.httpUtils import HTTPClient
|
||||||
|
from config.configCommon import seat_conf_2
|
||||||
|
import TickerConfig
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
import math
|
||||||
|
|
||||||
|
from myException.ReLoginException import ReLoginException
|
||||||
|
|
||||||
|
from myException.ticketIsExitsException import ticketIsExitsException
|
||||||
|
from myException.ticketNumOutException import ticketNumOutException
|
||||||
|
from selenium.common.exceptions import TimeoutException
|
||||||
|
import inter.easing
|
||||||
|
import asyncio
|
||||||
|
from pyppeteer import launch
|
||||||
|
import async_timeout
|
||||||
|
|
||||||
|
class SimulateOrderRequest:
|
||||||
|
def __init__(self,selectObj,from_station,to_station,from_station_h,to_station_h,_station_seat,station_trains, station_dates, ticke_peoples_num, train_no ,secretStr ,set_type ,train_date, passengerTicketStr, oldPassengerStr,start_time):
|
||||||
|
self.session = selectObj
|
||||||
|
self.urls = urlConf.urls
|
||||||
|
self.from_station = from_station
|
||||||
|
self.to_station = to_station
|
||||||
|
self.from_station_h = from_station_h
|
||||||
|
self.to_station_h = to_station_h
|
||||||
|
self.station_trains = station_trains
|
||||||
|
self._station_seat = _station_seat if isinstance(_station_seat, list) else list(_station_seat)
|
||||||
|
self.station_dates = station_dates if isinstance(station_dates, list) else list(station_dates)
|
||||||
|
self.ticket_black_list = dict()
|
||||||
|
self.ticke_peoples_num = ticke_peoples_num
|
||||||
|
self.train_date = train_date
|
||||||
|
self.secretStr = secretStr
|
||||||
|
self.train_no = train_no
|
||||||
|
self.start_time = start_time
|
||||||
|
self.passengerTicketStr= passengerTicketStr
|
||||||
|
self.oldPassengerStr= oldPassengerStr
|
||||||
|
|
||||||
|
self.set_type = set_type
|
||||||
|
|
||||||
|
|
||||||
|
async def mouse_slide(self,page=None):
|
||||||
|
await asyncio.sleep(0.3)
|
||||||
|
try :
|
||||||
|
#鼠标移动到滑块,按下,滑动到头(然后延时处理),松开按键
|
||||||
|
await self.page.hover('#nc_1_n1z')
|
||||||
|
await self.page.mouse.down()
|
||||||
|
await self.page.mouse.move(2000, 0, {'delay': random.randint(1000, 2000)})
|
||||||
|
await self.page.mouse.up()
|
||||||
|
except Exception as e:
|
||||||
|
print(e, ':验证失败')
|
||||||
|
return False,self.page
|
||||||
|
return True,self.page
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_order_information(self):
|
||||||
|
passengers = []
|
||||||
|
passengerStrList = self.passengerTicketStr.split('_')
|
||||||
|
for eachPassenger in passengerStrList:
|
||||||
|
passengerInfo = eachPassenger.split(',')
|
||||||
|
if (len(passengerInfo) == 9):
|
||||||
|
passengers.append({'type':passengerInfo[0],'name':passengerInfo[3]})
|
||||||
|
return passengers
|
||||||
|
|
||||||
|
async def fill_the_page(self):
|
||||||
|
TIME_OUT_L = 20
|
||||||
|
if TickerConfig.IS_HEADLESS:
|
||||||
|
TIME_OUT_L = 3
|
||||||
|
try:
|
||||||
|
async with async_timeout.timeout(TIME_OUT_L) as cm:
|
||||||
|
while not await self.page.querySelector('#normalPassenger_0'):
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
if cm.expired: #超时,没能进入订单页,可能是session失效
|
||||||
|
print("超时未能进入订单页面,重试")
|
||||||
|
raise ReLoginException("Need Login")
|
||||||
|
passengers = self.get_order_information()
|
||||||
|
passenger_num = 1
|
||||||
|
for eachPassenger in passengers:
|
||||||
|
xpath = "//label[text() = '{0}']".format(eachPassenger['name'])
|
||||||
|
while not await self.page.querySelector('#normalPassenger_0'):
|
||||||
|
pass
|
||||||
|
a = await self.page.xpath(xpath)
|
||||||
|
await a[-1].click()
|
||||||
|
await self.page.select('select#seatType_'+str(passenger_num),eachPassenger['type'])
|
||||||
|
passenger_num += 1
|
||||||
|
button = await self.page.J("#submitOrder_id")
|
||||||
|
if button:
|
||||||
|
print("不需要滑块验证,尝试提交中")
|
||||||
|
await button.click()
|
||||||
|
#await asyncio.sleep(0.2)
|
||||||
|
|
||||||
|
await self.page.waitForSelector('#qr_submit_id', {'visible':True,})
|
||||||
|
qr_btn = await self.page.J("#qr_submit_id")
|
||||||
|
#asyncio.sleep(120)
|
||||||
|
await qr_btn.click()
|
||||||
|
asyncio.sleep(30)
|
||||||
|
sendEmail(ticket.WAIT_ORDER_SUCCESS.format("1"))
|
||||||
|
sendServerChan(ticket.WAIT_ORDER_SUCCESS.format("1"))
|
||||||
|
raise ticketIsExitsException(ticket.WAIT_ORDER_SUCCESS.format("1"))
|
||||||
|
else:
|
||||||
|
slide = await self.page.J("#nc_1_n1z")
|
||||||
|
if slide:
|
||||||
|
print("需要滑块验证,尝试提交中")
|
||||||
|
flag = False
|
||||||
|
for i in range(3):
|
||||||
|
flag,self.page = await self.mouse_slide(page=self.page) #js拉动滑块过去。
|
||||||
|
if flag:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
await self.page.waitForSelector('#qr_submit_id', {'visible':True,})
|
||||||
|
qr_btn = await self.page.J("#qr_submit_id")
|
||||||
|
await qr_btn.click()
|
||||||
|
asyncio.sleep(30)
|
||||||
|
sendEmail(ticket.WAIT_ORDER_SUCCESS.format("1"))
|
||||||
|
sendServerChan(ticket.WAIT_ORDER_SUCCESS.format("1"))
|
||||||
|
raise ticketIsExitsException(ticket.WAIT_ORDER_SUCCESS.format("1"))
|
||||||
|
else:
|
||||||
|
print("失败:未知原因")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
async def py_delete_all_cookies(self):
|
||||||
|
tcookies = await self.page.cookies()
|
||||||
|
for a in tcookies:
|
||||||
|
await self.page.deleteCookie(a)
|
||||||
|
|
||||||
|
async def py_set_all_cookies(self):
|
||||||
|
c = self.session.httpClint.get_cookie_all_items()
|
||||||
|
#print(c)
|
||||||
|
for x in c:
|
||||||
|
if x[0] == 'RAIL_DEVICEID' or x[0] == 'RAIL_EXPIRATION':
|
||||||
|
await self.page.setCookie({'name':x[0],'value':x[1],'domain':'.12306.cn','path':'/'})
|
||||||
|
elif x[0] == 'JSESSIONID':
|
||||||
|
await self.page.setCookie({'name':x[0],'value':x[1],'path':'/otn','domain': 'kyfw.12306.cn'})
|
||||||
|
else:
|
||||||
|
await self.page.setCookie({'name':x[0],'value':x[1],'domain': 'kyfw.12306.cn'})
|
||||||
|
#print(await self.page.cookies())
|
||||||
|
|
||||||
|
async def I_AM_NOT_A_ROBOT(self):
|
||||||
|
await self.page.evaluate('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''') #以下为插入中间js,将淘宝会为了检测浏览器而调用的js修改其结果。
|
||||||
|
await self.page.evaluate('''() =>{ window.navigator.chrome = { runtime: {}, }; }''')
|
||||||
|
await self.page.evaluate('''() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }''')
|
||||||
|
await self.page.evaluate('''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')
|
||||||
|
|
||||||
|
await self.page.evaluateOnNewDocument('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''') #以下为插入中间js,将淘宝会为了检测浏览器而调用的js修改其结果。
|
||||||
|
await self.page.evaluateOnNewDocument('''() =>{ window.navigator.chrome = { runtime: {}, }; }''')
|
||||||
|
await self.page.evaluateOnNewDocument('''() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }''')
|
||||||
|
await self.page.evaluateOnNewDocument('''() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')
|
||||||
|
|
||||||
|
async def start_simulate(self):
|
||||||
|
self.driver = await launch({'headless':TickerConfig.IS_HEADLESS ,'args': ['--no-sandbox'], })
|
||||||
|
self.page = await self.driver.newPage()
|
||||||
|
select_url = copy.copy(self.urls["leftTicketPage"])
|
||||||
|
req_url = "https://"+select_url['Host'] +'/'+ select_url['req_url'].format(self.from_station_h+','+self.from_station,self.to_station_h+','+self.to_station,self.train_date)
|
||||||
|
await self.page.setUserAgent('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36')
|
||||||
|
|
||||||
|
await self.page.goto(req_url)
|
||||||
|
await self.I_AM_NOT_A_ROBOT()
|
||||||
|
while not await self.page.querySelector('#query_ticket'):
|
||||||
|
pass
|
||||||
|
await self.py_delete_all_cookies()
|
||||||
|
try:
|
||||||
|
while await self.page.cookies():
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
await self.py_set_all_cookies()
|
||||||
|
try:
|
||||||
|
while not await self.page.cookies():
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
await self.page.goto(req_url)
|
||||||
|
js = "checkG1234(\'"+self.secretStr+"\',\'"+self.start_time+"\',\'"+self.train_no+"\',\'"+self.from_station+"\',\'"+self.to_station+"\')"
|
||||||
|
await self.page.evaluate(js)
|
||||||
|
try:
|
||||||
|
await self.fill_the_page()
|
||||||
|
except ReLoginException:
|
||||||
|
print("重新登陆中")
|
||||||
|
self.session.call_login()
|
||||||
|
await self.page.goto(req_url)
|
||||||
|
while not await self.page.querySelector('#query_ticket'):
|
||||||
|
pass
|
||||||
|
await self.py_delete_all_cookies()
|
||||||
|
while await self.page.cookies():
|
||||||
|
pass
|
||||||
|
await self.py_set_all_cookies()
|
||||||
|
while not await self.page.cookies():
|
||||||
|
pass
|
||||||
|
await self.page.goto(req_url)
|
||||||
|
await self.page.evaluate(js)
|
||||||
|
try:
|
||||||
|
await self.fill_the_page()
|
||||||
|
except ReLoginException:
|
||||||
|
print("失败,重新查询")
|
||||||
|
return
|
||||||
|
|
||||||
|
def Do_simulate(self):
|
||||||
|
asyncio.get_event_loop().run_until_complete(self.start_simulate())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ from inter.ConfirmHB import confirmHB
|
||||||
from inter.PassengerInitApi import passengerInitApi
|
from inter.PassengerInitApi import passengerInitApi
|
||||||
from myException.ticketIsExitsException import ticketIsExitsException
|
from myException.ticketIsExitsException import ticketIsExitsException
|
||||||
|
|
||||||
|
|
||||||
def time():
|
def time():
|
||||||
"""
|
"""
|
||||||
获取日期
|
获取日期
|
||||||
|
@ -74,7 +73,7 @@ class submitOrderRequest:
|
||||||
print (u'出票失败')
|
print (u'出票失败')
|
||||||
elif 'messages' in submitResult and submitResult['messages']:
|
elif 'messages' in submitResult and submitResult['messages']:
|
||||||
raise ticketIsExitsException(submitResult['messages'][0])
|
raise ticketIsExitsException(submitResult['messages'][0])
|
||||||
|
|
||||||
|
|
||||||
class submitOrderRequestByAfterNate:
|
class submitOrderRequestByAfterNate:
|
||||||
def __init__(self, session, secretList, tickerNo):
|
def __init__(self, session, secretList, tickerNo):
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created by aneasystone on 2018/3/14
|
||||||
|
import numpy as np
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
# https://github.com/gdsmith/jquery.easing/blob/master/jquery.easing.js
|
||||||
|
def ease_in_quad(x):
|
||||||
|
return x * x
|
||||||
|
|
||||||
|
|
||||||
|
def ease_out_quad(x):
|
||||||
|
return 1 - (1 - x) * (1 - x)
|
||||||
|
|
||||||
|
|
||||||
|
def ease_out_quart(x):
|
||||||
|
return 1 - pow(1 - x, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def ease_out_expo(x):
|
||||||
|
if x == 1:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 1 - pow(2, -10 * x)
|
||||||
|
|
||||||
|
|
||||||
|
def ease_out_bounce(x):
|
||||||
|
n1 = 7.5625
|
||||||
|
d1 = 2.75
|
||||||
|
if x < 1 / d1 :
|
||||||
|
return n1 * x * x
|
||||||
|
elif x < 2 / d1:
|
||||||
|
x -= 1.5 / d1
|
||||||
|
return n1 * x*x + 0.75
|
||||||
|
elif x < 2.5 / d1:
|
||||||
|
x -= 2.25 / d1
|
||||||
|
return n1 * x*x + 0.9375
|
||||||
|
else:
|
||||||
|
x -= 2.625 / d1
|
||||||
|
return n1 * x*x + 0.984375
|
||||||
|
|
||||||
|
|
||||||
|
def ease_out_elastic(x):
|
||||||
|
if x == 0:
|
||||||
|
return 0
|
||||||
|
elif x == 1:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
c4 = (2 * math.pi) / 3
|
||||||
|
return pow(2, -10 * x) * math.sin((x * 10 - 0.75) * c4) + 1
|
||||||
|
|
||||||
|
|
||||||
|
def get_tracks(distance, seconds, ease_func):
|
||||||
|
tracks = [0]
|
||||||
|
offsets = [0]
|
||||||
|
for t in np.arange(0.0, seconds, 0.1):
|
||||||
|
ease = globals()[ease_func]
|
||||||
|
offset = round(ease(t/seconds) * distance)
|
||||||
|
tracks.append(offset - offsets[-1])
|
||||||
|
offsets.append(offset)
|
||||||
|
return offsets, tracks
|
|
@ -0,0 +1,2 @@
|
||||||
|
class ReLoginException(Exception):
|
||||||
|
pass
|
|
@ -73,6 +73,9 @@ class HTTPClient(object):
|
||||||
"""
|
"""
|
||||||
return self._s.cookies.values()
|
return self._s.cookies.values()
|
||||||
|
|
||||||
|
def get_cookie_all_items(self):
|
||||||
|
return self._s.cookies.items()
|
||||||
|
|
||||||
def del_cookies(self):
|
def del_cookies(self):
|
||||||
"""
|
"""
|
||||||
删除所有的key
|
删除所有的key
|
||||||
|
|
|
@ -12,4 +12,6 @@ matplotlib>=3.0.2
|
||||||
numpy>=1.14.6
|
numpy>=1.14.6
|
||||||
scipy>=1.1.0
|
scipy>=1.1.0
|
||||||
selenium==3.11.0
|
selenium==3.11.0
|
||||||
fake-useragent==0.1.11
|
fake-useragent==0.1.11
|
||||||
|
pyppeteer
|
||||||
|
async-timeout
|
BIN
tkcode.png
BIN
tkcode.png
Binary file not shown.
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
Loading…
Reference in New Issue