Merge pull request 'able' (#4) from liuchengxin_branch into develop
	
		
	
				
					
				
			
						commit
						a6b43bc244
					
				| @ -1 +0,0 @@ | ||||
| Subproject commit a495af88346a0d794493c6030f6a6207debb5824 | ||||
| @ -0,0 +1,15 @@ | ||||
| **/*.html | ||||
| **/*.pyc | ||||
| **/*.yaml | ||||
| **/*.log | ||||
| **/*~ | ||||
| **/.DS_Store | ||||
| **/Thumbs.db | ||||
| *.png | ||||
| .idea/ | ||||
| .git/ | ||||
| .github/ | ||||
| *.md | ||||
| UnitTest/ | ||||
| uml/ | ||||
| *.h5 | ||||
| @ -0,0 +1,6 @@ | ||||
| *.html | ||||
| *.pyc | ||||
| *.yaml | ||||
| *.log | ||||
| .idea/ | ||||
| tkcode.png | ||||
											
												Binary file not shown.
											
										
									
								| @ -0,0 +1,24 @@ | ||||
| FROM python:2.7.15 | ||||
| WORKDIR /usr/src/app | ||||
| ADD . /usr/src/app | ||||
| 
 | ||||
| ENV DEBIAN_FRONTEND noninteractive | ||||
| ENV TZ Asia/Shanghai | ||||
| 
 | ||||
| 
 | ||||
| ## install python requirements  | ||||
| RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspider --no-cache-dir -r requirements.txt | ||||
| RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone  | ||||
| 
 | ||||
| ## install ntpdate, not accept but saving code | ||||
| #RUN echo 'deb http://mirrors.163.com/debian/ jessie main non-free contrib \ | ||||
| #	deb http://mirrors.163.com/debian/ jessie-updates main non-free contrib \ | ||||
| #	deb http://mirrors.163.com/debian-security/ jessie/updates main non-free contrib' > /etc/apt/sources.list \ | ||||
| #	&& apt-get update\ | ||||
| #	&& apt-get install ntpdate -y \ | ||||
| 
 | ||||
| 
 | ||||
| #EXPOSE 5010 | ||||
| 
 | ||||
| CMD [ "python", "run.py" ] | ||||
| #ENTRYPOINT [ "python", "run.py" ] | ||||
| @ -0,0 +1,51 @@ | ||||
| FROM python:3.7-slim-buster | ||||
| 
 | ||||
| ARG CDV=77.0.3865.40 | ||||
| 
 | ||||
| RUN sed -i 's/deb.debian.org/ftp.cn.debian.org/g' /etc/apt/sources.list | ||||
| 
 | ||||
| RUN apt-get -y update && apt-get install -y \ | ||||
|     fonts-liberation \ | ||||
|     libappindicator3-1 \ | ||||
|     libasound2 \ | ||||
|     libatk-bridge2.0-0 \ | ||||
|     libatk1.0-0 \ | ||||
|     libatspi2.0-0 \ | ||||
|     libcups2 \ | ||||
|     libdbus-1-3 \ | ||||
|     libgtk-3-0 \ | ||||
|     libnspr4 \ | ||||
|     libnss3 \ | ||||
|     libx11-xcb1 \ | ||||
|     libxcomposite1 \ | ||||
|     libxcursor1 \ | ||||
|     libxdamage1 \ | ||||
|     libxfixes3 \ | ||||
|     libxi6 \ | ||||
|     libxrandr2 \ | ||||
|     libxss1 \ | ||||
|     libxtst6 \ | ||||
|     lsb-release \ | ||||
|     unzip \ | ||||
|     wget \ | ||||
|     xdg-utils \ | ||||
|  && apt-get clean && rm -rf /var/lib/apt/lists/* | ||||
| 
 | ||||
| ENV TZ Asia/Shanghai | ||||
| RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone | ||||
| 
 | ||||
| WORKDIR /usr/src/app | ||||
| 
 | ||||
| RUN wget -q https://dl.lancdn.com/landian/soft/chrome/m/77.0.3865.120_amd64.deb && \ | ||||
|     dpkg -i 77.0.3865.120_amd64.deb && rm -f 77.0.3865.120_amd64.deb | ||||
| 
 | ||||
| RUN wget -q  https://npm.taobao.org/mirrors/chromedriver/$CDV/chromedriver_linux64.zip && \ | ||||
|     unzip chromedriver_linux64.zip && rm -f chromedriver_linux64.zip | ||||
| 
 | ||||
| ## install python requirements | ||||
| COPY requirements-docker37.txt ./ | ||||
| RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir -r requirements-docker37.txt | ||||
| 
 | ||||
| COPY . . | ||||
| 
 | ||||
| CMD [ "sh", "-c", "python run.py c && python run.py r" ] | ||||
| @ -0,0 +1,21 @@ | ||||
| MIT License | ||||
| 
 | ||||
| Copyright (c) 2017 | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
											
												
													File diff suppressed because one or more lines are too long
												
											
										
									
								| @ -0,0 +1 @@ | ||||
| 119.101.114.196:9999 | ||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -0,0 +1,61 @@ | ||||
| #coding: utf-8 | ||||
| 
 | ||||
| import os | ||||
| import time | ||||
| import logging | ||||
| 
 | ||||
| from config import configCommon | ||||
| 
 | ||||
| logger = None | ||||
| loggerHandler = None | ||||
| dateStr = '' #默认拥有日期后缀 | ||||
| suffix = '' #除了日期外的后缀 | ||||
| 
 | ||||
| def setSuffix(s): | ||||
| 	global suffix | ||||
| 	suffix = s | ||||
| 
 | ||||
| def getTodayDateStr(): | ||||
| 	return time.strftime("%Y-%m-%d", time.localtime(configCommon.getNowTimestamp())) | ||||
| 
 | ||||
| def setDateStr(s): | ||||
| 	global dateStr | ||||
| 	dateStr = s | ||||
| 
 | ||||
| def isAnotherDay(s): | ||||
| 	global dateStr | ||||
| 	return dateStr != s | ||||
| 
 | ||||
| def getLogFile(): | ||||
| 	global dateStr, suffix | ||||
| 	rtn = os.path.join(configCommon.getLogDir(), dateStr) | ||||
| 	if suffix: | ||||
| 		rtn += "_" + suffix | ||||
| 	return rtn + ".log" | ||||
| 
 | ||||
| def log(msg, func = "info"): | ||||
| 	global logger | ||||
| 	if not logger: | ||||
| 		logger = logging.getLogger() | ||||
| 		logger.setLevel(logging.INFO) | ||||
| 
 | ||||
| 	todayStr = getTodayDateStr() | ||||
| 	if isAnotherDay(todayStr): | ||||
| 		setDateStr(todayStr) | ||||
| 		logger.removeHandler(loggerHandler) | ||||
| 		 | ||||
| 		fh = logging.FileHandler(getLogFile()) | ||||
| 		fm = logging.Formatter(u'[%(asctime)s][%(levelname)8s] --- %(message)s (%(filename)s:%(lineno)s)') | ||||
| 		fh.setFormatter(fm) | ||||
| 
 | ||||
| 		logger.addHandler(fh) | ||||
| 
 | ||||
| 	levels = { | ||||
| 		"debug": logger.debug, | ||||
| 		"info": logger.info, | ||||
| 		"warning": logger.warning, | ||||
| 		"error": logger.error, | ||||
| 		"critical": logger.critical | ||||
| 	} | ||||
| 
 | ||||
| 	levels[func](msg) | ||||
| @ -0,0 +1,36 @@ | ||||
| # -*- coding: utf8 -*- | ||||
| import TickerConfig | ||||
| from config.urlConf import urls | ||||
| from myUrllib.httpUtils import HTTPClient | ||||
| 
 | ||||
| PUSH_BEAR_API_PATH = "https://pushbear.ftqq.com/sub" | ||||
| 
 | ||||
| 
 | ||||
| def sendPushBear(msg): | ||||
|     """ | ||||
|     pushBear微信通知 | ||||
|     :param str: 通知内容 content | ||||
|     :return: | ||||
|     """ | ||||
|     if TickerConfig.PUSHBEAR_CONF["is_pushbear"] and TickerConfig.PUSHBEAR_CONF["send_key"].strip() != "": | ||||
|         try: | ||||
|             sendPushBearUrls = urls.get("Pushbear") | ||||
|             data = { | ||||
|                 "sendkey": TickerConfig.PUSHBEAR_CONF["send_key"].strip(), | ||||
|                 "text": "易行购票成功通知", | ||||
|                 "desp": msg | ||||
|             } | ||||
|             httpClint = HTTPClient(0) | ||||
|             sendPushBeaRsp = httpClint.send(sendPushBearUrls, data=data) | ||||
|             if sendPushBeaRsp.get("code") is 0: | ||||
|                 print(u"已下发 pushbear 微信通知, 请查收") | ||||
|             else: | ||||
|                 print(sendPushBeaRsp) | ||||
|         except Exception as e: | ||||
|             print(u"pushbear 配置有误 {}".format(e)) | ||||
|     else: | ||||
|         pass | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     sendPushBear(1) | ||||
| @ -0,0 +1,36 @@ | ||||
| # -*- coding: utf8 -*- | ||||
| import TickerConfig | ||||
| from config.urlConf import urls | ||||
| from myUrllib.httpUtils import HTTPClient | ||||
| 
 | ||||
| PUSH_SERVER_CHAN_PATH = "https://sc.ftqq.com" | ||||
| 
 | ||||
| 
 | ||||
| def sendServerChan(msg): | ||||
|     """ | ||||
|     pushBear微信通知 | ||||
|     :param str: 通知内容 content | ||||
|     :return: | ||||
|     """ | ||||
|     if ( | ||||
|         TickerConfig.SERVER_CHAN_CONF["is_server_chan"] | ||||
|         and TickerConfig.SERVER_CHAN_CONF["secret"].strip() != "" | ||||
|     ): | ||||
|         try: | ||||
|             secret = TickerConfig.SERVER_CHAN_CONF["secret"].strip() | ||||
|             sendServerChanUrls = urls.get("ServerChan") | ||||
|             sendServerChanUrls["req_url"] += f'{secret}.send' | ||||
| 
 | ||||
|             params = {"text": "易行购票成功通知", "desp": msg} | ||||
|             httpClint = HTTPClient(0) | ||||
|             sendServerChanRsp = httpClint.send(sendServerChanUrls, params=params) | ||||
|             if sendServerChanRsp.get("errno") == 0: | ||||
|                 print(u"已下发 Server酱 微信通知, 请查收") | ||||
|             else: | ||||
|                 print(sendServerChanRsp) | ||||
|         except Exception as e: | ||||
|             print(u"Server酱 配置有误 {}".format(e)) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     sendServerChan(1) | ||||
| @ -0,0 +1,582 @@ | ||||
| # coding=utf-8 | ||||
| import random | ||||
| import TickerConfig | ||||
| import time | ||||
| 
 | ||||
| urls = { | ||||
|     "auth": {  # 登录接口 | ||||
|         "req_url": "/passport/web/auth/uamtk", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|         "is_cdn": True, | ||||
|     }, | ||||
|     "uamtk-static": {  # 登录接口 | ||||
|         "req_url": "/passport/web/auth/uamtk-static", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 3, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|         "is_cdn": True, | ||||
|     }, | ||||
|     "login": {   # 登录接口 | ||||
|         "req_url": "/passport/web/login", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.5, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
| 
 | ||||
|     }, | ||||
|     "left_ticket_init": {   # 登录接口 | ||||
|         "req_url": "/otn/leftTicket/init", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
| 
 | ||||
|     }, | ||||
|     "getCodeImg": {  # 登录验证码 | ||||
|         "req_url": "/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{0}", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_json": False, | ||||
|         "is_cdn": True, | ||||
|         "not_decode": True, | ||||
|     }, | ||||
|     "getCodeImg1": {  # 登录验证码 | ||||
|         "req_url": "/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&{0}&callback=jQuery19108016482864806321_1554298927290&_=1554298927293", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "codeCheck": {  # 验证码校验 | ||||
|         "req_url": "/passport/captcha/captcha-check", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "codeCheck1": {  # 验证码校验 | ||||
|         "req_url": "/passport/captcha/captcha-check?callback=jQuery19108016482864806321_1554298927290&answer={0}&rand=sjrand&login_site=E&_={1}", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/resources/login.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "loginInit": {  # 登录页面 | ||||
|         "req_url": "/otn/login/init", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/index/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 1, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "loginInitCdn": {  # 登录页面 | ||||
|         "req_url": "/otn/login/init", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/index/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 1, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_test_cdn": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "loginInitCdn1": {  # 登录页面 | ||||
|         "req_url": "/otn/resources/login.html", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/view/index.html", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 1, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_test_cdn": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "getDevicesId": {  # 获取用户信息 | ||||
|         "req_url": "/otn/HttpZF/logdevice", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "getUserInfo": {  # 获取用户信息 | ||||
|         "req_url": "/otn/index/initMy12306", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": False, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "userLogin": {  # 用户登录 | ||||
|         "req_url": "/otn/login/userLogin", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "uamauthclient": {  # 登录 | ||||
|         "req_url": "/otn/uamauthclient", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 1, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "initdc_url": {  # 生成订单页面 | ||||
|         "req_url": "/otn/confirmPassenger/initDc", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.1, | ||||
|         "s_time": 1, | ||||
|         "is_logger": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "GetJS": {   # 订单页面js | ||||
|         "req_url": "/otn/HttpZF/GetJS", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "odxmfwg": {  # 订单页面js | ||||
|         "req_url": "/otn/dynamicJs/odxmfwg", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.1, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "get_passengerDTOs": {  # 获取乘车人 | ||||
|         "req_url": "/otn/confirmPassenger/getPassengerDTOs", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.1, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "select_url": {  # 查询余票 | ||||
|         "req_url": "/otn/{3}?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 1, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.01, | ||||
|         "is_logger": False, | ||||
|         "is_json": True, | ||||
|         "is_cdn": True, | ||||
|     }, | ||||
|     "check_user_url": {  # 检查用户登录 | ||||
|         "req_url": "/otn/login/checkUser", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 1, | ||||
|         "re_time": 1, | ||||
|         "s_time": 1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "submit_station_url": {  # 提交订单 | ||||
|         "req_url": "/otn/leftTicket/submitOrderRequest", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "checkOrderInfoUrl": {  # 检查订单信息规范 | ||||
|         "req_url": "/otn/confirmPassenger/checkOrderInfo", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "getQueueCountUrl": {  # 剩余余票数 | ||||
|         "req_url": "/otn/confirmPassenger/getQueueCount", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "checkQueueOrderUrl": {  # 订单队列排队 | ||||
|         "req_url": "/otn/confirmPassenger/confirmSingleForQueue", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "checkRandCodeAnsyn": {  # 暂时没用到 | ||||
|         "req_url": "/otn/passcodeNew/checkRandCodeAnsyn", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "codeImgByOrder": {  # 订单页面验证码 | ||||
|         "req_url": "/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&{}", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "queryOrderWaitTimeUrl": {  # 订单等待页面 | ||||
|         "req_url": "/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "queryMyOrderNoCompleteUrl": {  # 订单查询页面 | ||||
|         "req_url": "/otn/queryOrder/queryMyOrderNoComplete", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "initNoCompleteUrl": {  # 获取订单列表 | ||||
|         "req_url": "/otn/queryOrder/initNoComplete", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_cdn": True, | ||||
|         "is_json": False, | ||||
|     }, | ||||
|     "cancelNoCompleteMyOrder": {  # 取消订单 | ||||
|         "req_url": "/otn/queryOrder/cancelNoCompleteMyOrder", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "autoSubmitOrderRequest": {  # 快速自动提交订单 | ||||
|         "req_url": "/otn/confirmPassenger/autoSubmitOrderRequest", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "getQueueCountAsync": {  # 快速获取订单数据 | ||||
|         "req_url": "/otn/confirmPassenger/getQueueCountAsync", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "Content-Type": 1, | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "confirmSingleForQueueAsys": {  # 快速订单排队 | ||||
|         "req_url": "/otn/confirmPassenger/confirmSingleForQueueAsys", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Content-Type": 1, | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_cdn": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "Pushbear": {  # push通知 | ||||
|         "req_url": "/sub", | ||||
|         "req_type": "post", | ||||
|         "Referer": "", | ||||
|         "Content-Type": 1, | ||||
|         "Host": "pushbear.ftqq.com", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": False, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "ServerChan": {  # Server酱 push通知 | ||||
|         "req_url": "/", | ||||
|         "req_type": "get", | ||||
|         "Referer": "", | ||||
|         "Content-Type": 1, | ||||
|         "Host": "sc.ftqq.com", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "loginHtml": {  # 登录接口2 | ||||
|         "req_url": "/otn/resources/login.html", | ||||
|         "req_type": "get", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.3, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "loginConf": {  # 登录接口2 | ||||
|         "req_url": "/otn/login/conf", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.3, | ||||
|         "s_time": 0.1, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "loginAysnSuggest": {  # 登录接口2 | ||||
|         "req_url": "/otn/login/loginAysnSuggest", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.3, | ||||
|         "is_cdn": True, | ||||
|         "s_time": 0.1, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     # 候补订单接口 | ||||
| 
 | ||||
|     "chechFace": {  # 人脸识别 | ||||
|         "req_url": "/otn/afterNate/chechFace", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "getSuccessRate": {  # 成功信息 | ||||
|         "req_url": "/otn/afterNate/getSuccessRate", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "SubmitOrderRequestRsp": {  # 提交候补订单准备 | ||||
|         "req_url": "/otn/afterNate/submitOrderRequest", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "confirmHB": {  # 设置订单信息 | ||||
|         "req_url": "/otn/afterNate/confirmHB", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "queryQueue": {  # 排队 | ||||
|         "req_url": "/otn/afterNate/queryQueue", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
|     "passengerInitApi": {  # 排队 | ||||
|         "req_url": "/otn/afterNate/passengerInitApi", | ||||
|         "req_type": "post", | ||||
|         "Referer": "https://kyfw.12306.cn/otn/leftTicket/init", | ||||
|         "Host": "kyfw.12306.cn", | ||||
|         "re_try": 10, | ||||
|         "re_time": 0.01, | ||||
|         "s_time": 0.01, | ||||
|         "is_cdn": True, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|     }, | ||||
| 
 | ||||
|     "autoVerifyImage": {  # 云打码接口 | ||||
|         "req_url": TickerConfig.REQ_URL, | ||||
|         "req_type": "post", | ||||
|         "Referer": "", | ||||
|         "Host": TickerConfig.HOST, | ||||
|         "re_try": 6, | ||||
|         "re_time": 10, | ||||
|         "s_time": 0.001, | ||||
|         "is_logger": True, | ||||
|         "is_json": True, | ||||
|         "httpType": TickerConfig.HTTP_TYPE | ||||
|     }, | ||||
| } | ||||
| @ -0,0 +1,32 @@ | ||||
| version: "3" | ||||
| 
 | ||||
| services: | ||||
|     #抢票服务 | ||||
|     ticket: | ||||
|         build: | ||||
|             context: . | ||||
|             dockerfile: ./Dockerfile37 | ||||
|         image: ticket:v1.2.004 | ||||
|         environment: | ||||
|             - PYTHONUNBUFFERED=1 | ||||
|             - CAPTCHALOCAL=1 | ||||
|         container_name: ticket | ||||
|         depends_on: | ||||
|             - captcha | ||||
|         networks: | ||||
|             - 12306network | ||||
|         restart: on-failure | ||||
|     #打码服务器 | ||||
|     captcha: | ||||
|         image: yinaoxiong/12306_code_server:amd64 #请根据需要修改image | ||||
|         environment: | ||||
|             - WORKERS=1 #gunicorn works 默认为1可以根据服务器配置自行调整 | ||||
|             - PYTHONUNBUFFERED=1 | ||||
|         container_name: captcha | ||||
|         networks: | ||||
|             - 12306network | ||||
|         restart: unless-stopped | ||||
| networks: | ||||
|     12306network: | ||||
|         driver: bridge | ||||
| 
 | ||||
| @ -0,0 +1,45 @@ | ||||
| #!/bin/bash | ||||
| #author: MonsterTan | ||||
| #date: 2019-01-15 | ||||
| #this is a script that can install automatically docker software by centos7 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function checkSudo (){ | ||||
|         if [ $UID -ne 0 ];then | ||||
|                 echo -e 'it must be root!' | ||||
|                 exit 1 | ||||
|         fi | ||||
| } | ||||
| 
 | ||||
| checkSudo | ||||
| 
 | ||||
| ## something required system utils | ||||
| yum install -y yum-utils device-mapper-persistent-data lvm2 | ||||
| 
 | ||||
| 
 | ||||
| ## add repo source info | ||||
| sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo | ||||
| 
 | ||||
| 
 | ||||
| sudo yum mackecache fast  | ||||
| sudo yum -y install docker-ce | ||||
| sudo systemctl start docker | ||||
| 
 | ||||
| 
 | ||||
| str=successed! | ||||
| if [ $? -eq 0 ];then | ||||
| 	echo -e "\033[32msuccessed!\033[0m" | ||||
| else | ||||
| 	echo -e "\033[31msomething wrong, please check!\033[0m" | ||||
| fi | ||||
| 
 | ||||
| echo  -e "\033[31mstart to install docker-compose\033[0m" | ||||
| 
 | ||||
| result=`ls /usr/bin/ | grep ^pip$` | ||||
| if [ ${#result} -eq 0 ];then | ||||
| 	echo -e "\033[31mpip must be necessary, it should be installed firstly\033[0m" | ||||
| fi | ||||
| 
 | ||||
| sudo pip install docker-compose | ||||
| 
 | ||||
| @ -0,0 +1,559 @@ | ||||
| 111.161.122.240 | ||||
| 112.90.135.96 | ||||
| 60.9.0.19 | ||||
| 61.162.100.102 | ||||
| 222.186.141.146 | ||||
| 221.235.187.129 | ||||
| 58.221.78.231 | ||||
| 113.16.212.251 | ||||
| 112.47.27.131 | ||||
| 112.123.33.18 | ||||
| 183.134.42.18 | ||||
| 116.77.75.133 | ||||
| 112.90.135.97 | ||||
| 58.221.78.42 | ||||
| 61.162.100.103 | ||||
| 111.161.122.67 | ||||
| 60.9.0.20 | ||||
| 113.16.212.48 | ||||
| 112.47.56.174 | ||||
| 112.28.196.75 | ||||
| 183.134.42.19 | ||||
| 116.77.75.137 | ||||
| 112.90.135.98 | ||||
| 113.16.212.49 | ||||
| 36.250.248.220 | ||||
| 60.9.0.21 | ||||
| 116.199.127.56 | ||||
| 221.235.187.130 | ||||
| 112.47.27.172 | ||||
| 112.90.135.99 | ||||
| 183.134.42.190 | ||||
| 60.9.0.22 | ||||
| 222.186.141.165 | ||||
| 116.77.75.138 | ||||
| 36.102.230.136 | ||||
| 112.47.56.117 | ||||
| 183.134.42.191 | ||||
| 60.9.0.23 | ||||
| 116.77.75.145 | ||||
| 36.102.230.137 | ||||
| 222.186.141.166 | ||||
| 58.221.78.46 | ||||
| 61.162.100.107 | ||||
| 116.77.75.144 | ||||
| 113.207.77.252 | ||||
| 60.9.0.252 | ||||
| 222.186.141.178 | ||||
| 183.134.42.20 | ||||
| 61.167.54.55 | ||||
| 58.221.78.47 | ||||
| 221.180.208.54 | ||||
| 116.77.75.169 | ||||
| 61.162.100.252 | ||||
| 222.186.141.186 | ||||
| 60.9.0.254 | ||||
| 113.207.79.17 | ||||
| 183.134.42.247 | ||||
| 61.167.54.57 | ||||
| 111.161.22.17 | ||||
| 116.77.75.146 | ||||
| 58.221.78.48 | ||||
| 61.162.100.41 | ||||
| 111.6.176.208 | ||||
| 113.207.79.34 | ||||
| 36.250.248.222 | ||||
| 36.102.230.19 | ||||
| 183.134.53.153 | ||||
| 116.77.75.147 | ||||
| 61.162.100.44 | ||||
| 111.6.176.209 | ||||
| 113.207.79.42 | ||||
| 183.134.53.155 | ||||
| 116.77.75.170 | ||||
| 36.102.230.20 | ||||
| 120.221.64.161 | ||||
| 222.218.87.252 | ||||
| 111.6.176.248 | ||||
| 113.207.79.37 | ||||
| 120.221.64.169 | ||||
| 112.47.56.118 | ||||
| 111.6.176.25 | ||||
| 113.194.59.80 | ||||
| 124.236.28.100 | ||||
| 113.207.81.126 | ||||
| 111.6.176.94 | ||||
| 111.6.176.95 | ||||
| 113.194.59.199 | ||||
| 221.235.187.220 | ||||
| 124.236.28.252 | ||||
| 221.235.187.244 | ||||
| 111.6.176.97 | ||||
| 124.236.28.67 | ||||
| 113.194.59.81 | ||||
| 120.221.64.53 | ||||
| 36.250.248.252 | ||||
| 120.221.64.54 | ||||
| 124.236.28.247 | ||||
| 36.250.248.254 | ||||
| 120.221.64.55 | ||||
| 124.236.28.69 | ||||
| 116.77.75.183 | ||||
| 36.250.248.27 | ||||
| 221.235.187.66 | ||||
| 183.134.53.223 | ||||
| 124.236.28.68 | ||||
| 113.207.81.78 | ||||
| 58.20.179.253 | ||||
| 27.195.145.121 | ||||
| 221.235.187.90 | ||||
| 113.207.81.81 | ||||
| 27.195.145.123 | ||||
| 221.235.187.98 | ||||
| 123.128.14.254 | ||||
| 183.134.53.248 | ||||
| 111.161.22.62 | ||||
| 123.128.14.69 | ||||
| 124.236.28.93 | ||||
| 117.169.93.249 | ||||
| 183.146.22.135 | ||||
| 125.39.1.134 | ||||
| 36.102.230.254 | ||||
| 124.236.28.92 | ||||
| 117.169.93.85 | ||||
| 27.195.145.249 | ||||
| 125.39.1.191 | ||||
| 124.236.28.94 | ||||
| 42.81.144.179 | ||||
| 222.218.87.28 | ||||
| 27.195.145.52 | ||||
| 124.236.28.95 | ||||
| 36.250.248.56 | ||||
| 222.218.87.29 | ||||
| 42.81.144.180 | ||||
| 27.195.145.62 | ||||
| 36.159.115.250 | ||||
| 36.159.115.88 | ||||
| 36.159.115.89 | ||||
| 183.146.22.137 | ||||
| 110.242.21.24 | ||||
| 124.236.28.98 | ||||
| 117.169.93.86 | ||||
| 123.128.14.70 | ||||
| 110.242.21.23 | ||||
| 124.236.28.99 | ||||
| 117.23.2.252 | ||||
| 123.128.14.72 | ||||
| 112.28.196.54 | ||||
| 110.242.21.254 | ||||
| 117.149.154.185 | ||||
| 58.20.179.74 | ||||
| 150.138.111.251 | ||||
| 117.23.2.28 | ||||
| 110.242.21.243 | ||||
| 117.149.154.186 | ||||
| 58.20.179.73 | ||||
| 150.138.111.31 | ||||
| 110.242.21.41 | ||||
| 117.23.2.29 | ||||
| 111.47.220.251 | ||||
| 150.138.111.32 | ||||
| 110.242.21.71 | ||||
| 106.41.0.37 | ||||
| 111.47.220.66 | ||||
| 110.242.21.70 | ||||
| 150.138.111.33 | ||||
| 111.47.220.67 | ||||
| 106.41.0.44 | ||||
| 150.138.167.234 | ||||
| 150.138.167.50 | ||||
| 106.41.0.45 | ||||
| 222.186.145.51 | ||||
| 150.138.167.52 | ||||
| 111.62.194.30 | ||||
| 106.41.0.46 | ||||
| 122.228.237.248 | ||||
| 42.81.144.31 | ||||
| 150.138.169.120 | ||||
| 222.186.145.54 | ||||
| 59.56.30.51 | ||||
| 106.41.0.47 | ||||
| 42.81.144.39 | ||||
| 111.62.194.31 | ||||
| 222.44.151.24 | ||||
| 150.138.169.121 | ||||
| 112.28.196.251 | ||||
| 106.41.0.61 | ||||
| 111.62.194.254 | ||||
| 123.138.157.85 | ||||
| 106.120.178.19 | ||||
| 150.138.167.51 | ||||
| 150.138.169.123 | ||||
| 112.28.196.249 | ||||
| 106.41.0.62 | ||||
| 120.253.100.20 | ||||
| 114.112.172.58 | ||||
| 123.138.157.122 | ||||
| 150.138.169.124 | ||||
| 183.146.22.145 | ||||
| 112.28.196.53 | ||||
| 120.253.100.21 | ||||
| 222.44.151.191 | ||||
| 183.146.22.146 | ||||
| 125.77.147.254 | ||||
| 112.28.196.74 | ||||
| 120.253.100.22 | ||||
| 222.44.151.25 | ||||
| 222.186.145.52 | ||||
| 120.253.100.23 | ||||
| 61.151.238.197 | ||||
| 120.253.100.30 | ||||
| 61.151.238.222 | ||||
| 61.151.238.229 | ||||
| 117.149.155.148 | ||||
| 117.149.155.147 | ||||
| 183.146.22.171 | ||||
| 150.138.169.238 | ||||
| 60.210.23.26 | ||||
| 125.77.147.68 | ||||
| 221.235.187.119 | ||||
| 125.77.147.69 | ||||
| 115.157.63.19 | ||||
| 117.149.155.76 | ||||
| 115.157.63.49 | ||||
| 122.224.186.221 | ||||
| 183.201.225.249 | ||||
| 119.52.120.138 | ||||
| 60.28.100.155 | ||||
| 125.77.147.80 | ||||
| 122.70.142.148 | ||||
| 122.224.186.222 | ||||
| 119.52.120.139 | ||||
| 60.28.100.156 | ||||
| 122.70.142.147 | ||||
| 125.77.147.82 | ||||
| 122.224.186.225 | ||||
| 60.28.100.157 | ||||
| 119.52.120.140 | ||||
| 125.77.147.88 | ||||
| 114.112.172.57 | ||||
| 122.224.186.226 | ||||
| 60.28.100.158 | ||||
| 150.138.214.84 | ||||
| 119.52.120.144 | ||||
| 58.216.21.250 | ||||
| 60.28.100.248 | ||||
| 119.52.120.145 | ||||
| 150.138.214.124 | ||||
| 60.210.23.116 | ||||
| 183.66.109.254 | ||||
| 117.180.229.254 | ||||
| 150.138.214.85 | ||||
| 119.52.120.146 | ||||
| 61.147.226.46 | ||||
| 115.157.63.50 | ||||
| 122.224.186.253 | ||||
| 58.216.22.17 | ||||
| 150.138.214.86 | ||||
| 222.186.145.53 | ||||
| 117.180.229.142 | ||||
| 58.216.22.20 | ||||
| 183.222.97.164 | ||||
| 61.147.226.48 | ||||
| 58.216.22.22 | ||||
| 183.222.97.165 | ||||
| 122.224.186.223 | ||||
| 183.66.109.44 | ||||
| 58.216.22.56 | ||||
| 183.222.97.166 | ||||
| 60.210.23.29 | ||||
| 221.235.187.67 | ||||
| 183.66.109.45 | ||||
| 115.157.63.51 | ||||
| 183.222.97.254 | ||||
| 183.146.22.142 | ||||
| 183.146.22.139 | ||||
| 120.226.55.144 | ||||
| 221.235.187.121 | ||||
| 153.99.235.112 | ||||
| 120.226.55.151 | ||||
| 120.226.55.254 | ||||
| 112.240.60.213 | ||||
| 36.25.241.75 | ||||
| 122.225.83.25 | ||||
| 153.99.235.91 | ||||
| 112.240.60.214 | ||||
| 122.225.83.28 | ||||
| 115.157.63.52 | ||||
| 36.25.241.76 | ||||
| 121.22.247.202 | ||||
| 114.112.172.59 | ||||
| 122.228.237.74 | ||||
| 36.25.241.77 | ||||
| 112.240.60.215 | ||||
| 121.22.247.204 | ||||
| 223.111.18.161 | ||||
| 122.228.237.75 | ||||
| 112.240.60.216 | ||||
| 121.22.247.254 | ||||
| 218.26.75.149 | ||||
| 223.111.18.162 | ||||
| 122.228.237.76 | ||||
| 112.240.60.217 | ||||
| 115.157.63.62 | ||||
| 218.26.75.150 | ||||
| 223.111.18.163 | ||||
| 122.225.83.26 | ||||
| 122.228.239.233 | ||||
| 112.240.60.222 | ||||
| 223.111.18.217 | ||||
| 218.26.75.151 | ||||
| 222.186.145.251 | ||||
| 122.228.239.234 | ||||
| 112.240.60.236 | ||||
| 218.26.75.152 | ||||
| 116.207.132.183 | ||||
| 122.228.239.235 | ||||
| 61.147.227.53 | ||||
| 159.226.225.149 | ||||
| 218.26.75.153 | ||||
| 116.207.132.184 | ||||
| 122.228.239.236 | ||||
| 116.207.132.253 | ||||
| 218.26.75.206 | ||||
| 113.207.10.204 | ||||
| 122.228.239.238 | ||||
| 218.26.75.236 | ||||
| 113.207.10.218 | ||||
| 122.228.239.243 | ||||
| 122.228.239.244 | ||||
| 122.228.239.246 | ||||
| 139.209.49.140 | ||||
| 183.131.124.38 | ||||
| 159.226.225.154 | ||||
| 139.209.49.138 | ||||
| 121.22.247.203 | ||||
| 139.209.49.144 | ||||
| 123.53.139.253 | ||||
| 139.209.49.151 | ||||
| 125.74.58.134 | ||||
| 139.209.49.152 | ||||
| 123.53.139.36 | ||||
| 125.74.58.135 | ||||
| 125.74.58.136 | ||||
| 139.209.49.153 | ||||
| 123.184.108.251 | ||||
| 210.38.3.23 | ||||
| 183.131.124.40 | ||||
| 123.184.108.60 | ||||
| 123.184.108.61 | ||||
| 210.38.3.24 | ||||
| 159.226.225.139 | ||||
| 183.131.124.58 | ||||
| 125.74.58.254 | ||||
| 210.38.3.42 | ||||
| 159.226.225.140 | ||||
| 61.54.7.158 | ||||
| 124.95.148.254 | ||||
| 183.131.124.59 | ||||
| 61.54.7.174 | ||||
| 210.38.3.49 | ||||
| 124.95.148.30 | ||||
| 101.69.146.234 | ||||
| 210.38.3.50 | ||||
| 61.54.7.179 | ||||
| 124.95.148.29 | ||||
| 14.204.185.100 | ||||
| 210.38.3.60 | ||||
| 61.54.7.243 | ||||
| 60.220.196.220 | ||||
| 124.95.148.31 | ||||
| 14.204.185.101 | ||||
| 60.220.196.221 | ||||
| 59.83.232.18 | ||||
| 14.204.185.102 | ||||
| 59.83.232.50 | ||||
| 61.147.210.193 | ||||
| 122.70.142.252 | ||||
| 14.204.185.123 | ||||
| 61.147.210.195 | ||||
| 14.204.185.254 | ||||
| 223.111.198.252 | ||||
| 61.147.226.185 | ||||
| 101.69.146.33 | ||||
| 223.111.198.65 | ||||
| 113.207.70.194 | ||||
| 61.147.210.242 | ||||
| 113.207.70.207 | ||||
| 101.69.146.35 | ||||
| 60.210.23.23 | ||||
| 61.147.226.47 | ||||
| 113.207.70.208 | ||||
| 101.69.146.34 | ||||
| 60.210.23.25 | ||||
| 61.147.226.49 | ||||
| 183.131.168.148 | ||||
| 60.210.23.27 | ||||
| 61.147.227.102 | ||||
| 113.207.72.102 | ||||
| 60.213.21.117 | ||||
| 58.220.71.253 | ||||
| 61.147.227.126 | ||||
| 58.220.71.51 | ||||
| 60.213.21.118 | ||||
| 14.204.185.91 | ||||
| 58.220.71.52 | ||||
| 113.207.70.209 | ||||
| 60.213.21.156 | ||||
| 113.207.77.117 | ||||
| 60.213.21.214 | ||||
| 60.220.196.250 | ||||
| 58.220.71.62 | ||||
| 116.199.127.50 | ||||
| 60.213.21.244 | ||||
| 58.220.71.63 | ||||
| 118.123.233.254 | ||||
| 116.199.127.54 | ||||
| 218.29.198.43 | ||||
| 58.220.71.64 | ||||
| 60.213.21.243 | ||||
| 118.123.233.30 | ||||
| 218.29.198.62 | ||||
| 116.77.73.164 | ||||
| 103.254.189.230 | ||||
| 58.220.71.65 | ||||
| 60.213.21.245 | ||||
| 118.123.233.31 | ||||
| 223.86.219.254 | ||||
| 183.214.132.120 | ||||
| 60.213.21.252 | ||||
| 223.86.219.65 | ||||
| 183.214.132.16 | ||||
| 116.199.127.55 | ||||
| 223.86.219.66 | ||||
| 183.214.132.17 | ||||
| 60.255.143.93 | ||||
| 61.149.9.150 | ||||
| 60.255.143.94 | ||||
| 60.255.143.95 | ||||
| 60.255.143.96 | ||||
| 36.250.233.185 | ||||
| 106.40.140.224 | ||||
| 36.250.233.208 | ||||
| 61.147.228.201 | ||||
| 36.250.233.209 | ||||
| 183.214.140.204 | ||||
| 123.53.139.37 | ||||
| 222.24.122.86 | ||||
| 61.147.228.60 | ||||
| 36.250.233.210 | ||||
| 106.40.140.254 | ||||
| 183.214.140.238 | ||||
| 36.250.233.214 | ||||
| 36.250.233.228 | ||||
| 58.221.78.186 | ||||
| 36.250.248.218 | ||||
| 218.12.228.246 | ||||
| 112.90.135.244 | ||||
| 222.24.122.89 | ||||
| 36.250.248.217 | ||||
| 221.235.187.106 | ||||
| 218.12.228.38 | ||||
| 36.250.233.254 | ||||
| 112.47.20.250 | ||||
| 218.12.228.39 | ||||
| 112.90.135.92 | ||||
| 117.27.245.227 | ||||
| 112.90.135.93 | ||||
| 117.27.245.254 | ||||
| 117.27.245.52 | ||||
| 112.90.135.94 | ||||
| 117.27.245.97 | ||||
| 112.90.135.95 | ||||
| 117.27.245.54 | ||||
| 218.60.185.251 | ||||
| 113.5.80.33 | ||||
| 125.77.130.247 | ||||
| 218.60.185.46 | ||||
| 125.77.130.251 | ||||
| 118.203.202.206 | ||||
| 118.203.202.207 | ||||
| 218.60.185.47 | ||||
| 218.60.185.48 | ||||
| 118.203.202.208 | ||||
| 118.203.202.209 | ||||
| 118.203.202.222 | ||||
| 221.180.192.100 | ||||
| 125.77.130.46 | ||||
| 125.77.130.47 | ||||
| 112.47.20.68 | ||||
| 125.77.130.48 | ||||
| 163.177.132.27 | ||||
| 112.47.27.132 | ||||
| 125.77.130.49 | ||||
| 112.47.20.89 | ||||
| 61.147.228.89 | ||||
| 112.47.20.79 | ||||
| 106.120.178.253 | ||||
| 221.180.192.254 | ||||
| 221.230.141.170 | ||||
| 221.180.192.61 | ||||
| 106.120.178.20 | ||||
| 163.177.132.30 | ||||
| 183.216.176.74 | ||||
| 221.230.141.172 | ||||
| 183.216.176.75 | ||||
| 221.230.141.174 | ||||
| 110.19.204.219 | ||||
| 110.19.204.220 | ||||
| 219.138.27.108 | ||||
| 110.19.204.221 | ||||
| 219.138.27.249 | ||||
| 103.254.189.229 | ||||
| 106.120.178.22 | ||||
| 219.138.27.30 | ||||
| 219.138.27.31 | ||||
| 113.16.208.251 | ||||
| 222.186.141.132 | ||||
| 113.16.208.77 | ||||
| 113.16.208.78 | ||||
| 222.186.141.141 | ||||
| 110.19.204.254 | ||||
| 222.186.141.142 | ||||
| 221.180.208.252 | ||||
| 222.186.141.143 | ||||
| 117.161.19.126 | ||||
| 221.180.208.46 | ||||
| 222.186.141.145 | ||||
| 60.9.0.18 | ||||
| 117.161.19.19 | ||||
| 221.180.208.47 | ||||
| 117.161.19.22 | ||||
| 113.142.80.223 | ||||
| 183.134.42.153 | ||||
| 183.134.42.154 | ||||
| 183.134.42.155 | ||||
| 115.223.24.254 | ||||
| 183.134.42.156 | ||||
| 111.161.122.100 | ||||
| 183.134.42.157 | ||||
| 61.136.167.17 | ||||
| 183.134.42.158 | ||||
| 61.136.167.18 | ||||
| 183.134.42.159 | ||||
| 113.142.80.69 | ||||
| 183.134.42.17 | ||||
| 113.142.80.71 | ||||
| 61.136.167.19 | ||||
| 113.142.80.72 | ||||
| 115.223.24.80 | ||||
| 111.161.122.133 | ||||
| 115.223.24.81 | ||||
| 111.161.122.134 | ||||
| 115.223.24.82 | ||||
| 111.161.122.135 | ||||
| 114.112.172.56 | ||||
| 222.74.113.196 | ||||
| 222.74.113.219 | ||||
| 61.167.54.236 | ||||
| 61.167.54.242 | ||||
| @ -0,0 +1,136 @@ | ||||
| # -*- coding=utf-8 -*- | ||||
| import copy | ||||
| import time | ||||
| from collections import OrderedDict | ||||
| from time import sleep | ||||
| import TickerConfig | ||||
| from inter.GetPassCodeNewOrderAndLogin import getPassCodeNewOrderAndLogin1 | ||||
| from inter.GetRandCode import getRandCode | ||||
| from inter.LoginAysnSuggest import loginAysnSuggest | ||||
| from inter.LoginConf import loginConf | ||||
| from myException.UserPasswordException import UserPasswordException | ||||
| 
 | ||||
| 
 | ||||
| class GoLogin: | ||||
|     def __init__(self, session, is_auto_code, auto_code_type): | ||||
|         self.session = session | ||||
|         self.randCode = "" | ||||
|         self.is_auto_code = is_auto_code | ||||
|         self.auto_code_type = auto_code_type | ||||
| 
 | ||||
|     def auth(self): | ||||
|         """ | ||||
|         :return: | ||||
|         """ | ||||
|         self.session.httpClint.send(self.session.urls["loginInitCdn1"]) | ||||
|         uamtkStaticUrl = self.session.urls["uamtk-static"] | ||||
|         uamtkStaticData = {"appid": "otn"} | ||||
|         return self.session.httpClint.send(uamtkStaticUrl, uamtkStaticData) | ||||
| 
 | ||||
|     def codeCheck(self): | ||||
|         """ | ||||
|         验证码校验 | ||||
|         :return: | ||||
|         """ | ||||
|         codeCheckUrl = copy.deepcopy(self.session.urls["codeCheck1"]) | ||||
|         codeCheckUrl["req_url"] = codeCheckUrl["req_url"].format(self.randCode, int(time.time() * 1000)) | ||||
|         fresult = self.session.httpClint.send(codeCheckUrl) | ||||
|         if not isinstance(fresult, str): | ||||
|             print("登录失败") | ||||
|             return | ||||
|         fresult = eval(fresult.split("(")[1].split(")")[0]) | ||||
|         if "result_code" in fresult and fresult["result_code"] == "4": | ||||
|             print(u"验证码通过,开始登录..") | ||||
|             return True | ||||
|         else: | ||||
|             if "result_message" in fresult: | ||||
|                 print(fresult["result_message"]) | ||||
|             sleep(1) | ||||
|             self.session.httpClint.del_cookies() | ||||
| 
 | ||||
|     def baseLogin(self, user, passwd): | ||||
|         """ | ||||
|         登录过程 | ||||
|         :param user: | ||||
|         :param passwd: | ||||
|         :return: 权限校验码 | ||||
|         """ | ||||
|         logurl = self.session.urls["login"] | ||||
| 
 | ||||
|         loginData = OrderedDict() | ||||
|         loginData["username"] = user, | ||||
|         loginData["password"] = passwd, | ||||
|         loginData["appid"] = "otn", | ||||
|         loginData["answer"] = self.randCode, | ||||
| 
 | ||||
|         tresult = self.session.httpClint.send(logurl, loginData) | ||||
|         if 'result_code' in tresult and tresult["result_code"] == 0: | ||||
|             print(u"登录成功") | ||||
|             tk = self.auth() | ||||
|             if "newapptk" in tk and tk["newapptk"]: | ||||
|                 return tk["newapptk"] | ||||
|             else: | ||||
|                 return False | ||||
|         elif 'result_message' in tresult and tresult['result_message']: | ||||
|             messages = tresult['result_message'] | ||||
|             if messages.find(u"密码输入错误") is not -1: | ||||
|                 raise UserPasswordException("{0}".format(messages)) | ||||
|             else: | ||||
|                 print(u"登录失败: {0}".format(messages)) | ||||
|                 print(u"尝试重新登陆") | ||||
|                 return False | ||||
|         else: | ||||
|             return False | ||||
| 
 | ||||
|     def getUserName(self, uamtk): | ||||
|         """ | ||||
|         登录成功后,显示用户名 | ||||
|         :return: | ||||
|         """ | ||||
|         if not uamtk: | ||||
|             return u"权限校验码不能为空" | ||||
|         else: | ||||
|             uamauthclientUrl = self.session.urls["uamauthclient"] | ||||
|             data = {"tk": uamtk} | ||||
|             uamauthclientResult = self.session.httpClint.send(uamauthclientUrl, data) | ||||
|             if uamauthclientResult: | ||||
|                 if "result_code" in uamauthclientResult and uamauthclientResult["result_code"] == 0: | ||||
|                     print(u"欢迎 {} 登录".format(uamauthclientResult["username"])) | ||||
|                     return True | ||||
|                 else: | ||||
|                     return False | ||||
|             else: | ||||
|                 self.session.httpClint.send(uamauthclientUrl, data) | ||||
|                 url = self.session.urls["getUserInfo"] | ||||
|                 self.session.httpClint.send(url) | ||||
| 
 | ||||
|     def go_login(self): | ||||
|         """ | ||||
|         登陆 | ||||
|         :param user: 账户名 | ||||
|         :param passwd: 密码 | ||||
|         :return: | ||||
|         """ | ||||
|         user, passwd = TickerConfig.USER, TickerConfig.PWD | ||||
|         if not user or not passwd: | ||||
|             raise UserPasswordException(u"温馨提示: 用户名或者密码为空,请仔细检查") | ||||
|         login_num = 0 | ||||
|         while True: | ||||
|             if loginConf(self.session): | ||||
| 
 | ||||
|                 result = getPassCodeNewOrderAndLogin1(session=self.session, imgType="login") | ||||
|                 if not result: | ||||
|                     continue | ||||
|                 self.randCode = getRandCode(self.is_auto_code, self.auto_code_type, result) | ||||
|                 print(self.randCode) | ||||
|                 login_num += 1 | ||||
|                 self.auth() | ||||
|                 if self.codeCheck(): | ||||
|                     uamtk = self.baseLogin(user, passwd) | ||||
|                     if uamtk: | ||||
|                         self.getUserName(uamtk) | ||||
|                         break | ||||
|             else: | ||||
|                 loginAysnSuggest(self.session, username=user, password=passwd) | ||||
|                 login_num += 1 | ||||
|                 break | ||||
| @ -0,0 +1,27 @@ | ||||
| # coding=utf-8 | ||||
| class checkRandCodeAnsyn: | ||||
|     def __init__(self, session, randCode, token): | ||||
|         self.session = session | ||||
|         self.randCode = randCode | ||||
|         self.token = token | ||||
| 
 | ||||
|     def data_par(self): | ||||
|         """ | ||||
|         :return: | ||||
|         """ | ||||
|         data = { | ||||
|             "randCode": self.randCode, | ||||
|             "rand": "randp", | ||||
|             "_json_att": "", | ||||
|             "REPEAT_SUBMIT_TOKEN": self.token | ||||
|         } | ||||
|         return data | ||||
| 
 | ||||
|     def sendCheckRandCodeAnsyn(self): | ||||
|         """ | ||||
|         下单验证码识别 | ||||
|         :return: | ||||
|         """ | ||||
|         checkRandCodeAnsynUrl = self.session.urls["checkRandCodeAnsyn"] | ||||
|         fresult = self.session.httpClint.send(checkRandCodeAnsynUrl, self.data_par())  # 校验验证码是否正确 | ||||
|         return fresult['data']['msg'] | ||||
| @ -0,0 +1,39 @@ | ||||
| # coding=utf-8 | ||||
| import datetime | ||||
| import random | ||||
| import time | ||||
| import wrapcache | ||||
| from config import configCommon | ||||
| from config.TicketEnmu import ticket | ||||
| 
 | ||||
| 
 | ||||
| class checkUser: | ||||
|     def __init__(self, session): | ||||
|         self.session = session | ||||
| 
 | ||||
|     def sendCheckUser(self): | ||||
|         """ | ||||
|         检查用户登录, 检查间隔为2分钟 | ||||
|         :return: | ||||
|         """ | ||||
|         CHENK_TIME = 1 | ||||
|         while 1: | ||||
|             time.sleep(3)  # 防止cpu占用过高 | ||||
|             configCommon.checkSleepTime(self.session)  # 修复晚上查询线程休眠时,检查登录线程为休眠,造成快豆迅速消耗 | ||||
|             if wrapcache.get("user_time") is None: | ||||
|                 check_user_url = self.session.urls["check_user_url"] | ||||
|                 data = {"_json_att": ""} | ||||
|                 check_user = self.session.httpClint.send(check_user_url, data) | ||||
|                 if check_user.get("data", False): | ||||
|                     check_user_flag = check_user["data"]["flag"] | ||||
|                     if check_user_flag is True: | ||||
|                        wrapcache.set("user_time", datetime.datetime.now(), timeout=random.randint(60, 80) * CHENK_TIME) | ||||
|                     else: | ||||
|                         if check_user['messages']: | ||||
|                             print(ticket.LOGIN_SESSION_FAIL.format(check_user['messages'])) | ||||
|                             self.session.call_login() | ||||
|                             wrapcache.set("user_time", datetime.datetime.now(), timeout=random.randint(60, 80) * CHENK_TIME) | ||||
|                         else: | ||||
|                             print(ticket.LOGIN_SESSION_FAIL.format(check_user['messages'])) | ||||
|                             self.session.call_login() | ||||
|                             wrapcache.set("user_time", datetime.datetime.now(), timeout=random.randint(60, 80) * CHENK_TIME) | ||||
| @ -0,0 +1,48 @@ | ||||
| from collections import OrderedDict | ||||
| from config.urlConf import urls | ||||
| import TickerConfig | ||||
| from inter.GetQueueCount import queryQueueByAfterNate | ||||
| 
 | ||||
| 
 | ||||
| class confirmHB: | ||||
|     def __init__(self, secretList, session, tickerNo, jzdhDate): | ||||
|         """ | ||||
|         人脸识别 | ||||
|         """ | ||||
|         self.secretList = secretList | ||||
|         self.session = session | ||||
|         self.passengerTicketStrByAfterLate = session.passengerTicketStrByAfterLate | ||||
|         self.tickerNo = tickerNo | ||||
|         self.jzdhDate = jzdhDate | ||||
| 
 | ||||
|     def data_apr(self): | ||||
|         """ | ||||
|         passengerInfo	1#XXXX#1#***************77X#bf6ae40d3655ae7eff005ee21d95876b38ab97a8031b464bc2f74a067e3ec957; | ||||
|         jzParam	2019-08-31#19#00 | ||||
|         hbTrain	5l000G177230,O# | ||||
|         lkParam | ||||
|         :return: | ||||
|         """ | ||||
|         ticker = TickerConfig.PASSENGER_TICKER_STR.get(TickerConfig.SET_TYPE[0]) | ||||
|         data = OrderedDict() | ||||
|         data["passengerInfo"] = self.passengerTicketStrByAfterLate | ||||
|         data["jzParam"] = self.jzdhDate | ||||
|         data["hbTrain"] = f"{self.tickerNo},{ticker}#" | ||||
|         data["lkParam"] = "" | ||||
|         return data | ||||
| 
 | ||||
|     def sendChechFace(self): | ||||
|         ChechFaceRsp = self.session.httpClint.send(urls.get("confirmHB"), self.data_apr()) | ||||
|         if not ChechFaceRsp.get("status"): | ||||
|             print("".join(ChechFaceRsp.get("messages")) or ChechFaceRsp.get("validateMessages")) | ||||
|             return | ||||
|         data = ChechFaceRsp.get("data") | ||||
|         if not data.get("flag"): | ||||
|             print(f"错误信息:{data.get('msg')}") | ||||
|             return | ||||
|         queue = queryQueueByAfterNate(self.session) | ||||
|         queue.sendQueryQueueByAfterNate() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1,72 @@ | ||||
| # coding=utf-8 | ||||
| import json | ||||
| import urllib | ||||
| from collections import OrderedDict | ||||
| 
 | ||||
| from inter.QueryOrderWaitTime import queryOrderWaitTime | ||||
| 
 | ||||
| 
 | ||||
| class confirmSingleForQueueAsys: | ||||
|     """ | ||||
|     订单快读排队 | ||||
|     """ | ||||
|     def __init__(self, | ||||
|                  session, | ||||
|                  passengerTicketStr, | ||||
|                  oldPassengerStr, | ||||
|                  result, | ||||
|                  randCode="", | ||||
|                  ): | ||||
|         self.session = session | ||||
|         self.passengerTicketStr = passengerTicketStr | ||||
|         self.oldPassengerStr = oldPassengerStr | ||||
|         self.result = result if isinstance(result, str) else str(result) | ||||
|         self.randCode = randCode | ||||
| 
 | ||||
|     def data_par(self): | ||||
|         """ | ||||
|         字段说明 | ||||
|             passengerTicketStr 乘客乘车代码 | ||||
|             oldPassengerStr 乘客编号代码 | ||||
|             randCode 填空 | ||||
|             purpose_codes 学生还是成人 | ||||
|             key_check_isChange autoSubmitOrderRequest返回的result字段做切割即可 | ||||
|             leftTicketStr autoSubmitOrderRequest返回的result字段做切割即可 | ||||
|             train_location autoSubmitOrderRequest返回的result字段做切割即可 | ||||
|             choose_seats | ||||
|             seatDetailType | ||||
|             _json_att | ||||
|         :return: | ||||
|         """ | ||||
|         results = self.result.split("#") | ||||
|         key_check_isChange = results[1] | ||||
|         leftTicketStr = results[2] | ||||
|         train_location = results[0] | ||||
|         data = OrderedDict() | ||||
|         data["passengerTicketStr"] = self.passengerTicketStr | ||||
|         data["oldPassengerStr"] = self.oldPassengerStr | ||||
|         data["randCode"] = self.randCode | ||||
|         data["purpose_codes"] = "ADULT" | ||||
|         data["key_check_isChange"] = key_check_isChange | ||||
|         data["leftTicketStr"] = leftTicketStr | ||||
|         data["train_location"] = train_location | ||||
|         data["choose_seats"] = "" | ||||
|         data["seatDetailType"] = "" | ||||
|         data["_json_att"] = "" | ||||
|         return data | ||||
| 
 | ||||
|     def sendConfirmSingleForQueueAsys(self): | ||||
|         """ | ||||
|         请求订单快读排队接口 | ||||
|         :return: | ||||
|         """ | ||||
|         urls = self.session.urls["confirmSingleForQueueAsys"] | ||||
|         data = self.data_par() | ||||
|         confirmSingleForQueueAsysResult = self.session.httpClint.send(urls, data) | ||||
|         if confirmSingleForQueueAsysResult.get("status", False) and confirmSingleForQueueAsysResult.get("data", False): | ||||
|             queueData = confirmSingleForQueueAsysResult.get("data", {}) | ||||
|             if queueData.get("submitStatus", False): | ||||
|                 qwt = queryOrderWaitTime(session=self.session) | ||||
|                 qwt.sendQueryOrderWaitTime() | ||||
|             else: | ||||
|                 print(queueData.get("errMsg", "")) | ||||
| @ -0,0 +1,36 @@ | ||||
| # coding=utf-8 | ||||
| import json | ||||
| import re | ||||
| 
 | ||||
| 
 | ||||
| class getRepeatSubmitToken: | ||||
|     def __init__(self, session): | ||||
|         self.session = session | ||||
| 
 | ||||
|     def sendGetRepeatSubmitToken(self): | ||||
|         """ | ||||
|         获取提交车票请求token | ||||
|         :return: token | ||||
|         """ | ||||
|         initdc_url = self.session.urls["initdc_url"] | ||||
|         initdc_result = self.session.httpClint.send(initdc_url, ) | ||||
|         token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'") | ||||
|         ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?') | ||||
|         order_request_params_name = re.compile(r'var orderRequestDTO=(\{.+\})?') | ||||
|         token = re.search(token_name, initdc_result).group(1) | ||||
|         re_tfpf = re.findall(ticketInfoForPassengerForm_name, initdc_result) | ||||
|         re_orp = re.findall(order_request_params_name, initdc_result) | ||||
|         if re_tfpf: | ||||
|             ticketInfoForPassengerForm = json.loads(re_tfpf[0].replace("'", '"')) | ||||
|         else: | ||||
|             ticketInfoForPassengerForm = "" | ||||
|         if re_orp: | ||||
|             order_request_params = json.loads(re_orp[0].replace("'", '"')) | ||||
|         else: | ||||
|             order_request_params = "" | ||||
|         return { | ||||
|             "token": token, | ||||
|             "ticketInfoForPassengerForm": ticketInfoForPassengerForm, | ||||
|             "order_request_params": order_request_params, | ||||
|             "session": self.session | ||||
|         } | ||||
| @ -0,0 +1,20 @@ | ||||
| # coding=utf-8 | ||||
| from config.urlConf import urls | ||||
| 
 | ||||
| 
 | ||||
| def loginAysnSuggest(session, username, password): | ||||
|     """ | ||||
|     登录接口 | ||||
|     ps: 不需要验证码 | ||||
|     :return: | ||||
|     """ | ||||
|     loginAysnSuggestUrls = urls.get("loginAysnSuggest") | ||||
|     data = { | ||||
|         "loginUserDTO.user_name": username, | ||||
|         "userDTO.password":	password | ||||
|     } | ||||
|     loginAysnSuggestRsp = session.httpClint.send(urls=loginAysnSuggestUrls, data=data) | ||||
|     if loginAysnSuggestRsp and loginAysnSuggestRsp.get("httpstatus") is 200 and loginAysnSuggestRsp.get("data", {}).get("loginCheck") == "Y": | ||||
|         print(u"登录成功") | ||||
|     else: | ||||
|         print(u"登录失败, {0} {1}".format("".join(loginAysnSuggestRsp.get("messages")), loginAysnSuggestRsp.get("validateMessages"))) | ||||
| @ -0,0 +1,22 @@ | ||||
| # coding=utf-8 | ||||
| from config.urlConf import urls | ||||
| 
 | ||||
| 
 | ||||
| def loginConf(session): | ||||
|     """ | ||||
|     判断登录是否需要验证码 | ||||
|     :param session: | ||||
|     :return: | ||||
|     """ | ||||
|     loginConfUrl = urls.get("loginConf") | ||||
|     loginConfRsp = session.httpClint.send(urls=loginConfUrl, data={}) | ||||
|     if loginConfRsp and loginConfRsp.get("data", {}).get("is_login_passCode") == "N": | ||||
|         print(u"不需要验证码") | ||||
|         return False | ||||
|     else: | ||||
|         print(u"需要验证码") | ||||
|         return True | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     pass | ||||
| @ -0,0 +1,37 @@ | ||||
| import datetime | ||||
| import wrapcache | ||||
| import TickerConfig | ||||
| from config.urlConf import urls | ||||
| from inter.ConfirmHB import confirmHB | ||||
| 
 | ||||
| 
 | ||||
| class passengerInitApi: | ||||
|     def __init__(self, session, secretList, tickerNo): | ||||
|         """ | ||||
|         获取候补信息 | ||||
|         """ | ||||
|         self.secretList = secretList | ||||
|         self.tickerNo = tickerNo | ||||
|         self.session = session | ||||
| 
 | ||||
|     def sendPassengerInitApi(self): | ||||
|         passengerInitApiRsp = self.session.httpClint.send(urls.get("passengerInitApi")) | ||||
|         if not passengerInitApiRsp.get("status"): | ||||
|             print("".join(passengerInitApiRsp.get("messages")) or passengerInitApiRsp.get("validateMessages")) | ||||
|             return | ||||
|         data = passengerInitApiRsp.get("data", {}) | ||||
|         jzdhDateE = data.get("jzdhDateE") | ||||
|         if not data.get("jzdhHourE"): | ||||
|             wrapcache.set(key=f"hb{self.tickerNo}", value=datetime.datetime.now(), | ||||
|                           timeout=TickerConfig.TICKET_BLACK_LIST_TIME * 60) | ||||
|             print(f"获取当前候补日期失败,原因: {data.get('jzdhHourE')}") | ||||
|             return | ||||
|         jzdhHourE = data.get("jzdhHourE").replace(":", "#") | ||||
|         jzdhDate = f"{jzdhDateE}#{jzdhHourE}" | ||||
|         print(f"当前候补日期为:{jzdhDateE} {jzdhHourE}") | ||||
|         confirm = confirmHB(self.secretList, self.session, self.tickerNo, jzdhDate) | ||||
|         confirm.sendChechFace() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
											
												Binary file not shown.
											
										
									
								| @ -0,0 +1,2 @@ | ||||
| class PassengerUserException(Exception): | ||||
|     pass | ||||
| @ -0,0 +1,2 @@ | ||||
| class UserPasswordException(Exception): | ||||
|     pass | ||||
| @ -0,0 +1,2 @@ | ||||
| class balanceException(Exception): | ||||
|     pass | ||||
| @ -0,0 +1,2 @@ | ||||
| class ticketConfigException(Exception): | ||||
|     pass | ||||
| @ -0,0 +1,2 @@ | ||||
| class ticketIsExitsException(Exception): | ||||
|     pass | ||||
| @ -0,0 +1,2 @@ | ||||
| class ticketNumOutException(Exception): | ||||
|     pass | ||||
| @ -0,0 +1,202 @@ | ||||
| # coding=utf-8 | ||||
| import json | ||||
| import socket | ||||
| import re | ||||
| # s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||
| # s.connect(('183.232.189.31', 80)) | ||||
| # get_str = 'GET {0} HTTP/1.1\r\nConnection: close\r\n' \ | ||||
| #           'Host: %s\r\n' \ | ||||
| #           'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' \ | ||||
| #           '\r\nAccept: */*\r\n' \ | ||||
| #           '\r\n' | ||||
| # post_str = "POST {0} HTTP/1.1\r\n" \ | ||||
| #            "Host: kyfw.12306.cn\r\n" \ | ||||
| #            "Connection: close\r\n"\ | ||||
| #            "Origin: https://kyfw.12306.cn\r\n" \ | ||||
| #            "X-Requested-With: XMLHttpRequest\r\n" \ | ||||
| #            "Referer: https://kyfw.12306.cn/otn/leftTicket/init\r\n" \ | ||||
| #            "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n" \ | ||||
| #            "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" \ | ||||
| #            "Accept: application/json, text/javascript, */*; q=0.01\r\n" \ | ||||
| #            "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5\r\n" \ | ||||
| #            "Content-Length: 9\r\n"\ | ||||
| #            "Cookie: _passport_session=a459aba69761497eb31de76c27795e999613; _passport_ct=9116b2cb0bf443e1a01d22ac8c1ae449t5007; route=9036359bb8a8a461c164a04f8f50b252; BIGipServerpool_passport=200081930.50215.0000; BIGipServerotn=484704778.64545.0000\r\n\n"\ | ||||
| #            "appid=otn\r\n" | ||||
| # # s.sendall(get_str.format("https://kyfw.12306.cn/otn/resources/login.html")) | ||||
| # s.sendall(post_str.format("https://kyfw.12306.cn/passport/web/auth/uamtk")) | ||||
| from config.urlConf import urls | ||||
| 
 | ||||
| 
 | ||||
| def default_get_data(): | ||||
|     """ | ||||
|     get请求默认组装字符串 | ||||
|     需要拼接的字符串 | ||||
|     -- url 发送请求的全连接 | ||||
|     :return: | ||||
|         """ | ||||
|     return 'GET {0} HTTP/1.1\r\nConnection: close\r\n' \ | ||||
|            'Host: kyfw.12306.cn\r\n' \ | ||||
|            "Referer: {1}\r\n" \ | ||||
|            'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' \ | ||||
|            '\r\nAccept: */*\r\n' \ | ||||
|            "Cookie: {2}\r\n\n"\ | ||||
|            '\r\n' | ||||
|     # return 'GET {0} HTTP/1.1\r\nConnection: close\r\n' \ | ||||
|     #       'Host: kyfw.12306.cn\r\n' \ | ||||
|     #       'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' \ | ||||
|     #       '\r\nAccept: */*\r\n' \ | ||||
|     #       '\r\n' | ||||
| 
 | ||||
| 
 | ||||
| def default_post_data(): | ||||
|     """ | ||||
|     post请求默认组装字符串 | ||||
|     需要拼接的字符串 | ||||
|     -- url 发送请求的全连接 | ||||
|     -- Referer 请求页面来源 | ||||
|     -- Content-Length: body 长度 | ||||
|     -- Cookie 页面请求的身份认证 | ||||
|     -- appid 接口请求报文 | ||||
|     :return: | ||||
|     """ | ||||
|     return "POST https://kyfw.12306.cn{0} HTTP/1.1\r\n" \ | ||||
|            "Host: kyfw.12306.cn\r\n" \ | ||||
|            "Connection: close\r\n"\ | ||||
|            "Origin: https://kyfw.12306.cn\r\n" \ | ||||
|            "X-Requested-With: XMLHttpRequest\r\n" \ | ||||
|            "Referer: {3}\r\n" \ | ||||
|            "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n" \ | ||||
|            "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" \ | ||||
|            "Accept: application/json, text/javascript, */*; q=0.01\r\n" \ | ||||
|            "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5\r\n" \ | ||||
|            "Content-Length: {2}\r\n"\ | ||||
|            "Cookie: {4}\r\n\n"\ | ||||
|            "{1}\r\n"\ | ||||
|            # "\r\n" | ||||
| 
 | ||||
| 
 | ||||
| class socketUtils: | ||||
|     def __init__(self, host, port=80): | ||||
|         self.host = host | ||||
|         self.port = port | ||||
|         self.s = self.connect_socket(self.host, self.port) | ||||
| 
 | ||||
|     def connect_socket(self, host, port): | ||||
|         """ | ||||
|         连接socket | ||||
|         :param host: | ||||
|         :param port: | ||||
|         :return: | ||||
|         """ | ||||
|         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||
|         s.connect((host if isinstance(host, str) else str(host), | ||||
|                    port if isinstance(port, int) else int(port))) | ||||
|         return s | ||||
| 
 | ||||
|     def close_s(self): | ||||
|         self.s.close() | ||||
| 
 | ||||
|     # def send(self, urls, Cookie=None, data=None): | ||||
|     #     """ | ||||
|     #     发送请求 | ||||
|     #     :param urls: | ||||
|     #     :param data: | ||||
|     #     :param cookie: | ||||
|     #     :return: | ||||
|     #     """ | ||||
|     #     url = urls.get("req_url", "") | ||||
|     #     Referer = urls.get("Referer", "") | ||||
|     #     if urls.get("req_type", "get") == "post": | ||||
|     #         Content_Length = len(data) | ||||
|     #     Cookie = "tk=pnidlCoFy2B7wxO_X_pESbrkZFSq3OtVA_xzXwuba2a0; JSESSIONID=C6144324BFCE36AC5082E543E934E8B3; current_captcha_type=Z; _jc_save_fromDate=2018-08-03; _jc_save_fromStation=%u6DF1%u5733%2CSZQ; _jc_save_toDate=2018-08-03; _jc_save_toStation=%u957F%u6C99%2CCSQ; _jc_save_wfdc_flag=dc; ten_key=b5L6aMWfnzBm8CgQe8pcAKQsmVBS2PYH; BIGipServerpool_passport=166527498.50215.0000; BIGipServerotn=165937674.50210.0000; route=c5c62a339e7744272a54643b3be5bf64; RAIL_DEVICEID=fC-yepiUqNjsBiRvtLBXW4JqQmabCfB9QxI3FifJZK9YDRsImhJLSz4sAQ4HiGF7uQAFdFyISg6jA7KAhtpEldJV9ZMNsn6Dzm_psA5CBDwSNfiORf42w-LIRvkeGvdKFtegZwWGlkA2fVuEWKu-1xAYdCXRnsMD; RAIL_EXPIRATION=1533420302032; _jc_save_detail=true" | ||||
|     #     if data: | ||||
|     #         send_value = default_post_data().format(url, | ||||
|     #                                                 data, | ||||
|     #                                                 Content_Length, | ||||
|     #                                                 Referer, | ||||
|     #                                                 Cookie | ||||
|     #                                                 ) | ||||
|     #         print("send_value: " + send_value) | ||||
|     #         self.s.sendall(send_value) | ||||
|     #     else: | ||||
|     #         self.s.sendall(default_get_data().format(url, | ||||
|     #                                                  Referer, | ||||
|     #                                                  Cookie)) | ||||
|     #     total_data = "" | ||||
|     #     while 1: | ||||
|     #         data = self.s.recv(1024) | ||||
|     #         total_data += data | ||||
|     #         if not data: | ||||
|     #             break | ||||
|     #     self.close_s() | ||||
|     #     print(total_data) | ||||
|     #     return self.recv_data(total_data) | ||||
| 
 | ||||
|     def recv_data(self, r_data): | ||||
|         cookie = self.get_cookie(r_data) | ||||
|         status_code = self.get_status_code(r_data) | ||||
|         r_body = self.get_rep_body(r_data) | ||||
|         return { | ||||
|             "cookie": cookie, | ||||
|             "status_code": status_code, | ||||
|             "r_body": r_body | ||||
|         } | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def get_cookie(recv_data): | ||||
|         """ | ||||
|         提取cookie | ||||
|         :param recv_data: | ||||
|         :return: | ||||
|         """ | ||||
|         if not isinstance(recv_data, str): | ||||
|             recv_data = str(recv_data) | ||||
|         cookies_re = re.compile(r"Set-Cookie: (\S+);") | ||||
|         cookies = re.findall(cookies_re, recv_data) | ||||
|         return "; ".join(cookies) | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def get_status_code(recv_data): | ||||
|         """ | ||||
|         获取状态码 | ||||
|         :return: | ||||
|         """ | ||||
|         if not isinstance(recv_data, str): | ||||
|             recv_data = str(recv_data) | ||||
|         http_code_re = re.compile(r"HTTP/1.1 (\S+) ") | ||||
|         status_code = re.search(http_code_re, recv_data).group(1) | ||||
|         return status_code | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def get_rep_body(recv_data): | ||||
|         """ | ||||
|         获取返回值 | ||||
|         :param recv_data: | ||||
|         :return: | ||||
|         """ | ||||
|         if not isinstance(recv_data, str): | ||||
|             recv_data = str(recv_data) | ||||
|         if recv_data.find("{") != -1 and recv_data.find("}") != -1: | ||||
|             data = json.loads(recv_data.split("\n")[-1]) | ||||
|             return data | ||||
|         else: | ||||
|             print(recv_data) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     so = socketUtils('183.232.189.31', 80) | ||||
|     train_date = "2018-08-03" | ||||
|     from_station = "SZQ" | ||||
|     to_station = "CSQ" | ||||
|     urls["select_url"]["req_url"] = "https://kyfw.12306.cn" + urls["select_url"]["req_url"].format(train_date, from_station, to_station) | ||||
|     result = so.send(urls=urls["select_url"]) | ||||
|     print(result) | ||||
| 
 | ||||
|     so = socketUtils('183.232.189.31', 80) | ||||
| 
 | ||||
|     data = "secretStr=Vgo534nDZiCH8NCvyEPcGepzJoRCjvYr34gKFv5CW1K1XtM6mtKHoiFPjUYvaVKoe06SMhUUpT%2FK%0AxIEIsBD4zHgJPpVyKiTPx80y6OCWhNgcKjib2LLMXMJfgTgh0RKPISjkDjVFmO9p905O%2FegDeKjp%0A1fhIeqCuYraHjNhI0PjQY39BAY4AHLzW0iGgDq8b%2FtpyOY8Td2XfIWNZJCWzgyPkNXOk0HUguB2G%0AKh2T8nlko6zb5ra%2B%2BA%3D%3D&train_date=2018-08-03&back_train_date=2018-08-03&tour_flag=dc&purpose_codes=ADULT&query_from_station_name=深圳&query_to_station_name=长沙&undefined" | ||||
|     result1 = so.send(urls=urls["submit_station_url"], data=data) | ||||
|     print(result1) | ||||
|     # so = socketUtils('183.232.189.31', 80) | ||||
|     # result = so.send(url="https://kyfw.12306.cn/passport/web/login", s_data="") | ||||
|     # print(result) | ||||
| @ -0,0 +1,7 @@ | ||||
| bs4==0.0.1 | ||||
| requests==2.18.4 | ||||
| Pillow | ||||
| wrapcache==1.0.8 | ||||
| ntplib==0.3.3 | ||||
| selenium==3.11.0 | ||||
| fake-useragent==0.1.11 | ||||
| @ -0,0 +1,15 @@ | ||||
| beautifulsoup4==4.5.3 | ||||
| bs4==0.0.1 | ||||
| requests==2.18.4 | ||||
| Pillow | ||||
| wrapcache==1.0.8 | ||||
| ntplib==0.3.3 | ||||
| sklearn | ||||
| opencv-python | ||||
| keras==2.2.4 | ||||
| tensorflow==1.14.0 | ||||
| matplotlib>=3.0.2 | ||||
| numpy>=1.14.6 | ||||
| scipy>=1.1.0 | ||||
| selenium==3.11.0 | ||||
| fake-useragent==0.1.11 | ||||
											
												
													File diff suppressed because one or more lines are too long
												
											
										
									
								| After Width: | Height: | Size: 380 KiB | 
| After Width: | Height: | Size: 63 KiB | 
| After Width: | Height: | Size: 9.6 KiB | 
| After Width: | Height: | Size: 11 KiB | 
| After Width: | Height: | Size: 32 KiB | 
| After Width: | Height: | Size: 223 KiB | 
| @ -0,0 +1,115 @@ | ||||
| # coding: utf-8 | ||||
| import TickerConfig | ||||
| 
 | ||||
| if TickerConfig.AUTO_CODE_TYPE == 2: | ||||
|     import base64 | ||||
|     import os | ||||
|     import cv2 | ||||
|     import numpy as np | ||||
|     from keras import models, backend | ||||
|     import tensorflow as tf | ||||
|     from verify import pretreatment | ||||
|     from verify.mlearn_for_image import preprocess_input | ||||
| 
 | ||||
|     graph = tf.get_default_graph() | ||||
| 
 | ||||
| PATH = lambda p: os.path.abspath( | ||||
|     os.path.join(os.path.dirname(__file__), p) | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| TEXT_MODEL = "" | ||||
| IMG_MODEL = "" | ||||
| 
 | ||||
| 
 | ||||
| def get_text(img, offset=0): | ||||
|     text = pretreatment.get_text(img, offset) | ||||
|     text = cv2.cvtColor(text, cv2.COLOR_BGR2GRAY) | ||||
|     text = text / 255.0 | ||||
|     h, w = text.shape | ||||
|     text.shape = (1, h, w, 1) | ||||
|     return text | ||||
| 
 | ||||
| 
 | ||||
| def base64_to_image(base64_code): | ||||
|     # base64解码 | ||||
|     img_data = base64.b64decode(base64_code) | ||||
|     # 转换为np数组 | ||||
|     img_array = np.fromstring(img_data, np.uint8) | ||||
|     # 转换成opencv可用格式 | ||||
|     img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR) | ||||
| 
 | ||||
|     return img | ||||
| 
 | ||||
| 
 | ||||
| class Verify: | ||||
|     def __init__(self): | ||||
|         self.textModel = "" | ||||
|         self.imgModel = "" | ||||
|         self.loadImgModel() | ||||
|         self.loadTextModel() | ||||
| 
 | ||||
|     def loadTextModel(self): | ||||
|         if not self.textModel: | ||||
|             self.textModel = models.load_model(PATH('../model.v2.0.h5')) | ||||
|         else: | ||||
|             print("无需加载模型model.v2.0.h5") | ||||
| 
 | ||||
|     def loadImgModel(self): | ||||
|         if not self.imgModel: | ||||
|             self.imgModel = models.load_model(PATH('../12306.image.model.h5')) | ||||
| 
 | ||||
|     def verify(self, fn): | ||||
|         verify_titles = ['打字机', '调色板', '跑步机', '毛线', '老虎', '安全帽', '沙包', '盘子', '本子', '药片', '双面胶', '龙舟', '红酒', '拖把', '卷尺', | ||||
|                          '海苔', '红豆', '黑板', '热水袋', '烛台', '钟表', '路灯', '沙拉', '海报', '公交卡', '樱桃', '创可贴', '牌坊', '苍蝇拍', '高压锅', | ||||
|                          '电线', '网球拍', '海鸥', '风铃', '订书机', '冰箱', '话梅', '排风机', '锅铲', '绿豆', '航母', '电子秤', '红枣', '金字塔', '鞭炮', | ||||
|                          '菠萝', '开瓶器', '电饭煲', '仪表盘', '棉棒', '篮球', '狮子', '蚂蚁', '蜡烛', '茶盅', '印章', '茶几', '啤酒', '档案袋', '挂钟', '刺绣', | ||||
|                          '铃铛', '护腕', '手掌印', '锦旗', '文具盒', '辣椒酱', '耳塞', '中国结', '蜥蜴', '剪纸', '漏斗', '锣', '蒸笼', '珊瑚', '雨靴', '薯条', | ||||
|                          '蜜蜂', '日历', '口哨'] | ||||
|         # 读取并预处理验证码 | ||||
|         img = base64_to_image(fn) | ||||
|         text = get_text(img) | ||||
|         imgs = np.array(list(pretreatment._get_imgs(img))) | ||||
|         imgs = preprocess_input(imgs) | ||||
|         text_list = [] | ||||
|         # 识别文字 | ||||
|         self.loadTextModel() | ||||
|         global graph | ||||
|         with graph.as_default(): | ||||
|             label = self.textModel.predict(text) | ||||
|         label = label.argmax() | ||||
|         text = verify_titles[label] | ||||
|         text_list.append(text) | ||||
|         # 获取下一个词 | ||||
|         # 根据第一个词的长度来定位第二个词的位置 | ||||
|         if len(text) == 1: | ||||
|             offset = 27 | ||||
|         elif len(text) == 2: | ||||
|             offset = 47 | ||||
|         else: | ||||
|             offset = 60 | ||||
|         text = get_text(img, offset=offset) | ||||
|         if text.mean() < 0.95: | ||||
|             with graph.as_default(): | ||||
|                 label = self.textModel.predict(text) | ||||
|             label = label.argmax() | ||||
|             text = verify_titles[label] | ||||
|             text_list.append(text) | ||||
|         print("题目为{}".format(text_list)) | ||||
|         # 加载图片分类器 | ||||
|         self.loadImgModel() | ||||
|         with graph.as_default(): | ||||
|             labels = self.imgModel.predict(imgs) | ||||
|         labels = labels.argmax(axis=1) | ||||
|         results = [] | ||||
|         for pos, label in enumerate(labels): | ||||
|             l = verify_titles[label] | ||||
|             print(pos + 1, l) | ||||
|             if l in text_list: | ||||
|                 results.append(str(pos + 1)) | ||||
|         return results | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     pass | ||||
|     # verify("verify-img1.jpeg") | ||||
| @ -0,0 +1,102 @@ | ||||
| #! env python | ||||
| # coding: utf-8 | ||||
| # 功能:对图像进行预处理,将文字部分单独提取出来 | ||||
| # 并存放到ocr目录下 | ||||
| # 文件名为原验证码文件的文件名 | ||||
| import TickerConfig | ||||
| if TickerConfig.AUTO_CODE_TYPE == 2: | ||||
|     import hashlib | ||||
|     import os | ||||
|     import pathlib | ||||
| 
 | ||||
|     import cv2 | ||||
|     import numpy as np | ||||
|     import requests | ||||
|     import scipy.fftpack | ||||
| 
 | ||||
| 
 | ||||
| PATH = 'imgs' | ||||
| 
 | ||||
| 
 | ||||
| def download_image(): | ||||
|     # 抓取验证码 | ||||
|     # 存放到指定path下 | ||||
|     # 文件名为图像的MD5 | ||||
|     url = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand' | ||||
|     r = requests.get(url) | ||||
|     fn = hashlib.md5(r.content).hexdigest() | ||||
|     with open(f'{PATH}/{fn}.jpg', 'wb') as fp: | ||||
|         fp.write(r.content) | ||||
| 
 | ||||
| 
 | ||||
| def download_images(): | ||||
|     pathlib.Path(PATH).mkdir(exist_ok=True) | ||||
|     for idx in range(40000): | ||||
|         download_image() | ||||
|         print(idx) | ||||
| 
 | ||||
| 
 | ||||
| def get_text(img, offset=0): | ||||
|     # 得到图像中的文本部分 | ||||
|     return img[3:22, 120 + offset:177 + offset] | ||||
| 
 | ||||
| 
 | ||||
| def avhash(im): | ||||
|     im = cv2.resize(im, (8, 8), interpolation=cv2.INTER_CUBIC) | ||||
|     avg = im.mean() | ||||
|     im = im > avg | ||||
|     im = np.packbits(im) | ||||
|     return im | ||||
| 
 | ||||
| 
 | ||||
| def phash(im): | ||||
|     im = cv2.resize(im, (32, 32), interpolation=cv2.INTER_CUBIC) | ||||
|     im = scipy.fftpack.dct(scipy.fftpack.dct(im, axis=0), axis=1) | ||||
|     im = im[:8, :8] | ||||
|     med = np.median(im) | ||||
|     im = im > med | ||||
|     im = np.packbits(im) | ||||
|     return im | ||||
| 
 | ||||
| 
 | ||||
| def _get_imgs(img): | ||||
|     interval = 5 | ||||
|     length = 67 | ||||
|     for x in range(40, img.shape[0] - length, interval + length): | ||||
|         for y in range(interval, img.shape[1] - length, interval + length): | ||||
|             yield img[x:x + length, y:y + length] | ||||
| 
 | ||||
| 
 | ||||
| def get_imgs(img): | ||||
|     imgs = [] | ||||
|     for img in _get_imgs(img): | ||||
|         imgs.append(phash(img)) | ||||
|     return imgs | ||||
| 
 | ||||
| 
 | ||||
| def pretreat(): | ||||
|     if not os.path.isdir(PATH): | ||||
|         download_images() | ||||
|     texts, imgs = [], [] | ||||
|     for img in os.listdir(PATH): | ||||
|         img = os.path.join(PATH, img) | ||||
|         img = cv2.imread(img, cv2.IMREAD_GRAYSCALE) | ||||
|         texts.append(get_text(img)) | ||||
|         imgs.append(get_imgs(img)) | ||||
|     return texts, imgs | ||||
| 
 | ||||
| 
 | ||||
| def load_data(path='data.npz'): | ||||
|     if not os.path.isfile(path): | ||||
|         texts, imgs = pretreat() | ||||
|         np.savez(path, texts=texts, images=imgs) | ||||
|     f = np.load(path) | ||||
|     return f['texts'], f['images'] | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     texts, imgs = load_data() | ||||
|     print(texts.shape) | ||||
|     print(imgs.shape) | ||||
|     imgs = imgs.reshape(-1, 8) | ||||
|     print(np.unique(imgs, axis=0).shape) | ||||
					Loading…
					
					
				
		Reference in new issue