From 542db361b227d56b40484772600031d4977d22d7 Mon Sep 17 00:00:00 2001 From: AaronJny Date: Tue, 8 Jan 2019 14:18:37 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AF=B9linux=E7=9A=84=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=81=9A=E4=BA=86=E7=89=B9=E5=88=AB=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E3=80=82=201.=E4=BD=BF=E7=94=A8=20`python2=20-m=20pip?= =?UTF-8?q?=20install=20...`=E7=9A=84=E5=BD=A2=E5=BC=8F=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=8F=AF=E4=BB=A5=E9=81=BF=E5=85=8D=E5=A4=9A?= =?UTF-8?q?=E7=89=88=E6=9C=ACpython=E3=80=81pip=E4=B8=8B=E7=9A=84=E5=86=B2?= =?UTF-8?q?=E7=AA=81=E9=97=AE=E9=A2=98=EF=BC=8C=E5=90=A6=E5=88=99=E6=9C=89?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E4=BC=9A=E5=87=BA=E7=8E=B0=E5=B0=86=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=AE=89=E8=A3=85=E5=88=B0python3=E4=B8=8A=EF=BC=8C?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=97=A0=E6=B3=95=E8=BF=90=E8=A1=8C=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5=E3=80=82=202.=E5=AF=B9root=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=92=8C=E9=9D=9Eroot=E7=94=A8=E6=88=B7=E5=81=9A=E4=BA=86?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E3=80=82=E5=BD=93=E9=9D=9Eroot=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=9B=B4=E6=8E=A5=E4=BD=BF=E7=94=A8`pip=20install=20.?= =?UTF-8?q?..`=E5=91=BD=E4=BB=A4=E5=AE=89=E8=A3=85=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E4=BC=9A=E5=AE=89=E8=A3=85=E5=88=B0=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E7=94=A8=E6=88=B7=E7=9B=AE=E5=BD=95=E4=B8=8B=EF=BC=8C?= =?UTF-8?q?=E4=BD=86=E8=BF=90=E8=A1=8C=E9=A1=B9=E7=9B=AE=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E6=98=AF`sudo=20python=20run.py`=EF=BC=8C=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E7=9A=84=E6=98=AFroot=E7=94=A8=E6=88=B7=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E4=B8=8B=E7=9A=84=E4=BE=9D=E8=B5=96=EF=BC=8C=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E4=BC=9A=E5=AF=BC=E8=87=B4=E9=A1=B9=E7=9B=AE=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E5=A4=B1=E8=B4=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e335e49..d4a5660 100755 --- a/README.md +++ b/README.md @@ -5,7 +5,10 @@ - 依赖库 - 依赖若快 若快注册地址:http://www.ruokuai.com/client/index?6726 推荐用若快,打码兔平台已经关闭 - 项目依赖包 requirements.txt - - 安装方法 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt + - 安装方法-Windows: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt + - 安装方法-Linux: + - root用户(避免多python环境产生问题): python2 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt + - 非root用户(避免安装和运行时使用了不同环境): sudo python2 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt - 项目使用说明 - 需要配置邮箱,可以配置可以不配置,配置邮箱的格式在yaml里面可以看到ex From ad8066972bafdd23890cb989d89c6d4e9cad8e0f Mon Sep 17 00:00:00 2001 From: wenxianping <931128603@qq.com> Date: Tue, 8 Jan 2019 17:04:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=90=86ip?= =?UTF-8?q?=E5=8F=A3=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- UnitTest/TestAll.py | 50 ++++++++++++++++++++++++++++ UnitTest/__init__.py | 0 Update.md | 1 + agency/agency_tools.py | 44 ++++++++++++++++-------- agency/proxy_list | 1 + config/TicketEnmu.py | 4 +-- config/emailConf.py | 2 +- config/ticket_config.yaml | 31 ++++++----------- init/select_ticket_info.py | 16 +++++---- inter/GetPassCodeNewOrderAndLogin.py | 2 +- inter/GetPassengerDTOs.py | 1 + inter/GetRandCode.py | 1 + inter/Query.py | 2 +- myUrllib/httpUtils.py | 9 ++++- 15 files changed, 120 insertions(+), 47 deletions(-) create mode 100644 UnitTest/TestAll.py create mode 100644 UnitTest/__init__.py create mode 100644 agency/proxy_list diff --git a/README.md b/README.md index e335e49..9f3da75 100755 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ ![image](https://github.com/testerSunshine/12306/blob/master/uml/uml.png) - 项目声明: - - 本软件只供学习交流使用,务作为商业用途,交流群号:286271084(已满), 2群:649992274(已满),请加3群, 群号:632501142, + - 本软件只供学习交流使用,务作为商业用途,交流群号:286271084(已满), 2群:649992274(已满),请加3群(未满), 群号:632501142、4群(未满), 群号:606340519 + - 请不要重复加群,一个群就可以了,把机会留给更多人 - **进群先看公告!!!进群先看公告!!!进群先看公告!!! 重要的事情说三遍** - 能为你抢到一张回家的票,是我最大的心愿 diff --git a/UnitTest/TestAll.py b/UnitTest/TestAll.py new file mode 100644 index 0000000..17eb608 --- /dev/null +++ b/UnitTest/TestAll.py @@ -0,0 +1,50 @@ +# coding=utf-8 +import unittest +from collections import OrderedDict + +import requests + +from agency.agency_tools import proxy +from config.emailConf import sendEmail + + +def _set_header_default(): + header_dict = OrderedDict() + header_dict["Accept"] = "*/*" + header_dict["Accept-Encoding"] = "gzip, deflate" + header_dict["X-Requested-With"] = "superagent" + + header_dict[ + "User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1" + header_dict["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8" + + +class testAll(unittest.TestCase): + + def testProxy(self): + """ + 测试代理是否可用 + :return: + """ + _proxy = proxy() + proxie = _proxy.setProxy() + url = "http://httpbin.org/ip" + rsp = requests.get(url, proxies=proxie, timeout=5, headers=_set_header_default()).content + print(u"当前代理ip地址为: {}".format(rsp)) + + def testEmail(self): + """ + 实测邮箱是否可用 + :return: + """ + sendEmail("订票小助手测试一下") + + # def testConfig(self): + # """ + # 测试config是否配置正确 + # :return: + # """ + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/UnitTest/__init__.py b/UnitTest/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Update.md b/Update.md index 2842ebc..3cfceb1 100644 --- a/Update.md +++ b/Update.md @@ -133,3 +133,4 @@ - ticket_config 配置文件增加order_model字段(下单模式) - mac和linux服务器自动对点 - 增加预售踩点查询下单,经测试,误差在0.004s + diff --git a/agency/agency_tools.py b/agency/agency_tools.py index 1143d28..f82fdd0 100755 --- a/agency/agency_tools.py +++ b/agency/agency_tools.py @@ -1,4 +1,6 @@ -#encoding=utf8 +# encoding=utf8 +import os +import random import socket import time @@ -22,7 +24,7 @@ class proxy: for i in range(1, 5): time.sleep(1) - url = 'http://www.xicidaili.com/nn/'+str(i) + url = 'http://www.xicidaili.com/nn/' + str(i) res = requests.get(url=url, headers=header).content soup = BeautifulSoup(res, "html.parser") @@ -41,7 +43,8 @@ class proxy: :return: """ socket.setdefaulttimeout(1) - f = open("./proxy_list", "w") + path = os.path.join(os.path.dirname(__file__), './proxy_list') + f = open(path, "w") head = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36', 'Connection': 'keep-alive'} @@ -52,10 +55,10 @@ class proxy: try: req = requests.get(url, proxies=proxy_temp, timeout=2, headers=head).content print(req) - write_proxy = proxy+"\n" + write_proxy = proxy + "\n" f.write(write_proxy) proxy_num += 1 - except Exception, e: + except Exception: print ("代理链接超时,去除此IP:{0}".format(proxy)) continue print("总共可使用ip量为{}个".format(proxy_num)) @@ -65,18 +68,33 @@ class proxy: 读取该可用ip文件 :return: 可用ip文件list """ - f = open("./proxy_list", "r") - lins = f.readlines() - for i in lins: - p = i.strip("\n") - self.proxy_filter_list.append(p) - return self.proxy_filter_list + path = os.path.join(os.path.dirname(__file__), './proxy_list') + with open(path, "r") as f: + lins = f.readlines() + for i in lins: + p = i.strip("\n") + self.proxy_filter_list.append(p) + return self.proxy_filter_list def main(self): - self.get_proxy() + # self.get_proxy() self.filter_proxy() + def setProxy(self): + """ + 开启此功能的时候请确保代理ip是否可用 + 查询的时候设置代理ip,ip设置格式是ip地址+端口,推荐可用的ip代理池:https://github.com/jhao104/proxy_pool + :return: + """ + ip = self.get_filter_proxy() + setIp = ip[random.randint(0, len(ip) - 1)] + proxie = { + 'http': 'http://{}'.format(setIp), + 'https': 'http://{}'.format(setIp), + } + return proxie + if __name__ == "__main__": a = proxy() - a.main() \ No newline at end of file + print(a.get_filter_proxy()) diff --git a/agency/proxy_list b/agency/proxy_list new file mode 100644 index 0000000..fb30cba --- /dev/null +++ b/agency/proxy_list @@ -0,0 +1 @@ +119.101.114.196:9999 \ No newline at end of file diff --git a/config/TicketEnmu.py b/config/TicketEnmu.py index 075bc5d..d960282 100644 --- a/config/TicketEnmu.py +++ b/config/TicketEnmu.py @@ -14,8 +14,8 @@ class ticket(object): TICKET_BLACK_LIST_TIME = 5 # 加入小黑屋的等待时间,默认5 min - DTO_NOT_FOUND = u"未查找到常用联系人" - DTO_NOT_IN_LIST = u"联系人不在列表中,请查证后添加" + DTO_NOT_FOUND = u"未查找到常用联系人, 请查证后添加!!" + DTO_NOT_IN_LIST = u"联系人不在列表中,请查证后添加!!" QUEUE_TICKET_SHORT = u"当前余票数小于乘车人数,放弃订票" QUEUE_TICKET_SUCCESS = u"排队成功, 当前余票还剩余: {0}张" diff --git a/config/emailConf.py b/config/emailConf.py index a914a01..6d28d41 100755 --- a/config/emailConf.py +++ b/config/emailConf.py @@ -36,7 +36,7 @@ def sendEmail(msg): smtp.quit() print(u"邮件已通知, 请查收") except Exception as e: - print(u"邮件配置有误", e) + print(u"邮件配置有误{}".format(e)) else: pass diff --git a/config/ticket_config.yaml b/config/ticket_config.yaml index 3b09c5e..60bc001 100755 --- a/config/ticket_config.yaml +++ b/config/ticket_config.yaml @@ -30,24 +30,6 @@ set: # - "G1353" # - "G1329" station_trains: -# - "G6114" -# - "G1311" -# - "G6201" -# - "G821" -# - "G1019" -# - "G6587" -# - "G2905" -# - "G6345" -# - "G6033" -# - "G75" -# - "G6025" -# - "G6341" -# - "G1021" -# - "G99" -# - "G6011" -# - "D2972" -# - "D1874" -# - "D2834" - "G6172" - "G6186" - "G6154" @@ -76,14 +58,14 @@ set: # - "梁敏" # 12306登录账号(list) 12306account: - - user: "931128603@qq.com" + - user: "13828728396" - pwd: "" -# 加入小黑屋时间,此功能为了防止僵尸票导致一直下单不成功错过正常的票 +# 加入小黑屋时间默认为5分钟,此功能为了防止僵尸票导致一直下单不成功错过正常的票, ticket_black_list_time: 5 # 自动打码 -is_auto_code: False +is_auto_code: True # 打码平台, 2 为若快平台(目前只支持若快平台打码,打码兔已经关闭), 若快注册地址:http://www.ruokuai.com/client/index?6726 auto_code_type: 2 @@ -127,5 +109,12 @@ order_model: 2 # 预售放票时间, 如果是捡漏模式,可以忽略此操作 open_time: '13:00:00' +# 是否开启代理, 0代表关闭, 1表示开始 +# 开启此功能的时候请确保代理ip是否可用,在测试放里面经过充分的测试,再开启此功能,不然可能会耽误你购票的宝贵时间 +# 使用方法: +# 1、在agency/proxy_list列表下填入代理ip +# 2、测试UnitTest/TestAll/testProxy 测试代理是否可以用 +# 3、开启代理ip +is_proxy: 0 diff --git a/init/select_ticket_info.py b/init/select_ticket_info.py index a709e2d..f9aa0a3 100755 --- a/init/select_ticket_info.py +++ b/init/select_ticket_info.py @@ -47,11 +47,11 @@ class select: self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, \ self.ticke_peoples, self.station_trains, self.ticket_black_list_time, \ self.order_type, self.is_by_time, self.train_types, self.departure_time, \ - self.arrival_time, self.take_time, self.order_model, self.open_time = self.get_ticket_info() + self.arrival_time, self.take_time, self.order_model, self.open_time, self.is_proxy = self.get_ticket_info() self.is_auto_code = _get_yaml()["is_auto_code"] self.auto_code_type = _get_yaml()["auto_code_type"] self.is_cdn = _get_yaml()["is_cdn"] - self.httpClint = HTTPClient() + self.httpClint = HTTPClient(self.is_proxy) self.urls = urlConf.urls self.login = GoLogin(self, self.is_auto_code, self.auto_code_type) self.cdn_list = [] @@ -88,8 +88,12 @@ class select: order_model = ticket_info_config["order_model"] open_time = ticket_info_config["open_time"] + # 代理模式 + is_proxy = ticket_info_config["is_proxy"] + print(u"*" * 50) - print(u"12306刷票小助手,最后更新于2019.01.07,请勿作为商业用途,交流群号:286271084(已满), 2群:649992274(已满),请加3群,群号:632501142") + print(u"检查当前python版本为:{},目前版本只支持2.7.10-2.7.15".format(sys.version.split(" ")[0])) + print(u"12306刷票小助手,最后更新于2019.01.08,请勿作为商业用途,交流群号:286271084(已满), 2群:649992274(已满),请加3群(未满), 群号:632501142、4群(未满), 群号:606340519") if is_by_time: method_notie = u"购票方式:根据时间区间购票\n可接受最早出发时间:{0}\n可接受最晚抵达时间:{1}\n可接受最长旅途时间:{2}\n可接受列车类型:{3}\n" \ .format(minutes_to_time(departure_time), minutes_to_time(arrival_time), minutes_to_time(take_time), @@ -97,7 +101,7 @@ class select: else: method_notie = u"购票方式:根据候选车次购买\n候选购买车次:{0}".format(",".join(station_trains)) print (u"当前配置:\n出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票优先提交:{4}\n乘车人:{5}\n" \ - u"刷新间隔: 随机(1-3S)\n{6}\n僵尸票关小黑屋时长: {7}\n下单接口: {8}\n下单模式: {9}\n预售踩点时间:{10} ".format \ + u"刷新间隔: 随机(1-3S)\n{6}\n僵尸票关小黑屋时长: {7}\n下单接口: {8}\n下单模式: {9}\n预售踩点时间:{10} ".format \ ( from_station, to_station, @@ -114,7 +118,7 @@ class select: print (u"*" * 50) return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, station_trains, \ ticket_black_list_time, order_type, is_by_time, train_types, departure_time, arrival_time, take_time, \ - order_model, open_time + order_model, open_time, is_proxy def station_table(self, from_station, to_station): """ @@ -146,7 +150,7 @@ class select: def cdn_req(self, cdn): for i in range(len(cdn) - 1): - http = HTTPClient() + http = HTTPClient(0) urls = self.urls["loginInitCdn"] http._cdn = cdn[i].replace("\n", "") start_time = datetime.datetime.now() diff --git a/inter/GetPassCodeNewOrderAndLogin.py b/inter/GetPassCodeNewOrderAndLogin.py index 26c17c1..551e357 100644 --- a/inter/GetPassCodeNewOrderAndLogin.py +++ b/inter/GetPassCodeNewOrderAndLogin.py @@ -22,7 +22,7 @@ def getPassCodeNewOrderAndLogin(session, imgType): result = session.httpClint.send(codeImgUrl) try: if isinstance(result, dict): - print(u"下载验证码失败, 请手动检查是否ip被封,或者重试,请求地址:https://kyfw.12306.cn/{}".format(codeImgUrl.get("req_url"))) + print(u"下载验证码失败, 请手动检查是否ip被封,或者重试,请求地址:https://kyfw.12306.cn{}".format(codeImgUrl.get("req_url"))) return False else: print(u"下载验证码成功") diff --git a/inter/GetPassengerDTOs.py b/inter/GetPassengerDTOs.py index 02f52ba..3a402d7 100644 --- a/inter/GetPassengerDTOs.py +++ b/inter/GetPassengerDTOs.py @@ -38,6 +38,7 @@ class getPassengerDTOs: elif getPassengerDTOsResult.get('messages', False): print(getPassengerDTOsResult.get('messages', False)) else: + print(getPassengerDTOsResult) raise PassengerUserException(ticket.DTO_NOT_FOUND) def getPassengerTicketStr(self, set_type): diff --git a/inter/GetRandCode.py b/inter/GetRandCode.py index f65edff..5660174 100644 --- a/inter/GetRandCode.py +++ b/inter/GetRandCode.py @@ -53,6 +53,7 @@ def codexy(Ofset=None, is_raw_input=True): """) print(u"验证码分为8个,对应上面数字,例如第一和第二张,输入1, 2 如果开启cdn查询的话,会冲掉提示,直接鼠标点击命令行获取焦点,输入即可,不要输入空格") print(u"如果是linux无图形界面,请使用自动打码,is_auto_code: True") + print(u"如果没有弹出验证码,请手动双击根目录下的tkcode.png文件") Ofset = raw_input(u"输入对应的验证码: ") Ofset = Ofset.replace(",", ",") select = Ofset.split(',') diff --git a/inter/Query.py b/inter/Query.py index 91a7442..6205436 100644 --- a/inter/Query.py +++ b/inter/Query.py @@ -21,7 +21,7 @@ class query: def __init__(self, session, from_station, to_station, from_station_h, to_station_h, _station_seat, station_trains, ticke_peoples_num, station_dates=None, ): self.session = session - self.httpClint = HTTPClient() + self.httpClint = HTTPClient(session.is_proxy) self.urls = urlConf.urls self.from_station = from_station self.to_station = to_station diff --git a/myUrllib/httpUtils.py b/myUrllib/httpUtils.py index 879dcd8..7ce6183 100755 --- a/myUrllib/httpUtils.py +++ b/myUrllib/httpUtils.py @@ -4,6 +4,8 @@ import socket from collections import OrderedDict from time import sleep import requests + +from agency.agency_tools import proxy from config import logger @@ -19,7 +21,7 @@ def _set_header_default(): class HTTPClient(object): - def __init__(self): + def __init__(self, is_proxy): """ :param method: :param headers: Must be a dict. Such as headers={'Content_Type':'text/html'} @@ -27,6 +29,10 @@ class HTTPClient(object): self.initS() self._cdn = None self._proxies = None + if is_proxy is 1: + self.proxy = proxy() + self._proxies = self.proxy.setProxy() + # print(u"设置当前代理ip为 {}, 请注意代理ip是否可用!!!!!请注意代理ip是否可用!!!!!请注意代理ip是否可用!!!!!".format(self._proxies)) def initS(self): self._s = requests.Session() @@ -134,6 +140,7 @@ class HTTPClient(object): pass response = self._s.request(method=method, timeout=2, + proxies=self._proxies, url="https://" + url_host + req_url, data=data, allow_redirects=allow_redirects,