Skip to content

Commit

Permalink
update version 1.2.001
Browse files Browse the repository at this point in the history
  • Loading branch information
testerSunshine committed Dec 17, 2019
1 parent 05f1486 commit 9d70f83
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 219 deletions.
40 changes: 35 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,56 @@
#### 依赖库
- 验证码目前可以本地识别,需要下载模型,放于项目根目录,全部代码来源于此项目 [传送门](https://github.com/zhaipro/easy12306),表示感谢
```
PS:
1. 模型下载链接:https://pan.baidu.com/s/1rS155VjweWVWIJogakechA 密码:bmlm
群里面也可以下载
2. git仓库下载:https://github.com/testerSunshine/12306model.git
```
- 自托管云打码服务器搭建:[12306_code_server](https://github.com/YinAoXiong/12306_code_server)
- 如果大家有空闲的服务器,可搭建之后再这个 [issues](https://github.com/testerSunshine/12306/issues/446) 里面填入自己的服务器(请注意服务器安全!)
- 项目依赖包查看 [requirements.txt](requirements.txt)
- 如果大家有空闲的服务器,可搭建之后在这个 [issues](https://github.com/testerSunshine/12306/issues/446) 里面填入自己的服务器(请注意服务器安全!)
- 项目依赖 [requirements.txt](requirements.txt)
- 安装方法x:
- root用户(避免多python环境产生问题): `pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt`
- 非root用户(避免安装和运行时使用了不同环境): `pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt`
- 许多windows的用户装不了tensorflow的话,可以适当降低版本或者升高版本都是可以的
```
1. tensorflow的兼容版本 1.14.0rc\1.14.0rc\1.15.0\1.15.0rc
以上版本都测试无问题
2. 如果pip代理的清华源无法下载,可以更换其他源解决此问题
```
#### 项目使用说明
- 服务器启动:
- 修改[配置](TickerConfig.py)文件
- 可以配置邮箱,配置邮箱的格式在[配置](TickerConfig.py)里面可以看到ex
- 可以配置server酱提醒(推荐)[配置教程](https://www.jianshu.com/p/8d10b5b9c4e3)
```
# 测试邮箱和server酱是否可用, server酱测试的前提是server酱开关开启
# 可以配置server酱提醒(推荐)[配置教程](https://www.jianshu.com/p/8d10b5b9c4e3)
# 用python3 还是python 完全取决于安装的时候配置的环境变量是否为python3,以下启动默认环境变量为python3
python3 run.py t
```
- 配置[配置](TickerConfig.py)文件的时候,需注意空格和遵循python语法格式
- 运行根目录`sudo python run.py`,即可开始
- 启动前请先筛选cdn,这点很`重要`
```
python3 run.py c
```
- 启动服务
```
python3 run.py r
```
- 如果你不知道如何操作,下面的命令可能会帮助你
```
python3 run.py -h
——————————————————————————
sage: run.py [-h] operate
positional arguments:
operate r: 运行抢票程序, c: 过滤cdn, t: 测试邮箱和server酱,server酱
```
- 如果你的服务器安装了docker与docker-compose, 那么就可以通过`docker-compose`进行启动,`docker.sh`脚本对此进行了封装,可以通过如下命令进行启动
- 1、`sudo ./docker.sh run` #创建一个镜像并启动容器,如果镜像已经创建过了会直接启动容器。
- 2、`sudo ./docker.sh restart` #修改配置文件后,通过此名命令可重新加载容器运行
Expand Down
23 changes: 12 additions & 11 deletions TickerConfig.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding=utf-8 -*-
# 关于软件使用配置说明,一定要看!!!
# ps: 如果是候补车票,需要通过人证一致性核验的用户及激活的“铁路畅行”会员可以提交候补需求,请您按照操作说明在铁路12306app.上完成人证核验
# 关于候补了之后是否还能继续捡漏的问题在此说明: 软件为全自动候补加捡漏,如果软件候补成功则会停止抢票,发出邮件通知,但是不会影响你继续捡漏,
Expand All @@ -8,13 +9,13 @@

# 出发日期(list) "2018-01-06", "2018-01-07"
STATION_DATES = [
"2019-10-25"
"2020-01-05"
]

# 填入需要购买的车次(list),"G1353"
# 修改车次填入规则,注:(以前设置的车次逻辑不变),如果车次填入为空,那么就是当日乘车所有车次都纳入筛选返回
# 不填车次是整个list为空才算,如果不是为空,依然会判断车次的,这种是错误的写法 [""], 正确的写法 []
STATION_TRAINS = []
STATION_TRAINS = ["G1002"]

# 出发城市,比如深圳北,就填深圳就搜得到
FROM_STATION = "深圳北"
Expand All @@ -32,7 +33,7 @@
# "硬座",
# "无座",
# "动卧",
SET_TYPE = []
SET_TYPE = ["硬座"]

# 当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交
# bool
Expand All @@ -58,7 +59,7 @@
AUTO_CODE_TYPE = 2

# 此处设置云打码服务器地址,如果有自建的服务器,可以自行更改
HOST = "api.readour.org"
HOST = "120.77.154.140:8000"
REQ_URL = "/verify/base64/"
HTTP_TYPE = "http"
# HOST="12306.yinaoxiong.cn" #备用服务器稳定性较差
Expand Down Expand Up @@ -97,7 +98,7 @@
IS_CDN = 1

# 下单接口分为两种,1 模拟网页自动捡漏下单(不稳定),2 模拟车次后面的购票按钮下单(稳如老狗)
ORDER_TYPE = 1
ORDER_TYPE = 2

# 下单模式 1 为预售,整点刷新,刷新间隔0.1-0.5S, 然后会校验时间,比如12点的预售,那脚本就会在12.00整检票,刷新订单
# 2 是捡漏,捡漏的刷新间隔时间为0.5-3秒,时间间隔长,不容易封ip
Expand All @@ -116,17 +117,17 @@
# 1=使用selenium获取devicesID
# 2=使用网页端/otn/HttpZF/logdevice获取devicesId,这个接口的算法目前可能有点问题,如果登录一直302的请改为配置1
# 3=自己打开浏览器在headers-Cookies中抓取RAIL_DEVICEID和RAIL_EXPIRATION,这个就不用配置selenium
COOKIE_TYPE = 1
COOKIE_TYPE = 3
# 如果COOKIE_TYPE=1,则需配置chromeDriver路径,下载地址http://chromedriver.storage.googleapis.com/index.html
# chromedriver配置版本只要和chrome的大版本匹配就行
CHROME_PATH = "/usr/src/app/chromedriver"

#为了docker37 准备的环境变量,windows环境可以不用管这个参数
CHROME_CHROME_PATH = "/opt/google/chrome/google-chrome";
# 为了docker37 准备的环境变量,windows环境可以不用管这个参数
CHROME_CHROME_PATH = "/opt/google/chrome/google-chrome"

# 如果COOKIE_TYPE=3, 则需配置RAIL_EXPIRATION、RAIL_DEVICEID的值
RAIL_EXPIRATION = ""
RAIL_DEVICEID = ""
RAIL_EXPIRATION = "1576654754825"
RAIL_DEVICEID = "iIT4N7T5eI7O26P1vMt3oCLWvjlt4O9_ONCjqrKQPkChXEhGnMWKzD7wRJdc-C_1RYHw66659vxUwVxLeyh1MBgR3nf-2sW44mLg7ZMdE2CskpVx0LBsaIjVkQBsjyNH-Gi1lb45BiGGokq_zJUkFubcmj9pSAUu"


# 1=>为一直随机ua,2->只启动的时候随机一次ua
Expand All @@ -151,4 +152,4 @@
MIN_TIME = 3

# 软件版本
RE_VERSION = "1.1.117"
RE_VERSION = "1.2.001"
16 changes: 16 additions & 0 deletions UnitTest/TestAll.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import requests

from agency.agency_tools import proxy
from agency.cdn_utils import CDNProxy
from config.emailConf import sendEmail
from config.serverchanConf import sendServerChan
from init.select_ticket_info import select


def _set_header_default():
Expand Down Expand Up @@ -98,6 +100,20 @@ def testRemoteVerfy(self):
except:
pass

def testCdn(self):
"""
测试cdn筛选
:return:
"""
CDN = CDNProxy()
all_cdn = CDN.open_cdn_file()
s = select()
all_cdn = self.open_cdn_file()
cdns = [all_cdn[i:i + 50] for i in range(0, len(all_cdn), 50)]
for i in cdns:
t = threading.Thread(target=s.cdn_req, args=(i,))
t.start()


if __name__ == '__main__':
unittest.main()
135 changes: 64 additions & 71 deletions agency/cdn_utils.py
Original file line number Diff line number Diff line change
@@ -1,88 +1,81 @@
# encoding=utf8
import collections
import json
import datetime
import os
import re
import sys
import csv
import requests
from config import urlConf
import threading
from config.urlConf import urls

try:
reload(sys)
sys.setdefaultencoding('utf-8')
except NameError:
pass
from myUrllib.httpUtils import HTTPClient

cdn_list = []

class CDNProxy:
def __init__(self, host=None):
self.host = host

class CDNProxy(threading.Thread):
def __init__(self, cdns):
super().__init__()
self.cdns = cdns
self.urlConf = urlConf.urls
self.httpClint = requests
self.city_list = []
self.timeout = 5

def _set_header(self):
"""设置header"""
return {
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"X-Requested-With": "xmlHttpRequest",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Accept": "*/*",
}
def run(self):
for cdn in self.cdns:
http = HTTPClient(0)
url = urls["loginInitCdn"]
http._cdn = cdn.replace("\n", "")
start_time = datetime.datetime.now()
rep = http.send(url)
if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 1000:
if cdn.replace("\n", "") not in cdn_list: # 如果有重复的cdn,则放弃加入
print(f"加入cdn: {cdn}")
cdn_list.append(cdn.replace("\n", ""))


def open_cdn_file(cdnFile):
cdn = []
path = os.path.join(os.path.dirname(__file__), f'../{cdnFile}')
try:
with open(path, "r", encoding="utf-8") as f:
for i in f.readlines():
if i and "kyfw.12306.cn:443" not in i:
cdn.append(i.replace("\n", ""))
return cdn
except Exception:
with open(path, "r") as f:
for i in f.readlines():
if i and "kyfw.12306.cn:443" not in i:
cdn.append(i.replace("\n", ""))
return cdn


def filterCdn():
"""
过滤cdn, 过滤逻辑为当前cdn响应值小于1000毫秒
过滤日志:
加入cdn: 116.77.75.146
:return:
"""
cdns = open_cdn_file("cdn_list")
cdnss = [cdns[i:i + 50] for i in range(0, len(cdns), 50)]
cdnThread = []
for cdn in cdnss:
t = CDNProxy(cdn)
cdnThread.append(t)
for cdn_t in cdnThread:
cdn_t.start()

def get_city_id(self):
"""
获取所有城市md5参数
:return:
"""
try:
if self.host:
while True:
url = self.urlConf["cdn_host"]["req_url"]
data = {"host": self.host, "lintType": "电信,多线,联通,移动"}
rep = self.httpClint.post(url, data, headers=self._set_header(), timeout=self.timeout)
city_re = re.compile(r"<li id=\"(\S+)\" class=\"PingListCent PingRLlist")
self.city_list = re.findall(city_re, rep.content)
if self.city_list:
print(self.city_list)
break
else:
pass
except:
pass
for cdn_j in cdnThread:
cdn_j.join()

def open_cdn_file(self):
cdn = []
# cdn_re = re.compile("CONNECT (\S+) HTTP/1.1")
# path = os.path.join(os.path.dirname(__file__), '../cdn_list')
# with open(path, "r") as f:
# for i in f.readlines():
# # print(i.replace("\n", ""))
# cdn_list = re.findall(cdn_re, i)
# if cdn_list and "kyfw.12306.cn:443" not in cdn_list:
# print(cdn_list[0].split(":")[0])
# cdn.append(cdn_list[0].split(":")[0])
# return cdn
path = os.path.join(os.path.dirname(__file__), '../cdn_list')
try:
with open(path, "r", encoding="utf-8") as f:
for i in f.readlines():
# print(i.replace("\n", ""))
if i and "kyfw.12306.cn:443" not in i:
cdn.append(i.replace("\n", ""))
return cdn
except Exception:
with open(path, "r") as f:
for i in f.readlines():
# print(i.replace("\n", ""))
if i and "kyfw.12306.cn:443" not in i:
cdn.append(i.replace("\n", ""))
return cdn
print(f"当前有效cdn个数为: {len(cdn_list)}")
if cdn_list:
f = open(r"../filter_cdn_list", "a+")
for c in cdn_list:
f.writelines(f"{c}\n")
f.close()


if __name__ == '__main__':
cdn = CDNProxy()
print(cdn.open_cdn_file())
filterCdn()
Loading

0 comments on commit 9d70f83

Please sign in to comment.