16 Commits

Author SHA1 Message Date
xiaohanfei
5f6541c521 12306登录时不再请求httpZF这个url 2018-01-29 14:08:55 +08:00
xiaohanfei
89a7cae001 修复自动验证码登录问题 2018-01-25 14:35:29 +08:00
xiaohanfei
f2f87ac10f bug fix 2018-01-23 11:45:12 +08:00
xiaohanfei
5e0a435c3e bug fix 2018-01-23 11:44:19 +08:00
xiaohanfei
8bfd3864c3 python3版本更新,优化请求模式,重构登录 2018-01-22 23:04:22 +08:00
xiaohanfei
69df1ac189 merge python2 2018-01-16 19:18:03 +08:00
xiaohanfei
95354cefd8 bug fix 2018-01-16 14:17:18 +08:00
xiaohanfei
2b0580e20c 区分yaml 2018-01-13 22:53:24 +08:00
xiaohanfei
5a9f095319 区分yaml.conf 2018-01-13 22:36:45 +08:00
xiaohanfei
0ffbe102e2 区分yaml.conf 2018-01-13 22:33:31 +08:00
wenxianping
aa599d7d70 fix 2018-01-12 21:00:20 +08:00
wenxianping
62f1785203 Merge remote-tracking branch 'origin/python3' into python3
# Conflicts:
#	.idea/workspace.xml
#	config/ticket_config.yaml
2018-01-12 20:59:38 +08:00
wenxianping
4d68360a24 fix 2018-01-12 20:59:09 +08:00
xiaohanfei
8b78cab389 update 2018-01-12 20:15:24 +08:00
xiaohanfei
c1b572d9ec update README.md 2018-01-12 19:55:56 +08:00
xiaohanfei
0747e2b01a buy ticket for python3 2018-01-12 19:46:47 +08:00
23 changed files with 1716 additions and 428 deletions

51
.idea/workspace.xml generated
View File

@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="79a86edc-721f-4aad-920d-b595d0348b7f" name="Default" comment="跳出下单循环">
<list default="true" id="79a86edc-721f-4aad-920d-b595d0348b7f" name="Default" comment="fix">
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/config/ticket_config.yaml" afterPath="$PROJECT_DIR$/config/ticket_config.yaml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/init/select_ticket_info.py" afterPath="$PROJECT_DIR$/init/select_ticket_info.py" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
@@ -99,8 +98,8 @@
<file leaf-file-name="ticket_config.yaml" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/config/ticket_config.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="626">
<caret line="60" column="9" lean-forward="false" selection-start-line="60" selection-start-column="9" selection-end-line="60" selection-end-column="9" />
<state relative-caret-position="228">
<caret line="48" column="15" lean-forward="false" selection-start-line="48" selection-start-column="15" selection-end-line="48" selection-end-column="15" />
<folding />
</state>
</provider>
@@ -173,7 +172,7 @@
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="c114077926c834ce85e64f9fc2620185dcf196ac" />
<entry key="$PROJECT_DIR$" value="master" />
</map>
</option>
</component>
@@ -821,7 +820,21 @@
<option name="project" value="LOCAL" />
<updated>1515736276438</updated>
</task>
<option name="localTasksCounter" value="23" />
<task id="LOCAL-00023" summary="跳出下单循环">
<created>1515739350489</created>
<option name="number" value="00023" />
<option name="presentableId" value="LOCAL-00023" />
<option name="project" value="LOCAL" />
<updated>1515739350490</updated>
</task>
<task id="LOCAL-00024" summary="fix">
<created>1515750040458</created>
<option name="number" value="00024" />
<option name="presentableId" value="LOCAL-00024" />
<option name="project" value="LOCAL" />
<updated>1515750040458</updated>
</task>
<option name="localTasksCounter" value="25" />
<servers />
</component>
<component name="ToolWindowManager">
@@ -836,7 +849,7 @@
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.47922438" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.54413545" sideWeight="0.49570817" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24964234" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32889965" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32889965" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3297568" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.7315599" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Data View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3297568" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
@@ -917,13 +930,13 @@
<MESSAGE value="优化订购车票流程" />
<MESSAGE value="1、12306接口无响应的时候给出合理提示&#10;2、优化订票排队时间" />
<MESSAGE value="更改冗余目录结构" />
<MESSAGE value="fix" />
<MESSAGE value="更改车次提示不间断" />
<MESSAGE value="修改提交需要验证码逻辑" />
<MESSAGE value="提交验证码拉去类别问题" />
<MESSAGE value="增加提交订单验证码校验" />
<MESSAGE value="跳出下单循环" />
<option name="LAST_COMMIT_MESSAGE" value="跳出下单循环" />
<MESSAGE value="fix" />
<option name="LAST_COMMIT_MESSAGE" value="fix" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
@@ -1099,14 +1112,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/requirements.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="70">
<caret line="5" column="6" lean-forward="false" selection-start-line="5" selection-start-column="0" selection-end-line="5" selection-end-column="6" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/init/select_ticket_info.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="214">
@@ -1118,10 +1123,18 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/requirements.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="70">
<caret line="5" column="6" lean-forward="false" selection-start-line="5" selection-start-column="0" selection-end-line="5" selection-end-column="6" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/config/ticket_config.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="626">
<caret line="60" column="9" lean-forward="false" selection-start-line="60" selection-start-column="9" selection-end-line="60" selection-end-column="9" />
<state relative-caret-position="228">
<caret line="48" column="15" lean-forward="false" selection-start-line="48" selection-start-column="15" selection-end-line="48" selection-end-column="15" />
<folding />
</state>
</provider>

View File

@@ -1,7 +1,7 @@
### 12306
- python版本支持
- 2.7
- 2.7 3.0+
- 依赖库
- 依赖打码兔 需要去打码兔注册账号打码兔账号地址http://www.dama2.com一般充值1元就够用了
- 项目依赖包 requirements.txt
@@ -71,3 +71,6 @@
- 优化查票流程
- 修改二等座的余票数返回为字符串的问题
- 优化订单查询bug
- 2018.1.12 更新
- python3 版本支持python3的同学请切换至python3分支

View File

@@ -1,7 +1,7 @@
#encoding=utf8
import socket
import urllib
import urllib2
import urllib.request, urllib.parse, urllib.error
import urllib.request, urllib.error, urllib.parse
from bs4 import BeautifulSoup
@@ -21,8 +21,8 @@ class proxy:
for i in range(1, 5):
url = 'http://www.xicidaili.com/nn/'+str(i)
req = urllib2.Request(url, headers=header)
res = urllib2.urlopen(req).read()
req = urllib.request.Request(url, headers=header)
res = urllib.request.urlopen(req).read()
soup = BeautifulSoup(res, "html.parser")
ips = soup.findAll('tr')
@@ -45,15 +45,15 @@ class proxy:
for proxy in self.proxy_list:
proxy_temp = {"http://": proxy}
try:
urllib.urlopen(url, proxies=proxy_temp).read()
urllib.request.urlopen(url, proxies=proxy_temp).read()
write_proxy = proxy+"\n"
f.write(write_proxy)
proxy_num += 1
except Exception, e:
print ("代理链接超时去除此IP{0}".format(proxy))
print e
except Exception as e:
print(("代理链接超时去除此IP{0}".format(proxy)))
print(e)
continue
print("总共可使用ip量为{}".format(proxy_num))
print(("总共可使用ip量为{}".format(proxy_num)))
def get_filter_proxy(self):
"""

View File

@@ -0,0 +1,77 @@
#encoding=utf8
import socket
import urllib
import urllib2
from bs4 import BeautifulSoup
class proxy:
def __init__(self):
self.proxy_list = []
self.proxy_filter_list = []
def get_proxy(self):
"""
获取未加工代理列表
:return:
"""
User_Agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0'
header = {}
header['User-Agent'] = User_Agent
for i in range(1, 5):
url = 'http://www.xicidaili.com/nn/'+str(i)
req = urllib2.Request(url, headers=header)
res = urllib2.urlopen(req).read()
soup = BeautifulSoup(res, "html.parser")
ips = soup.findAll('tr')
for x in range(1, len(ips)):
ip = ips[x]
tds = ip.findAll("td")
ip_temp = tds[1].contents[0] + ":" + tds[2].contents[0]
self.proxy_list.append(ip_temp)
def filter_proxy(self):
"""
将不可用IP剔除
:return:
"""
socket.setdefaulttimeout(1)
f = open("./proxy_list", "w")
url = "http://ip.chinaz.com/getip.aspx"
proxy_num = 0
for proxy in self.proxy_list:
proxy_temp = {"http://": proxy}
try:
urllib.urlopen(url, proxies=proxy_temp).read()
write_proxy = proxy+"\n"
f.write(write_proxy)
proxy_num += 1
except Exception, e:
print ("代理链接超时去除此IP{0}".format(proxy))
print e
continue
print("总共可使用ip量为{}".format(proxy_num))
def get_filter_proxy(self):
"""
读取该可用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
def main(self):
self.get_proxy()
self.filter_proxy()
if __name__ == "__main__":
a = proxy()
a.get_filter_proxy()

46
config/emailConf.py Normal file
View File

@@ -0,0 +1,46 @@
# -*- coding: utf8 -*-
__author__ = 'MR.wen'
from email.header import Header
from email.mime.text import MIMEText
from config.ticketConf import _get_yaml
import smtplib
class email:
def __init__(self,*args):
self.msg = args[0]
self.ticket_config = args[1]
def sendEmail(self):
"""
邮件通知
:param str: email content
:return:
"""
email_conf = _get_yaml(self.ticket_config)
is_email = email_conf["email_conf"]["is_email"]
if is_email:
sender = email_conf["email_conf"]["email"]
receiver = email_conf["email_conf"]["notice_email_list"]
subject = '恭喜,您已订票成功'
username = email_conf["email_conf"]["username"]
password = email_conf["email_conf"]["password"]
host = email_conf["email_conf"]["host"]
s = "{0}".format(self.msg)
msg = MIMEText(s, 'text', 'utf-8') # 中文需参数utf-8单字节字符不需要
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = sender
msg['To'] = receiver
smtp = smtplib.SMTP_SSL()
smtp.connect(host)
smtp.login(username, password)
smtp.sendmail(sender, receiver.split(","), msg.as_string())
smtp.quit()
print("邮件已通知, 请查收")
else:
pass
if __name__ == '__main__':
email.sendEmail()

View File

@@ -3,20 +3,20 @@ __author__ = 'MR.wen'
import os
import yaml
import codecs
def _get_yaml():
def _get_yaml(ticket_config):
"""
解析yaml
:return: s 字典
"""
path = os.path.join(os.path.dirname(__file__) + '/ticket_config.yaml')
f = open(path)
path = os.path.join(os.path.dirname(__file__) + '/'+ticket_config)
f = codecs.open(path,encoding='utf-8')
s = yaml.load(f)
f.close()
return s
# def get_set_info():
# return _get_yaml()["set"]
#

View File

@@ -23,10 +23,9 @@
#damatu打码兔账号用于自动登录
#is_aotu_code是否自动打码如果选择Ture,则调用打码兔打码,默认不使用打码兔
set:
station_date: "2018-02-10"
station_date: "2018-02-21"
station_trains:
- "T17"
- "T297"
- "Z42"
# - "G2365"
# - "G1371"
# - "G1377"
@@ -37,19 +36,20 @@ set:
# - "G1373"
# - "G1363"
# - "G4933"
from_station: "北京"
to_station: "牡丹江"
from_station: "嘉峪关"
to_station: "上海"
set_type:
- "硬卧"
is_more_ticket: True
ticke_peoples:
- ""
- "xxx"
- ""
12306count:
# - uesr: ""
# - uesr: "11"
# - pwd: "649823049lilymin"
- uesr: "@qq.com"
- pwd: "QWERTY"
- uesr: "*"
- pwd: "***"
select_refresh_interval: 0.1
expect_refresh_interval: 0.3
@@ -58,8 +58,14 @@ is_aotu_code: False
#enable_proxy: False
damatu:
uesr: ""
uesr: "***"
pwd: "wen1995"
email_conf:
is_email: True
email: "***@163.com"
notice_email_list: "***@163.com"
username: "***"
password: "****"
host: "smtp.163.com"

View File

@@ -28,7 +28,7 @@ class DamatuApi():
self.file_path = file_path
def getSign(self, param=b''):
return (md5(bytes(self.KEY) + bytes(self.username) + param))[:8]
return (md5(self.KEY.encode(encoding="utf-8") + self.username.encode(encoding="utf-8") + param))[:8]
def getPwd(self):
return md5str(self.KEY + md5str(md5str(self.username) + md5str(self.password)))
@@ -47,7 +47,7 @@ class DamatuApi():
'sign': self.getSign()
}
res = self.post('d2Balance', data)
res = str(res)
res = res.decode(encoding="utf-8")
jres = json.loads(res)
if jres['ret'] == 0:
return jres['balance']
@@ -68,7 +68,7 @@ class DamatuApi():
'sign': self.getSign(fdata)
}
res = self.post('d2File', data)
res = str(res)
res = res.decode(encoding='utf-8')
jres = json.loads(res)
if jres['ret'] == 0:
# 注意这个json里面有retidresultcookie根据自己的需要获取
@@ -124,4 +124,3 @@ class DamatuApi():
# print(dmt.decode('tkcode', 287)) # 上传打码
# # print(dmt.decodeUrl('https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&0.7586344633015405', 310)) # 上传打码
# # print(dmt.reportError('894657096')) # 上报错误

18
init/gol.py Normal file
View File

@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
def _init():#初始化
global _global_dict
_global_dict = {}
def set_value(key,value):
""" 定义一个全局变量 """
_global_dict[key] = value
def get_value(key,defValue=None):
""" 获得一个全局变量,不存在则返回默认值 """
try:
return _global_dict[key]
except KeyError:
return defValue

View File

@@ -8,197 +8,262 @@ from time import sleep
from config.ticketConf import _get_yaml
from PIL import Image
from damatuCode.damatuWeb import DamatuApi
from myUrllib import myurllib2
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&%s' % random.random()
import requests
from init import gol
def cookietp():
stoidinput("获取Cookie")
Url = "https://kyfw.12306.cn/otn/login/init"
myurllib2.get(Url)
# for index, c in enumerate(myurllib2.cookiejar):
# stoidinput(c)
class go_login:
def __init__(self,ticket_config = ""):
self.captcha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&%s' % random.random()
self.ticket_config = ticket_config
self.text = ""
self.user = _get_yaml(ticket_config)["set"]["12306count"][0]["uesr"]
self.passwd = _get_yaml(ticket_config)["set"]["12306count"][1]["pwd"]
self.s = self.create_session()
def create_session(self):
s = requests.Session()
return s
def readImg():
"""
增加手动打码,只是登录接口,完全不用担心提交订单效率
思路
1.调用PIL显示图片
2.图片位置说明验证码图片中每个图片代表一个下标依次类推12345678
3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码,
:return:
"""
def get_logincookies(self):
global login_cookies,randCode
init_url = "https://kyfw.12306.cn/otn/login/init"
uamtk_data = {'appid': 'otn'}
#httpZF_url = "https://kyfw.12306.cn/otn/HttpZF/logdevice?algID=i8UYSfDgWt&hashCode=td9I6c9a9k73Jv8Nc2ie0FGZWit-S-0MQJfASXNUQmk&FMQw=0&q4f3=zh-CN&VySQ=FGFKKeD8kVn5VC6vc-6l42-GJzul0oeM&VPIf=1&custID=133&VEek=unknown&dzuS=0&yD16=0&EOQP=c227b88b01f5c513710d4b9f16a5ce52&lEnu=2886927661&jp76=e237f9703f53d448d77c858b634154a5&hAqN=MacIntel&platform=WEB&ks0Q=b9a555dce60346a48de933b3e16ebd6e&TeRS=877x1440&tOHY=24xx900x1440&Fvje=i1l1o1s1&q5aJ=-8&wNLf=99115dfb07133750ba677d055874de87&0aew=Mozilla/5.0%20(Macintosh;%20Intel%20Mac%20OS%20X%2010_13_2)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/63.0.3239.132%20Safari/537.36&E3gR=ea438f8fd5bf8a3ac1fe9bd188f2c823&timestamp=1516195328849"
captcha_check_url = "https://kyfw.12306.cn/passport/captcha/captcha-check"
uamtk_url = "https://kyfw.12306.cn/passport/web/auth/uamtk"
login_url = "https://kyfw.12306.cn/passport/web/login"
login_userLogin = "https://kyfw.12306.cn/otn/login/userLogin"
#userLogin = "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin"
uamauthclient = "https://kyfw.12306.cn/otn/uamauthclient"
self.s.get(init_url,verify=False)
self.s.post(uamtk_url,data=uamtk_data,verify=False)
#content = self.s.get(httpZF_url, verify=False).content
#content = content.decode(encoding='utf-8').split("'")[1]
#d = json.loads(content)
#requests.utils.add_dict_to_cookiejar(self.s.cookies, {"RAIL_DEVICEID" : d['dfp']})
#requests.utils.add_dict_to_cookiejar(self.s.cookies, {"RAIL_DEVICEID": 'XHe6FfHQKdYj65DI8SswKR16VuCcV5nT8G62Uyj0uiGpChNOindm0SNWaPvgL2_obrOdD22vuuZf1WmTDAERbW1IRBdpJVAaKYA8Ks9FOVufsrLZ2ccVy3g5XdNQIyXrjmk-psvlj7TSvHrcpUVcvlQd2cn5qEp7'})
#requests.utils.add_dict_to_cookiejar(self.s.cookies, {"RAIL_EXPIRATION" : d['exp']})
requests.utils.add_dict_to_cookiejar(self.s.cookies, {"_jc_save_fromDate": '2018-01-27'})
requests.utils.add_dict_to_cookiejar(self.s.cookies, {"_jc_save_toStation": '%u5170%u5DDE%u897F%2CLAJ'})
requests.utils.add_dict_to_cookiejar(self.s.cookies, {"_jc_save_toDate": '2018-01-22'})
requests.utils.add_dict_to_cookiejar(self.s.cookies, {"_jc_save_wfdc_flag": 'dc'})
requests.utils.add_dict_to_cookiejar(self.s.cookies, {"_jc_save_fromStation": '%u4E0A%u6D77%u8679%u6865%2CAOH'})
randCode = self.get_randcode()
randdata ={"answer":randCode,
"login_site":"E",
"rand":"sjrand"}
login_data = {"username":self.user,
"password":self.passwd,
"appid":"otn"}
rand_result = self.s.post(captcha_check_url, data=randdata, verify=False).json()
print(rand_result)
while rand_result['result_code'] is not '4' :
randCode = self.get_randcode()
randdata = {"answer": randCode,
"login_site": "E",
"rand": "sjrand"}
rand_result = self.s.post(captcha_check_url, data=randdata, verify=False).json()
print(rand_result)
global randCode
stoidinput("下载验证码...")
img_path = './tkcode'
result = myurllib2.get(codeimg)
try:
open(img_path, 'wb').write(result)
if _get_yaml()["is_aotu_code"]:
randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main()
else:
img = Image.open('./tkcode')
img.show()
codexy()
except OSError as e:
print (e)
pass
login_result = self.s.post(login_url, allow_redirects=False, data=login_data, verify=False)
login_code = login_result.status_code
print(login_code)
#解决登录接口302重定向问题
while login_code == 302 :
login_result = self.s.post(login_url, allow_redirects=False, data=login_data, verify=False)
login_code = login_result.status_code
if login_code == 200 :
print(login_result.json())
login_userLogin_data = {'_json_att' : ''}
self.s.post(login_userLogin, data=login_userLogin_data, verify=False)
uamtk_result = self.s.post(uamtk_url, allow_redirects=False, data=uamtk_data, verify=False)
while uamtk_result.status_code == 302 :
uamtk_result = self.s.post(uamtk_url, allow_redirects=False, data=uamtk_data, verify=False)
uamtk_result = uamtk_result.json()
uamauthclient_data = {'tk': uamtk_result['newapptk']}
uamauthclient_result = self.s.post(uamauthclient, data=uamauthclient_data, verify=False).json()
print(uamauthclient_result)
login_cookies = self.s.cookies.get_dict()
return login_cookies
def stoidinput(text):
"""
正常信息输出
:param text:
:return:
"""
print "\033[34m[*]\033[0m %s " % text
def get_randcode(self):
self.stoidinput("下载验证码...")
img_path = './tkcode'
r = self.s.get(self.captcha_url, verify=False)
result = r.content
# print(result)
try:
open(img_path, 'wb').write(result)
if _get_yaml(self.ticket_config)["is_aotu_code"]:
randCode = DamatuApi(_get_yaml(self.ticket_config)["damatu"]["uesr"],
_get_yaml(self.ticket_config)["damatu"]["pwd"], img_path).main()
def errorinput(text):
"""
错误信息输出
:param text:
:return:
"""
print "\033[32m[!]\033[0m %s " % text
return False
def codexy():
"""
获取验证码
:return: str
"""
Ofset = raw_input("[*] 请输入验证码: ")
select = Ofset.split(',')
global randCode
post = []
offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题
offsetsY = 0 # 选择的答案的top值
for ofset in select:
if ofset == '1':
offsetsY = 46
offsetsX = 42
elif ofset == '2':
offsetsY = 46
offsetsX = 105
elif ofset == '3':
offsetsY = 45
offsetsX = 184
elif ofset == '4':
offsetsY = 48
offsetsX = 256
elif ofset == '5':
offsetsY = 36
offsetsX = 117
elif ofset == '6':
offsetsY = 112
offsetsX = 115
elif ofset == '7':
offsetsY = 114
offsetsX = 181
elif ofset == '8':
offsetsY = 111
offsetsX = 252
else:
else:
img = Image.open('./tkcode')
img.show()
randCode = self.codexy()
except OSError as e:
print(e)
pass
post.append(offsetsX)
post.append(offsetsY)
randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '')
print(randCode)
return randCode
# def cookietp(self):
# global initcookies
# self.stoidinput("获取Cookie")
# Url = "https://kyfw.12306.cn/otn/login/init"
# initcookies1 = myurllib2.myrequests(cookies=None).get(Url).cookies
# initcookies1 = initcookies1.get_dict()
# #initcookies['current_captcha_type'] = "Z"
# print(initcookies1)
# uamtk_url = "https://kyfw.12306.cn/passport/web/auth/uamtk"
# uamtk_data = {'appid':'otn'}
# initcookies2 = myurllib2.myrequests(cookies=initcookies1).post(uamtk_url,data=uamtk_data).cookies
# initcookies2 = initcookies2.get_dict()
# print(initcookies2)
# captcha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&%s' % random.random()
# initcookies3 = myurllib2.myrequests(cookies=None).get(captcha_url).cookies
# initcookies3 = initcookies3.get_dict()
# initcookies = dict(initcookies3, **initcookies2,**initcookies1)
# print(initcookies3)
# print(initcookies)
# return initcookies
# for index, c in enumerate(myurllib2.cookiejar):
# stoidinput(c)
def login(user, passwd):
"""
登陆
:param user: 账户名
:param passwd: 密码
:return:
"""
login_num = 0
while True:
cookietp()
readImg()
login_num += 1
randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn'
logurl = 'https://kyfw.12306.cn/otn/login/loginAysnSuggest'
surl = 'https://kyfw.12306.cn/otn/login/userLogin'
randdata = {
"randCode": randCode,
"rand": "sjrand"
}
logdata = {
"loginUserDTO.user_name": user,
"userDTO.password": passwd,
"randCode": randCode
}
ldata = {
"_json_att": None
}
fresult = json.loads(myurllib2.Post(randurl, randdata), encoding='utf8')
checkcode = fresult['data']['msg']
if checkcode == 'FALSE':
errorinput("验证码有误,第{}次尝试重试".format(login_num))
# def readImg(self):
# """
# 增加手动打码,只是登录接口,完全不用担心提交订单效率
# 思路
# 1.调用PIL显示图片
# 2.图片位置说明验证码图片中每个图片代表一个下标依次类推12345678
# 3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码,
# :return:
# """
#
# #global randCode
# self.stoidinput("下载验证码...")
# img_path = './tkcode'
# r = s.get(self.captcha_url, verify=False)
# captcha_cookie = r.cookies.get_dict()
# result = r.content
# #print(result)
# try:
# open(img_path, 'wb').write(result)
# if _get_yaml(self.ticket_config)["is_aotu_code"]:
# #print(_get_yaml(self.ticket_config)["damatu"]["uesr"])
# randCode = DamatuApi(_get_yaml(self.ticket_config)["damatu"]["uesr"], _get_yaml(self.ticket_config)["damatu"]["pwd"], img_path).main()
# else:
# img = Image.open('./tkcode')
# img.show()
# self.codexy()
# except OSError as e:
# print (e)
# pass
# return randCode
def stoidinput(self,text):
"""
正常信息输出
:param text:
:return:
"""
print("\033[34m[*]\033[0m %s " % text)
def errorinput(self,text):
"""
错误信息输出
:param text:
:return:
"""
print("\033[32m[!]\033[0m %s " % text)
return False
def codexy(self):
"""
获取验证码
:return: str
"""
global randCode
Ofset = input("[*] 请输入验证码: ")
select = Ofset.split(',')
#global randCode
post = []
offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题
offsetsY = 0 # 选择的答案的top值
for ofset in select:
if ofset == '1':
offsetsY = 41
offsetsX = 39
elif ofset == '2':
offsetsY = 44
offsetsX = 110
elif ofset == '3':
offsetsY = 49
offsetsX = 184
elif ofset == '4':
offsetsY = 45
offsetsX = 253
elif ofset == '5':
offsetsY = 116
offsetsX = 39
elif ofset == '6':
offsetsY = 113
offsetsX = 110
elif ofset == '7':
offsetsY = 120
offsetsX = 184
elif ofset == '8':
offsetsY = 121
offsetsX = 257
else:
pass
post.append(offsetsX)
post.append(offsetsY)
randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '')
return randCode
def login(self):
self.get_logincookies()
gol._init()
gol.set_value('s',self.s)
#
# def getUserinfo(self):
# """
# 登录成功后,显示用户名
# :return:
# """
# url = 'https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfo'
# data = dict(_json_att=None)
# #result = myurllib2.myrequests().post(url, data).decode('utf-8')
# result = self.s.post(url,data=data,verify=False).content
# userinfo = result
# name = r'<input name="userDTO.loginUserDTO.user_name" style="display:none;" type="text" value="(\S+)" />'
# try:
# self.stoidinput("欢迎 %s 登录" % re.search(name, result).group(1))
# except AttributeError:
# pass
def logout(self):
url = 'https://kyfw.12306.cn/otn/login/loginOut'
result = self.s.get(url, verify=False).json()
if result:
self.stoidinput("已退出")
else:
stoidinput("验证码通过,开始登录..")
sleep(1)
try:
tresult = json.loads(myurllib2.Post(logurl, logdata), encoding='utf8')
if 'data' not in tresult:
errorinput("登录失败: %s" % tresult['messages'][0])
# elif "messages" in tresult and tresult["messages"][0].find("密码输入错误") is not -1:
# errorinput("登陆失败:{}".format(tresult["messages"][0]))
# break
elif 'messages' in tresult and tresult['messages']:
messages = tresult['messages'][0]
if messages.find("密码输入错误") is not -1:
errorinput("登陆失败:{}".format(tresult["messages"][0]))
break
else:
errorinput("登录失败: %s" % tresult['messages'][0])
stoidinput("尝试重新登陆")
else:
stoidinput("登录成功")
myurllib2.Post(surl, ldata)
getUserinfo()
break
except ValueError as e:
errorinput(e)
sleep(1)
def getUserinfo():
"""
登录成功后,显示用户名
:return:
"""
url = 'https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfo'
data = dict(_json_att=None)
result = myurllib2.Post(url, data)
userinfo = result
name = r'<input name="userDTO.loginUserDTO.user_name" style="display:none;" type="text" value="(\S+)" />'
try:
stoidinput("欢迎 %s 登录" % re.search(name, result).group(1))
except AttributeError:
pass
def main():
login(_get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"])
def logout():
url = 'https://kyfw.12306.cn/otn/login/loginOut'
result = myurllib2.get(url)
if result:
stoidinput("已退出")
else:
errorinput("退出失败")
self.errorinput("退出失败")
if __name__ == "__main__":
main()
go_login.login()
# logout()

204
init/login.py.bak Normal file
View File

@@ -0,0 +1,204 @@
#!/bin/env python
# -*- coding=utf-8 -*-
import random
import json
import re
from time import sleep
from config.ticketConf import _get_yaml
from PIL import Image
from damatuCode.damatuWeb import DamatuApi
from myUrllib import myurllib2
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&%s' % random.random()
def cookietp():
stoidinput("获取Cookie")
Url = "https://kyfw.12306.cn/otn/login/init"
myurllib2.get(Url)
# for index, c in enumerate(myurllib2.cookiejar):
# stoidinput(c)
def readImg():
"""
增加手动打码,只是登录接口,完全不用担心提交订单效率
思路
1.调用PIL显示图片
2.图片位置说明验证码图片中每个图片代表一个下标依次类推12345678
3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码,
:return:
"""
global randCode
stoidinput("下载验证码...")
img_path = './tkcode'
result = myurllib2.get(codeimg)
try:
open(img_path, 'wb').write(result)
if _get_yaml()["is_aotu_code"]:
randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main()
else:
img = Image.open('./tkcode')
img.show()
codexy()
except OSError as e:
print (e)
pass
def stoidinput(text):
"""
正常信息输出
:param text:
:return:
"""
print "\033[34m[*]\033[0m %s " % text
def errorinput(text):
"""
错误信息输出
:param text:
:return:
"""
print "\033[32m[!]\033[0m %s " % text
return False
def codexy():
"""
获取验证码
:return: str
"""
Ofset = raw_input("[*] 请输入验证码: ")
select = Ofset.split(',')
global randCode
post = []
offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题
offsetsY = 0 # 选择的答案的top值
for ofset in select:
if ofset == '1':
offsetsY = 46
offsetsX = 42
elif ofset == '2':
offsetsY = 46
offsetsX = 105
elif ofset == '3':
offsetsY = 45
offsetsX = 184
elif ofset == '4':
offsetsY = 48
offsetsX = 256
elif ofset == '5':
offsetsY = 36
offsetsX = 117
elif ofset == '6':
offsetsY = 112
offsetsX = 115
elif ofset == '7':
offsetsY = 114
offsetsX = 181
elif ofset == '8':
offsetsY = 111
offsetsX = 252
else:
pass
post.append(offsetsX)
post.append(offsetsY)
randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '')
def login(user, passwd):
"""
登陆
:param user: 账户名
:param passwd: 密码
:return:
"""
login_num = 0
while True:
cookietp()
readImg()
login_num += 1
randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn'
logurl = 'https://kyfw.12306.cn/otn/login/loginAysnSuggest'
surl = 'https://kyfw.12306.cn/otn/login/userLogin'
randdata = {
"randCode": randCode,
"rand": "sjrand"
}
logdata = {
"loginUserDTO.user_name": user,
"userDTO.password": passwd,
"randCode": randCode
}
ldata = {
"_json_att": None
}
fresult = json.loads(myurllib2.Post(randurl, randdata), encoding='utf8')
checkcode = fresult['data']['msg']
if checkcode == 'FALSE':
errorinput("验证码有误,第{}次尝试重试".format(login_num))
else:
stoidinput("验证码通过,开始登录..")
sleep(1)
try:
tresult = json.loads(myurllib2.Post(logurl, logdata), encoding='utf8')
if 'data' not in tresult:
errorinput("登录失败: %s" % tresult['messages'][0])
# elif "messages" in tresult and tresult["messages"][0].find("密码输入错误") is not -1:
# errorinput("登陆失败:{}".format(tresult["messages"][0]))
# break
elif 'messages' in tresult and tresult['messages']:
messages = tresult['messages'][0]
if messages.find("密码输入错误") is not -1:
errorinput("登陆失败:{}".format(tresult["messages"][0]))
break
else:
errorinput("登录失败: %s" % tresult['messages'][0])
stoidinput("尝试重新登陆")
else:
stoidinput("登录成功")
myurllib2.Post(surl, ldata)
getUserinfo()
break
except ValueError as e:
errorinput(e)
sleep(1)
def getUserinfo():
"""
登录成功后,显示用户名
:return:
"""
url = 'https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfo'
data = dict(_json_att=None)
result = myurllib2.Post(url, data)
userinfo = result
name = r'<input name="userDTO.loginUserDTO.user_name" style="display:none;" type="text" value="(\S+)" />'
try:
stoidinput("欢迎 %s 登录" % re.search(name, result).group(1))
except AttributeError:
pass
def main():
login(_get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"])
def logout():
url = 'https://kyfw.12306.cn/otn/login/loginOut'
result = myurllib2.get(url)
if result:
stoidinput("已退出")
else:
errorinput("退出失败")
if __name__ == "__main__":
main()
# logout()

View File

@@ -3,12 +3,15 @@ import json
import datetime
import random
import re
import socket
import threading
import urllib
import urllib.request, urllib.parse, urllib.error
import sys
import time
from collections import OrderedDict
from init import login
from config.emailConf import email
from config.ticketConf import _get_yaml
from damatuCode.damatuWeb import DamatuApi
from myException.PassengerUserException import PassengerUserException
@@ -16,14 +19,13 @@ from myException.ticketConfigException import ticketConfigException
from myException.ticketIsExitsException import ticketIsExitsException
from myException.ticketNumOutException import ticketNumOutException
from myUrllib import myurllib2
reload(sys)
sys.setdefaultencoding('utf-8')
import codecs
from init import gol
class select:
def __init__(self):
self.from_station, self.to_station, self.station_date, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.expect_refresh_interval, self.ticket_black_list_time = self.get_ticket_info()
def __init__(self,ticket_config):
self.from_station, self.to_station, self.station_date, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.expect_refresh_interval, self.ticket_black_list_time = self.get_ticket_info(ticket_config)
self.order_request_params = {} # 订单提交时的参数
self.ticketInfoForPassengerForm = {} # 初始化当前页面参数
self.current_seats = {} # 席别信息
@@ -32,16 +34,19 @@ class select:
self.user_info = ""
self.secretStr = ""
self.ticket_black_list = dict()
self.is_check_user = dict()
self.ticket_config = ticket_config
def get_ticket_info(self):
def get_ticket_info(self,ticket_config):
"""
获取配置信息
:return:
"""
ticket_info_config = _get_yaml()
from_station = ticket_info_config["set"]["from_station"].encode("utf8")
to_station = ticket_info_config["set"]["to_station"].encode("utf8")
station_date = ticket_info_config["set"]["station_date"].encode("utf8")
ticket_info_config = _get_yaml(ticket_config)
from_station = ticket_info_config["set"]["from_station"]
to_station = ticket_info_config["set"]["to_station"]
station_date = ticket_info_config["set"]["station_date"]
set_type = ticket_info_config["set"]["set_type"]
is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
@@ -49,8 +54,8 @@ class select:
station_trains = ticket_info_config["set"]["station_trains"]
expect_refresh_interval = ticket_info_config["expect_refresh_interval"]
ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
print "*"*20
print "当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:{6}\n候选购买车次:{7}\n未开始刷票间隔时间:{8}\n僵尸票关小黑屋时长:{9}\n".format\
print("*"*20)
print("当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:{6}\n候选购买车次:{7}\n未开始刷票间隔时间:{8}\n僵尸票关小黑屋时长:{9}\n".format\
(
from_station,
to_station,
@@ -62,8 +67,8 @@ class select:
",".join(station_trains),
expect_refresh_interval,
ticket_black_list_time,
)
print "*"*20
))
print("*"*20)
return from_station, to_station, station_date, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, expect_refresh_interval, ticket_black_list_time
def get_order_request_params(self):
@@ -107,15 +112,15 @@ class select:
:param station:
:return:
"""
result = open('station_name.txt')
result = codecs.open('station_name.txt', encoding='utf-8')
info = result.read().split('=')[1].strip("'").split('@')
del info[0]
station_name = {}
for i in range(0, len(info)):
n_info = info[i].split('|')
station_name[n_info[1]] = n_info[2]
from_station = station_name[from_station.encode("utf8")]
to_station = station_name[to_station.encode("utf8")]
from_station = station_name[from_station]
to_station = station_name[to_station]
return from_station, to_station
def time(self):
@@ -133,7 +138,7 @@ class select:
:return: token
"""
initdc_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
initdc_result = myurllib2.get(initdc_url)
initdc_result = self.s.get(initdc_url, verify=False).content.decode(encoding='utf-8')
token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'")
ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?')
order_request_params_name = re.compile(r'var orderRequestDTO=(\{.+\})?')
@@ -160,7 +165,7 @@ class select:
'_json_att': None,
'REPEAT_SUBMIT_TOKEN': self.token
}
jsonData = json.loads(myurllib2.Post(get_passengerDTOs, get_data))
jsonData = self.s.post(get_passengerDTOs, data = get_data, verify=False).json()
if 'data' in jsonData and jsonData['data'] and 'normal_passengers' in jsonData['data'] and jsonData['data'][
'normal_passengers']:
# return jsonData['data']['normal_passengers']
@@ -176,25 +181,21 @@ class select:
print("未查找到常用联系人")
raise PassengerUserException("未查找到常用联系人,请先添加联系人在试试")
def leftTicketLog(self, from_station, to_station):
"""
模拟进入车次列表页
:param from_station:
:param to_station:
:return:
"""
leftTicketLogUrl = 'https://kyfw.12306.cn/otn/leftTicket/log?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format(
self.station_date, from_station, to_station)
leftTicketLog = json.loads(myurllib2.get(leftTicketLogUrl), encoding='utf-8')
if "status" in leftTicketLog and leftTicketLog["status"] is True:
return True
else:
if "message" in leftTicketLog and leftTicketLog["message"]:
print leftTicketLog["message"]
elif "validateMessages" in leftTicketLog and leftTicketLog["validateMessages"]:
print leftTicketLog["validateMessages"]
def submitOrderRequestFunc(self, from_station, to_station, station_date=None):
global station_ticket
try:
select_url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format(
self.station_date if station_date is None else station_date, from_station, to_station)
station_ticket = self.s.get(select_url, allow_redirects=False, verify=False)
while station_ticket.status_code is not 200 :
station_ticket = self.s.get(select_url, allow_redirects=False, verify=False)
station_ticket = station_ticket.json()
except KeyboardInterrupt:
pass
def submitOrderRequest(self, from_station, to_station):
return station_ticket
def submitOrderRequestImplement(self, from_station, to_station,):
"""
提交车次信息
车次对应字典
@@ -209,44 +210,45 @@ class select:
} 参照station_seat()方法
:return:
"""
select_url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format(self.station_date, from_station, to_station)
station_ticket = json.loads(myurllib2.get(select_url), encoding='utf-8')
global station_ticket
station_ticket = self.submitOrderRequestFunc(from_station, to_station,station_date=None)
value = station_ticket['data']
if not value:
print ('{0}-{1} 车次坐席查询为空...'.format(self.from_station, self.to_station))
print(('{0}-{1} 车次坐席查询为空...'.format(self.from_station, self.to_station)))
else:
if value['result']:
for i in value['result']:
ticket_info = i.split('|')
if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订": # 筛选未在开始时间内的车次
if ticket_info[11] == "Y" and ticket_info[1] == "预订": # 筛选未在开始时间内的车次
for j in range(len(self._station_seat)):
is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))]
is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j])]
# print self._station_seat[j]
if is_ticket_pass != '' and is_ticket_pass != '' and ticket_info[3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次
# tiket_values = [k for k in value['map'].values()]
self.secretStr = ticket_info[0]
train_no = ticket_info[3]
print ('车次: ' + train_no + ' 始发车站: ' + self.from_station + ' 终点站: ' +
self.to_station + ' ' + self._station_seat[j].encode("utf8") + ':' + ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))])
if self.ticket_black_list.has_key(train_no) and (datetime.datetime.now() - self.ticket_black_list[train_no]).seconds/60 < int(self.ticket_black_list_time):
self.to_station + ' ' + self._station_seat[j] + ':' + ticket_info[self.station_seat(self._station_seat[j])])
if self.ticket_black_list.__contains__(train_no) and (datetime.datetime.now() - self.ticket_black_list[train_no]).seconds/60 < int(self.ticket_black_list_time):
print("该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
break
else:
print ('正在尝试提交订票...')
if self.check_user():
self.submit_station()
self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
self.getRepeatSubmitToken()
# self.submitOrderRequestFunc(from_station, to_station, self.time())
self.submit_station()
self.getPassengerTicketStr(self._station_seat[j])
self.getRepeatSubmitToken()
if not self.user_info: # 修改每次都调用用户接口导致用户接口不能用
self.user_info = self.getPassengerDTOs()
if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")):
break
if self.checkOrderInfo(train_no, self._station_seat[j]):
break
else:
pass
else:
pass
time.sleep(self.expect_refresh_interval)
else:
print "车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
print("车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket))
def check_user(self):
"""
@@ -255,16 +257,21 @@ class select:
"""
check_user_url = 'https://kyfw.12306.cn/otn/login/checkUser'
data = dict(_json_att=None)
check_user = json.loads(myurllib2.Post(check_user_url, data), encoding='utf-8')
check_user = self.s.post(check_user_url, data=data, verify=False).json()
check_user_flag = check_user['data']['flag']
if check_user_flag is True:
print ('尝试提交订单...')
return True
else:
if check_user['messages']:
print ('用户检查失败:%s可能未登录可能session已经失效' % check_user['messages'][0])
print ('正在尝试重新登录')
self.call_login()
self.is_check_user["user_time"] = datetime.datetime.now()
else:
print ('用户检查失败: %s可能未登录可能session已经失效' % check_user)
print ('正在尝试重新登录')
self.call_login()
self.is_check_user["user_time"] = datetime.datetime.now()
def submit_station(self):
"""
@@ -278,7 +285,7 @@ class select:
"""
submit_station_url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
data = [('secretStr', urllib.unquote(self.secretStr)), # 字符串加密
data = [('secretStr', urllib.parse.unquote(self.secretStr)), # 字符串加密
('train_date', self.time()), # 出发时间
('back_train_date', self.time()), # 返程时间
('tour_flag', 'dc'), # 旅途类型
@@ -286,7 +293,12 @@ class select:
('query_from_station_name', self.from_station), # 起始车站
('query_to_station_name', self.to_station), # 终点车站
]
submitResult = json.loads(myurllib2.Post(submit_station_url, data), encoding='utf-8')
submitResult = self.s.post(submit_station_url, allow_redirects=False, data=data, verify=False)
while submitResult.status_code is not 200:
submitResult = self.s.post(submit_station_url, allow_redirects=False, data=data, verify=False)
submitResult = submitResult.json()
print(submitResult)
if 'data' in submitResult and submitResult['data']:
if submitResult['data'] == 'N':
print ('出票成功')
@@ -366,7 +378,7 @@ class select:
data['tour_flag'] = 'dc'
data['whatsSelect'] = 1
data['REPEAT_SUBMIT_TOKEN'] = self.token
checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, ))
checkOrderInfo = self.s.post(checkOrderInfoUrl, data=data, verify=False).json()
if 'data' in checkOrderInfo:
if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y":
is_need_code = True
@@ -379,12 +391,12 @@ class select:
return True
else:
if "errMsg" in checkOrderInfo['data'] and checkOrderInfo['data']["errMsg"]:
print checkOrderInfo['data']["errMsg"]
print(checkOrderInfo['data']["errMsg"])
else:
print checkOrderInfo
print(checkOrderInfo)
elif 'messages' in checkOrderInfo and checkOrderInfo['messages']:
print (checkOrderInfo['messages'][0])
print(checkOrderInfo['messages'][0])
def getQueueCount(self, train_no, set_type, is_need_code):
"""
@@ -393,13 +405,11 @@ class select:
:param token:
:return:
"""
old_train_date = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_date']+"00:00:00" # 模仿12306格式 Sun May 21 2017 00:00:00 GMT+0800 (中国标准时间)
m_time = time.mktime(time.strptime(old_train_date, "%Y%m%d%H:%M:%S"))
l_time = time.localtime(m_time)
new_train_date = time.strftime("%a %b %d %Y %H:%M:%S", l_time)
l_time = time.localtime(time.time())
new_train_date = time.strftime("%a %b %d %Y", l_time)
getQueueCountUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount'
data = {
'train_date': new_train_date,
'train_date': str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)",
'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'],
'stationTrainCode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['station_train_code'],
'seatType': self.set_type,
@@ -410,16 +420,11 @@ class select:
'train_location': self.get_ticketInfoForPassengerForm()['train_location'],
'REPEAT_SUBMIT_TOKEN': self.get_token(),
}
getQueueCountResult = json.loads(myurllib2.Post(getQueueCountUrl, data))
getQueueCountResult = self.s.post(getQueueCountUrl, data=data, verify=False).json()
if "status" in getQueueCountResult and getQueueCountResult["status"] is True:
if "countT" in getQueueCountResult["data"]:
ticket = getQueueCountResult["data"]["ticket"]
ticket_split = sum(map(self.conversion_int, ticket.split(","))) if ticket.find(",") != -1 else ticket
# ticket_sum = sum([int(ticket_split[0]),int(ticket_split[1])])
# if set_type == "无座": # 修改无座和硬座的座位号提交是个字符串的问题
# ticket = ticket_split[1]
# elif set_type == "硬座":
# ticket = ticket_split[0]
countT = getQueueCountResult["data"]["countT"]
if int(countT) is 0:
if int(ticket_split) < len(self.user_info):
@@ -461,6 +466,8 @@ class select:
"seatDetailType": "000", # 开始需要选择座位但是目前12306不支持自动选择作为那这个参数为默认
"roomType": "00", # 好像是根据一个id来判断选中的两种 第一种是00第二种是10但是我在12306的页面没找到该id目前写死是00不知道会出什么错
"dwAll": "N",
"whatsSelect": 1,
"_json_at": None,
"REPEAT_SUBMIT_TOKEN": self.get_token(),
}
try:
@@ -468,7 +475,7 @@ class select:
if is_node_code:
print("正在使用自动识别验证码功能")
randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn'
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=sjrand&%s' % random.random()
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s' % random.random()
result = myurllib2.get(codeimg)
img_path = './tkcode'
open(img_path, 'wb').write(result)
@@ -480,18 +487,24 @@ class select:
"_json_att": None,
"REPEAT_SUBMIT_TOKEN": self.get_token()
}
fresult = json.loads(myurllib2.Post(randurl, randData), encoding='utf8') # 校验验证码是否正确
fresult = self.s.post(randurl, data=randData, verify=False).json() # 校验验证码是否正确
checkcode = fresult['data']['msg']
if checkcode == 'FALSE':
print ("验证码有误,第{}次尝试重试".format(i))
else:
if checkcode == 'TRUE':
print("验证码通过,正在提交订单")
data['randCode'] = randCode
break
else:
print("验证码有误, 接口返回{0}{1}次尝试重试".format(fresult, i))
else:
print("不需要验证码")
break
checkQueueOrderResult = json.loads(myurllib2.Post(checkQueueOrderUrl, data))
# print("".join(data))
checkQueueOrderResultObj = self.s.post(checkQueueOrderUrl, allow_redirects=False, data=data, verify=False)
#解决进入排队时接口302问题
while checkQueueOrderResultObj.status_code == 302:
checkQueueOrderResultObj = self.s.post(checkQueueOrderUrl, allow_redirects=False, data=data,
verify=False)
checkQueueOrderResult = checkQueueOrderResultObj.json()
if "status" in checkQueueOrderResult and checkQueueOrderResult["status"]:
c_data = checkQueueOrderResult["data"] if "data" in checkQueueOrderResult else {}
if 'submitStatus' in c_data and c_data['submitStatus'] is True:
@@ -529,16 +542,19 @@ class select:
print("超出排队时间,自动放弃,正在重新刷票")
break
try:
queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN={1}".format(_random, self.get_token())
queryOrderWaitTimeResult = json.loads(myurllib2.get(queryOrderWaitTimeUrl))
# queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN={1}".format(_random, self.get_token())
data = {"random": _random, "tourFlag": "dc"}
queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime"
queryOrderWaitTimeResult = self.s.post(queryOrderWaitTimeUrl, data=data, verify=False).json()
except ValueError:
queryOrderWaitTimeResult = {}
if queryOrderWaitTimeResult:
if "status" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["status"]:
if "orderId" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["orderId"] is not None:
email("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(queryOrderWaitTimeResult["data"]["orderId"]),self.ticket_config).sendEmail()
raise ticketIsExitsException("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(queryOrderWaitTimeResult["data"]["orderId"]))
elif "msg" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["msg"]:
print queryOrderWaitTimeResult["data"]["msg"]
print(queryOrderWaitTimeResult["data"]["msg"])
break
elif "waitTime"in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["waitTime"]:
print("排队等待时间预计还剩 {0} ms".format(0-queryOrderWaitTimeResult["data"]["waitTime"]))
@@ -547,13 +563,15 @@ class select:
elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
print("排队等待失败: " + queryOrderWaitTimeResult["messages"])
else:
print("{}排队中,请耐心等待".format(num))
print("{}排队中,请耐心等待".format(num))
else:
print("排队中")
time.sleep(2)
time.sleep(1)
order_id = self.queryMyOrderNoComplete() # 尝试查看订单列表,如果有订单,则判断成功,不过一般可能性不大
if order_id:
email("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(order_id),self.ticket_config).sendEmail()
raise ticketIsExitsException("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(order_id))
else:
print(ticketNumOutException("订单提交失败!,正在重新刷票"))
@@ -566,7 +584,7 @@ class select:
queryMyOrderNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete"
data = {"_json_att": None}
try:
queryMyOrderNoCompleteResult = json.loads(myurllib2.Post(queryMyOrderNoCompleteUrl, data))
queryMyOrderNoCompleteResult = self.s.post(queryMyOrderNoCompleteUrl, data=data, verify=False).json()
except ValueError:
queryMyOrderNoCompleteResult = {}
if queryMyOrderNoCompleteResult:
@@ -579,7 +597,7 @@ class select:
raise ticketNumOutException(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
else:
if "message" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult["message"]:
print queryMyOrderNoCompleteResult["message"]
print(queryMyOrderNoCompleteResult["message"])
return False
else:
return False
@@ -593,7 +611,7 @@ class select:
"""
initNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/initNoComplete"
data = {"_json_att": None}
myurllib2.Post(initNoCompleteUrl, data)
self.s.post(initNoCompleteUrl, data=data, verify=False)
# def call_submit_ticket(self, function_name=None):
# """
@@ -607,63 +625,59 @@ class select:
# else:
# self.submitOrderRequest()
def call_login(self):
"""登录回调方法"""
login.go_login(self.ticket_config).login()
def main(self):
self.call_login()
self.s = gol.get_value('s')
#print(self.s.cookies)
from_station, to_station = self.station_table(self.from_station, self.to_station)
if self.leftTicketLog(from_station, to_station):
num = 1
while 1:
try:
num += 1
time.sleep(self.select_refresh_interval)
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
print "12306休息时间本程序自动停止,明天早上七点运行"
break
start_time = datetime.datetime.now()
self.submitOrderRequest(from_station, to_station)
print "正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 代理设置 无 总耗时{3}ms".format(num, self.station_date, ",".join(self.station_trains), (datetime.datetime.now()-start_time).microseconds/1000)
except PassengerUserException as e:
print e.message
break
except ticketConfigException as e:
print e.message
break
except ticketIsExitsException as e:
print e.message
break
except ticketNumOutException as e:
print e.message
break
except ValueError as e:
if e.message == "No JSON object could be decoded":
print("12306接口无响应正在重试")
else:
print(e.message)
except KeyError as e:
# if self.leftTicketLog(from_station, to_station):
num = 1
while 1:
try:
num += 1
if "user_time" in self.is_check_user and (datetime.datetime.now() - self.is_check_user["user_time"]).seconds/60 > 10:
# 十分钟调用一次检查用户是否登录
self.check_user()
time.sleep(self.select_refresh_interval)
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
print("12306休息时间本程序自动停止,明天早上七点将自动运行")
time.sleep(60 * 60 * 7)
self.call_login()
start_time = datetime.datetime.now()
self.submitOrderRequestImplement(from_station, to_station)
print("正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 代理设置 无 总耗时{3}ms".format(num, self.station_date, ",".join(self.station_trains), (datetime.datetime.now()-start_time).microseconds/1000))
except PassengerUserException as e:
print(e.message)
break
except ticketConfigException as e:
print(e.message)
break
except ticketIsExitsException as e:
print(e.message)
break
except ticketNumOutException as e:
print(e.message)
break
except ValueError as e:
if e.message == "No JSON object could be decoded":
print("12306接口无响应正在重试")
else:
print(e.message)
except KeyError as e:
print(e.message)
except TypeError as e:
print(e.message)
except socket.error as e:
print(e.message)
# class selectProducer(threading.Thread):
# """刷票队列"""
# def __init__(self, t_name, queue):
# threading.Thread.__init__(self, name=t_name)
# self.data = queue
# print "{0} 正在运行".format(t_name)
#
# def run(self):
# pass
#
#
# class submitOrderConsumer(threading.Thread):
# """订单队列"""
# def __init__(self, t_name, queue):
# threading.Thread.__init__(self, name=t_name)
# self.data = queue
# print "{0} 正在运行".format(t_name)
#
# def run(self):
# pass
if __name__ == '__main__':
a = select('上海', '北京')
a.main()
login.go_login().login()
# a = select('上海', '北京')
# a.main()

View File

@@ -0,0 +1,671 @@
# -*- coding=utf-8 -*-
import json
import datetime
import random
import re
import socket
import threading
import urllib
import sys
import time
from collections import OrderedDict
from init import login
from config.emailConf import sendEmail
from config.ticketConf import _get_yaml
from damatuCode.damatuWeb import DamatuApi
from init.login import login
from myException.PassengerUserException import PassengerUserException
from myException.ticketConfigException import ticketConfigException
from myException.ticketIsExitsException import ticketIsExitsException
from myException.ticketNumOutException import ticketNumOutException
from myUrllib import myurllib2
reload(sys)
sys.setdefaultencoding('utf-8')
class select:
def __init__(self):
self.from_station, self.to_station, self.station_date, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.expect_refresh_interval, self.ticket_black_list_time = self.get_ticket_info()
self.order_request_params = {} # 订单提交时的参数
self.ticketInfoForPassengerForm = {} # 初始化当前页面参数
self.current_seats = {} # 席别信息
self.token = ""
self.set_type = ""
self.user_info = ""
self.secretStr = ""
self.ticket_black_list = dict()
def get_ticket_info(self):
"""
获取配置信息
:return:
"""
ticket_info_config = _get_yaml()
from_station = ticket_info_config["set"]["from_station"].encode("utf8")
to_station = ticket_info_config["set"]["to_station"].encode("utf8")
station_date = ticket_info_config["set"]["station_date"].encode("utf8")
set_type = ticket_info_config["set"]["set_type"]
is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
select_refresh_interval = ticket_info_config["select_refresh_interval"]
station_trains = ticket_info_config["set"]["station_trains"]
expect_refresh_interval = ticket_info_config["expect_refresh_interval"]
ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
print "*"*20
print "当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:{6}\n候选购买车次:{7}\n未开始刷票间隔时间:{8}\n僵尸票关小黑屋时长:{9}\n".format\
(
from_station,
to_station,
station_date,
",".join(set_type),
is_more_ticket,
",".join(ticke_peoples),
select_refresh_interval,
",".join(station_trains),
expect_refresh_interval,
ticket_black_list_time,
)
print "*"*20
return from_station, to_station, station_date, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, expect_refresh_interval, ticket_black_list_time
def get_order_request_params(self):
return self.order_request_params
def get_ticketInfoForPassengerForm(self):
return self.ticketInfoForPassengerForm
def get_current_seats(self):
return self.current_seats
def get_token(self):
return self.token
def get_set_type(self):
return self.set_type
def conversion_int(self, str):
return int(str)
def station_seat(self, index):
"""
获取车票对应坐席
:param seat_type:
:return:
"""
seat = {'商务座': 32,
'一等座': 31,
'二等座': 30,
'特等座': 25,
'软卧': 23,
'硬卧': 28,
'硬座': 29,
'无座': 26,
}
return seat[index]
def station_table(self, from_station, to_station):
"""
读取车站信息
:param station:
:return:
"""
result = open('station_name.txt')
info = result.read().split('=')[1].strip("'").split('@')
del info[0]
station_name = {}
for i in range(0, len(info)):
n_info = info[i].split('|')
station_name[n_info[1]] = n_info[2]
from_station = station_name[from_station.encode("utf8")]
to_station = station_name[to_station.encode("utf8")]
return from_station, to_station
def time(self):
"""
获取日期
:return:
"""
today = datetime.date.today()
tomorrow = today+datetime.timedelta(1)
return tomorrow.strftime('%Y-%m-%d')
def getRepeatSubmitToken(self):
"""
获取提交车票请求token
:return: token
"""
initdc_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
initdc_result = myurllib2.get(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=(\{.+\})?')
# if token_name and ticketInfoForPassengerForm_name and order_request_params_name:
self.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:
self.ticketInfoForPassengerForm = json.loads(re_tfpf[0].replace("'", '"'))
else:
pass
if re_orp:
self.order_request_params = json.loads(re_orp[0].replace("'", '"'))
else:
pass
def getPassengerDTOs(self):
"""
获取乘客信息
:return:
"""
get_passengerDTOs = 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs'
get_data = {
'_json_att': None,
'REPEAT_SUBMIT_TOKEN': self.token
}
jsonData = json.loads(myurllib2.Post(get_passengerDTOs, get_data))
if 'data' in jsonData and jsonData['data'] and 'normal_passengers' in jsonData['data'] and jsonData['data'][
'normal_passengers']:
# return jsonData['data']['normal_passengers']
normal_passengers = jsonData['data']['normal_passengers']
_normal_passenger = [normal_passengers[i] for i in range(len(normal_passengers))if normal_passengers[i]["passenger_name"] in self.ticke_peoples]
return _normal_passenger if _normal_passenger else normal_passengers[0] # 如果配置乘车人没有在账号,则默认返回第一个用户
else:
if 'data' in jsonData and 'exMsg' in jsonData['data'] and jsonData['data']['exMsg']:
print(jsonData['data']['exMsg'])
elif 'messages' in jsonData and jsonData['messages']:
print(jsonData['messages'][0])
else:
print("未查找到常用联系人")
raise PassengerUserException("未查找到常用联系人,请先添加联系人在试试")
def submitOrderRequestFunc(self, from_station, to_station, station_date=None):
select_url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format(
self.station_date if station_date is None else station_date, from_station, to_station)
station_ticket = json.loads(myurllib2.get(select_url), encoding='utf-8')
return station_ticket
def submitOrderRequestImplement(self, from_station, to_station,):
"""
提交车次信息
车次对应字典
{32: '商务座 ',
31: '一等座 ',
30: '二等座 ',
25: '特等座 ',
23: '软卧 ',
28: '硬卧 ',
29: '硬座 ',
26: '无座 '
} 参照station_seat()方法
:return:
"""
station_ticket = self.submitOrderRequestFunc(from_station, to_station)
value = station_ticket['data']
if not value:
print ('{0}-{1} 车次坐席查询为空...'.format(self.from_station, self.to_station))
else:
if value['result']:
for i in value['result']:
ticket_info = i.split('|')
if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订": # 筛选未在开始时间内的车次
for j in range(len(self._station_seat)):
is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))]
# print self._station_seat[j]
if is_ticket_pass != '' and is_ticket_pass != '' and ticket_info[3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次
# tiket_values = [k for k in value['map'].values()]
self.secretStr = ticket_info[0]
train_no = ticket_info[3]
print ('车次: ' + train_no + ' 始发车站: ' + self.from_station + ' 终点站: ' +
self.to_station + ' ' + self._station_seat[j].encode("utf8") + ':' + ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))])
if self.ticket_black_list.has_key(train_no) and (datetime.datetime.now() - self.ticket_black_list[train_no]).seconds/60 < int(self.ticket_black_list_time):
print("该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
break
else:
print ('正在尝试提交订票...')
self.submitOrderRequestFunc(from_station, to_station, self.time())
if self.check_user():
self.submit_station()
self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
self.getRepeatSubmitToken()
if not self.user_info: # 修改每次都调用用户接口导致用户接口不能用
self.user_info = self.getPassengerDTOs()
if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")):
break
else:
pass
else:
pass
time.sleep(self.expect_refresh_interval)
else:
print "车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
def check_user(self):
"""
检查用户是否达到订票条件
:return:
"""
check_user_url = 'https://kyfw.12306.cn/otn/login/checkUser'
data = dict(_json_att=None)
check_user = json.loads(myurllib2.Post(check_user_url, data), encoding='utf-8')
check_user_flag = check_user['data']['flag']
if check_user_flag is True:
print ('尝试提交订单...')
return True
else:
if check_user['messages']:
print ('用户检查失败:%s可能未登录可能session已经失效' % check_user['messages'][0])
else:
print ('用户检查失败: %s可能未登录可能session已经失效' % check_user)
def submit_station(self):
"""
提交车次
预定的请求参数,注意参数顺序
注意这里为了防止secretStr被urllib.parse过度编码在这里进行一次解码
否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败
:param self:
:param secretStr: 提交车次加密
:return:
"""
submit_station_url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
data = [('secretStr', urllib.unquote(self.secretStr)), # 字符串加密
('train_date', self.time()), # 出发时间
('back_train_date', self.time()), # 返程时间
('tour_flag', 'dc'), # 旅途类型
('purpose_codes', 'ADULT'), # 成人票还是学生票
('query_from_station_name', self.from_station), # 起始车站
('query_to_station_name', self.to_station), # 终点车站
]
submitResult = json.loads(myurllib2.Post(submit_station_url, data), encoding='utf-8')
if 'data' in submitResult and submitResult['data']:
if submitResult['data'] == 'N':
print ('出票成功')
else:
print ('出票失败')
elif 'messages' in submitResult and submitResult['messages']:
raise ticketIsExitsException(submitResult['messages'][0])
def getPassengerTicketStr(self, set_type):
"""
获取getPassengerTicketStr 提交对应的代号码
:param str: 坐席
:return:
"""
passengerTicketStr = {
'一等座': 'M',
'特等座': 'P',
'二等座': 'O',
'商务座': 9,
'硬座': 1,
'无座': 1,
'软卧': 4,
'硬卧': 3,
}
self.set_type = str(passengerTicketStr[set_type.replace(' ', '')])
def ticket_type(self):
"""订单票的类型,目前只考虑成人票,此方法暂时搁置,做备案"""
ticket_type = {'adult': "1", 'child': "2", 'student': "3", 'disability': "4"}
return ticket_type
def getPassengerTicketStrListAndOldPassengerStr(self):
"""
获取提交车次人内容格式
passengerTicketStr O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N
oldPassengerStr 文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1_
:return:
"""
passengerTicketStrList = []
oldPassengerStr = []
if not self.user_info:
raise PassengerUserException("联系人不在列表中,请查证后添加")
if len(self.user_info) is 1:
passengerTicketStrList.append(
'0,' + self.user_info[0]['passenger_id_type_code'] + "," + self.user_info[0][
"passenger_name"] + "," +
self.user_info[0]['passenger_type'] + "," + self.user_info[0]['passenger_id_no'] + "," +
self.user_info[0]['mobile_no'] + ',N')
oldPassengerStr.append(
self.user_info[0]['passenger_name'] + "," + self.user_info[0]['passenger_type'] + "," +
self.user_info[0]['passenger_id_no'] + "," + self.user_info[0]['passenger_type'] + '_')
else:
for i in range(len(self.user_info)):
passengerTicketStrList.append(
'0,' + self.user_info[i]['passenger_id_type_code'] + "," + self.user_info[i][
"passenger_name"] + "," + self.user_info[i]['passenger_type'] + "," + self.user_info[i][
'passenger_id_no'] + "," + self.user_info[i]['mobile_no'] + ',N_' + self.set_type)
oldPassengerStr.append(
self.user_info[i]['passenger_name'] + "," + self.user_info[i]['passenger_type'] + "," +
self.user_info[i]['passenger_id_no'] + "," + self.user_info[i]['passenger_type'] + '_')
return passengerTicketStrList, oldPassengerStr
def checkOrderInfo(self, train_no, set_type):
"""
检查支付订单需要提交REPEAT_SUBMIT_TOKEN
passengerTicketStr : 座位编号,0,票类型,乘客名,证件类型,证件号,手机号码,保存常用联系人(Y或N)
oldPassengersStr: 乘客名,证件类型,证件号,乘客类型
:return:
"""
passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
checkOrderInfoUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo'
data = OrderedDict()
data['cancel_flag'] = 2
data['bed_level_order_num'] = "000000000000000000000000000000"
data['passengerTicketStr'] = self.set_type + "," + ",".join(passengerTicketStrList).rstrip("_{0}".format(self.set_type))
data['oldPassengerStr'] = "".join(oldPassengerStr)
data['tour_flag'] = 'dc'
data['whatsSelect'] = 1
data['REPEAT_SUBMIT_TOKEN'] = self.token
checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, ))
if 'data' in checkOrderInfo:
if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y":
is_need_code = True
if self.getQueueCount(train_no, set_type, is_need_code):
return True
if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo['data']['submitStatus'] is True:
print ('车票提交通过,正在尝试排队')
is_need_code = False
if self.getQueueCount(train_no, set_type, is_need_code):
return True
else:
if "errMsg" in checkOrderInfo['data'] and checkOrderInfo['data']["errMsg"]:
print checkOrderInfo['data']["errMsg"]
else:
print checkOrderInfo
elif 'messages' in checkOrderInfo and checkOrderInfo['messages']:
print (checkOrderInfo['messages'][0])
def getQueueCount(self, train_no, set_type, is_need_code):
"""
# 模拟查询当前的列车排队人数的方法
# 返回信息组成的提示字符串
:param token:
:return:
"""
l_time = time.localtime(time.time())
new_train_date = time.strftime("%a %b %d %Y", l_time)
getQueueCountUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount'
data = {
'train_date': str(new_train_date) + " 00:00:00 GMT+0800 (CST)",
'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'],
'stationTrainCode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['station_train_code'],
'seatType': self.set_type,
'fromStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['from_station'],
'toStationTelecode': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['to_station'],
'leftTicket': self.get_ticketInfoForPassengerForm()['leftTicketStr'],
'purpose_codes': self.get_ticketInfoForPassengerForm()['purpose_codes'],
'train_location': self.get_ticketInfoForPassengerForm()['train_location'],
'REPEAT_SUBMIT_TOKEN': self.get_token(),
}
getQueueCountResult = json.loads(myurllib2.Post(getQueueCountUrl, data))
if "status" in getQueueCountResult and getQueueCountResult["status"] is True:
if "countT" in getQueueCountResult["data"]:
ticket = getQueueCountResult["data"]["ticket"]
ticket_split = sum(map(self.conversion_int, ticket.split(","))) if ticket.find(",") != -1 else ticket
# ticket_sum = sum([int(ticket_split[0]),int(ticket_split[1])])
# if set_type == "无座": # 修改无座和硬座的座位号提交是个字符串的问题
# ticket = ticket_split[1]
# elif set_type == "硬座":
# ticket = ticket_split[0]
countT = getQueueCountResult["data"]["countT"]
if int(countT) is 0:
if int(ticket_split) < len(self.user_info):
print("当前余票数小于乘车人数,放弃订票")
else:
print("排队成功, 当前余票还剩余: {0}".format(ticket_split))
if self.checkQueueOrder(is_need_code):
return True
else:
print("当前排队人数:" + str(countT) + "当前余票还剩余:{0} 张,继续排队中".format(ticket_split))
else:
print("排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountResult, train_no))
self.ticket_black_list[train_no] = datetime.datetime.now()
elif "messages" in getQueueCountResult and getQueueCountResult["messages"]:
print("排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋".format(getQueueCountResult["messages"][0], train_no))
self.ticket_black_list[train_no] = datetime.datetime.now()
else:
if "validateMessages" in getQueueCountResult and getQueueCountResult["validateMessages"]:
print(str(getQueueCountResult["validateMessages"]))
self.ticket_black_list[train_no] = datetime.datetime.now()
else:
print("未知错误 {0}".format("".join(getQueueCountResult)))
def checkQueueOrder(self, is_node_code=False):
"""
模拟提交订单是确认按钮参数获取方法还是get_ticketInfoForPassengerForm 中获取
:return:
"""
passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
checkQueueOrderUrl = "https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue"
data = {
"passengerTicketStr": self.set_type + "," + ",".join(passengerTicketStrList).rstrip("_{0}".format(self.set_type)),
"oldPassengerStr": "".join(oldPassengerStr),
"purpose_codes": self.get_ticketInfoForPassengerForm()["purpose_codes"],
"key_check_isChange": self.get_ticketInfoForPassengerForm()["key_check_isChange"],
"leftTicketStr": self.get_ticketInfoForPassengerForm()["leftTicketStr"],
"train_location": self.get_ticketInfoForPassengerForm()["train_location"],
"seatDetailType": "000", # 开始需要选择座位但是目前12306不支持自动选择作为那这个参数为默认
"roomType": "00", # 好像是根据一个id来判断选中的两种 第一种是00第二种是10但是我在12306的页面没找到该id目前写死是00不知道会出什么错
"dwAll": "N",
"whatsSelect": 1,
"_json_at": None,
"REPEAT_SUBMIT_TOKEN": self.get_token(),
}
try:
for i in range(3):
if is_node_code:
print("正在使用自动识别验证码功能")
randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn'
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s' % random.random()
result = myurllib2.get(codeimg)
img_path = './tkcode'
open(img_path, 'wb').write(result)
randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"],
img_path).main()
randData = {
"randCode": randCode,
"rand": "randp",
"_json_att": None,
"REPEAT_SUBMIT_TOKEN": self.get_token()
}
fresult = json.loads(myurllib2.Post(randurl, randData), encoding='utf8') # 校验验证码是否正确
checkcode = fresult['data']['msg']
if checkcode == 'TRUE':
print("验证码通过,正在提交订单")
data['randCode'] = randCode
break
else:
print ("验证码有误, 接口返回{0}{1}次尝试重试".format(fresult, i))
else:
print("不需要验证码")
break
# print("".join(data))
checkQueueOrderResult = json.loads(myurllib2.Post(checkQueueOrderUrl, data))
if "status" in checkQueueOrderResult and checkQueueOrderResult["status"]:
c_data = checkQueueOrderResult["data"] if "data" in checkQueueOrderResult else {}
if 'submitStatus' in c_data and c_data['submitStatus'] is True:
print("提交订单成功!")
self.queryOrderWaitTime()
else:
if 'errMsg' in c_data and c_data['errMsg']:
print("提交订单失败,{0}".format(c_data['errMsg']))
else:
print(c_data)
print('订票失败!很抱歉,请重试提交预订功能!')
elif "messages" in checkQueueOrderResult and checkQueueOrderResult["messages"]:
print("提交订单失败,错误信息: " + checkQueueOrderResult["messages"])
else:
print("提交订单中,请耐心等待:" + str(checkQueueOrderResult["validateMessages"]))
except ValueError:
print("接口 {} 无响应".format(checkQueueOrderUrl))
def queryOrderWaitTime(self):
"""
排队获取订单等待信息,每隔3秒请求一次最高请求次数为20次
:return:
"""
# queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime"
# data = {
# "random": "{0}{1}".format(int(time.time()), random.randint(1, 9)),
# "tourFlag": "dc",
# "REPEAT_SUBMIT_TOKEN": self.get_token(),
# }
num = 1
while True:
_random = int(round(time.time() * 1000))
num += 1
if num > 30:
print("超出排队时间,自动放弃,正在重新刷票")
break
try:
queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN={1}".format(_random, self.get_token())
queryOrderWaitTimeResult = json.loads(myurllib2.get(queryOrderWaitTimeUrl))
except ValueError:
queryOrderWaitTimeResult = {}
if queryOrderWaitTimeResult:
if "status" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["status"]:
if "orderId" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["orderId"] is not None:
sendEmail("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(queryOrderWaitTimeResult["data"]["orderId"]))
raise ticketIsExitsException("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(queryOrderWaitTimeResult["data"]["orderId"]))
elif "msg" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["msg"]:
print queryOrderWaitTimeResult["data"]["msg"]
break
elif "waitTime"in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["waitTime"]:
print("排队等待时间预计还剩 {0} ms".format(0-queryOrderWaitTimeResult["data"]["waitTime"]))
else:
print ("正在等待中")
elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
print("排队等待失败: " + queryOrderWaitTimeResult["messages"])
else:
print("{}次排队中,请耐心等待".format(num))
else:
print("排队中")
time.sleep(1)
order_id = self.queryMyOrderNoComplete() # 尝试查看订单列表,如果有订单,则判断成功,不过一般可能性不大
if order_id:
sendEmail("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(order_id))
raise ticketIsExitsException("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付".format(order_id))
else:
print(ticketNumOutException("订单提交失败!,正在重新刷票"))
def queryMyOrderNoComplete(self):
"""
获取订单列表信息
:return:
"""
self.initNoComplete()
queryMyOrderNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete"
data = {"_json_att": None}
try:
queryMyOrderNoCompleteResult = json.loads(myurllib2.Post(queryMyOrderNoCompleteUrl, data))
except ValueError:
queryMyOrderNoCompleteResult = {}
if queryMyOrderNoCompleteResult:
if "data" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult["data"] and "orderDBList" in queryMyOrderNoCompleteResult["data"] and queryMyOrderNoCompleteResult["data"]["orderDBList"]:
orderId = queryMyOrderNoCompleteResult["data"]["orderDBList"][0]["sequence_no"]
return orderId
elif "data" in queryMyOrderNoCompleteResult and "orderCacheDTO" in queryMyOrderNoCompleteResult["data"] and queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]:
if "message" in queryMyOrderNoCompleteResult["data"]["orderCacheDTO"] and queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]:
print(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
raise ticketNumOutException(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
else:
if "message" in queryMyOrderNoCompleteResult and queryMyOrderNoCompleteResult["message"]:
print queryMyOrderNoCompleteResult["message"]
return False
else:
return False
else:
print("接口 {} 无响应".format(queryMyOrderNoCompleteUrl))
def initNoComplete(self):
"""
获取订单前需要进入订单列表页获取订单列表页session
:return:
"""
initNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/initNoComplete"
data = {"_json_att": None}
myurllib2.Post(initNoCompleteUrl, data)
# def call_submit_ticket(self, function_name=None):
# """
# 订票失败回调方法默认执行submitOrderRequest()
# 此方法暂不使用
# :param function_name:
# :return:
# """
# if function_name:
# self.function_name()
# else:
# self.submitOrderRequest()
def main(self):
from_station, to_station = self.station_table(self.from_station, self.to_station)
# if self.leftTicketLog(from_station, to_station):
num = 1
while 1:
try:
num += 1
time.sleep(self.select_refresh_interval)
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
print "12306休息时间本程序自动停止,明天早上七点将自动运行"
time.sleep(28800)
login.main() # 重新登录
start_time = datetime.datetime.now()
self.submitOrderRequestImplement(from_station, to_station)
print "正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 代理设置 无 总耗时{3}ms".format(num, self.station_date, ",".join(self.station_trains), (datetime.datetime.now()-start_time).microseconds/1000)
except PassengerUserException as e:
print e.message
break
except ticketConfigException as e:
print e.message
break
except ticketIsExitsException as e:
print e.message
break
except ticketNumOutException as e:
print e.message
break
except ValueError as e:
if e.message == "No JSON object could be decoded":
print("12306接口无响应正在重试")
else:
print(e.message)
except KeyError as e:
print(e.message)
except TypeError as e:
print(e.message)
except socket.error as e:
print(e.message)
# class selectProducer(threading.Thread):
# """刷票队列"""
# def __init__(self, t_name, queue):
# threading.Thread.__init__(self, name=t_name)
# self.data = queue
# print "{0} 正在运行".format(t_name)
#
# def run(self):
# pass
#
#
# class submitOrderConsumer(threading.Thread):
# """订单队列"""
# def __init__(self, t_name, queue):
# threading.Thread.__init__(self, name=t_name)
# self.data = queue
# print "{0} 正在运行".format(t_name)
#
# def run(self):
# pass
if __name__ == '__main__':
a = select('上海', '北京')
a.main()

View File

@@ -36,7 +36,7 @@ class HTTPClient(object):
if response.status_code == 200:
return response.content
else:
print("请求失败。{0}".format(response))
print(("请求失败。{0}".format(response)))
def post(self, url, data=None, proxy=None, **kwargs):
if proxy:
@@ -51,4 +51,4 @@ class HTTPClient(object):
if response.status_code == 200:
return response.content
else:
print("请求失败。{0}".format(response))
print(("请求失败。{0}".format(response)))

54
myUrllib/httpUtils.py.bak Normal file
View File

@@ -0,0 +1,54 @@
# -*- coding: utf8 -*-
import datetime
import requests
class HTTPClient(object):
def __init__(self):
"""
:param method:
:param headers: Must be a dict. Such as headers={'Content_Type':'text/html'}
"""
self.session = requests.session()
self._set_header()
def _set_header(self):
"""设置header"""
add_header = {
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"X-Requested-With": "xmlHttpRequest",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Accept": "*/*",
}
self.session.headers.update(add_header)
def get(self, url, proxy=None, **kwargs):
if proxy:
proxies = {"http": proxy}
else:
proxies = ""
response = self.session.request(method="GET",
url=url,
proxies=proxies,
**kwargs)
if response.status_code == 200:
return response.content
else:
print("请求失败。{0}".format(response))
def post(self, url, data=None, proxy=None, **kwargs):
if proxy:
proxies = {"http": proxy}
else:
proxies = ""
response = self.session.request(method="POST",
url=url,
data=data,
proxies=proxies,
**kwargs)
if response.status_code == 200:
return response.content
else:
print("请求失败。{0}".format(response))

View File

@@ -1,63 +1,38 @@
# -*- coding=utf-8 -*-
import httplib
import ssl
import urllib
import urllib2
import sys
from cookielib import LWPCookieJar
#/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
reload(sys)
sys.setdefaultencoding('UTF8')
cookiejar = LWPCookieJar()
cookiesuppor = urllib2.HTTPCookieProcessor(cookiejar)
opener = urllib2.build_opener(cookiesuppor, urllib2.HTTPHandler)
urllib2.install_opener(opener)
ssl._create_default_https_context = ssl._create_unverified_context
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
class myrequests:
def __init__(self,cookies):
self.s = requests.Session()
self.cookies = cookies
def headers(self):
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36',
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"X-Requested-With": "xmlHttpRequest",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Origin":"https://kyfw.12306.cn",
"Accept-Encoding":"gzip, deflate, br",
"Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"
}
return headers
def get(url):
try:
request = urllib2.Request(url=url)
request.add_header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
request.add_header('X-Requested-With', 'xmlHttpRequest')
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36')
request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init')
request.add_header('Accept', '*/*')
result = urllib2.urlopen(request).read()
assert isinstance(result, object)
def get(self,url):
result = self.s.get(url,headers=self.headers(),cookies=self.cookies, verify=False)
return result
def post(self,url,data):
result = self.s.post(url, allow_redirects=False,headers=self.headers(),cookies=self.cookies,data=data,verify=False)
return result
except httplib.error as e:
print e
pass
except urllib2.URLError as e:
print e
pass
except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError:
pass
def Post(url, data):
try:
request = urllib2.Request(url=url, data=urllib.urlencode(data))
# req.add_header('User-Agent', 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0')
# request = urllib2Post.Request(ajax_url, urllib.urlencode(dc))
request.add_header("Content-Type", "application/x-www-form-urlencoded;application/json;charset=utf-8")
request.add_header('X-Requested-With', 'xmlHttpRequest')
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36')
request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init')
request.add_header('Accept', '*/*')
# request.add_header('Accept-Encoding', 'gzip, deflate')
for i in range(3):
result = urllib2.urlopen(request).read()
if result:
return result
else:
print("返回结果为空,正在第{0}重试".format(i))
except httplib.error as e:
return e
except urllib2.URLError as e:
return e
except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError:
return ('error')
if __name__ == "__main__":
myrequests.get()
myrequests.post()

63
myUrllib/myurllib2.py.bak Normal file
View File

@@ -0,0 +1,63 @@
# -*- coding=utf-8 -*-
import httplib
import ssl
import urllib
import urllib2
import sys
from cookielib import LWPCookieJar
reload(sys)
sys.setdefaultencoding('UTF8')
cookiejar = LWPCookieJar()
cookiesuppor = urllib2.HTTPCookieProcessor(cookiejar)
opener = urllib2.build_opener(cookiesuppor, urllib2.HTTPHandler)
urllib2.install_opener(opener)
ssl._create_default_https_context = ssl._create_unverified_context
def get(url):
try:
request = urllib2.Request(url=url)
request.add_header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
request.add_header('X-Requested-With', 'xmlHttpRequest')
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36')
request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init')
request.add_header('Accept', '*/*')
result = urllib2.urlopen(request).read()
assert isinstance(result, object)
return result
except httplib.error as e:
print e
pass
except urllib2.URLError as e:
print e
pass
except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError:
pass
def Post(url, data):
try:
request = urllib2.Request(url=url, data=urllib.urlencode(data))
# req.add_header('User-Agent', 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0')
# request = urllib2Post.Request(ajax_url, urllib.urlencode(dc))
request.add_header("Content-Type", "application/x-www-form-urlencoded;application/json;charset=utf-8")
request.add_header('X-Requested-With', 'xmlHttpRequest')
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36')
request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init')
request.add_header('Accept', '*/*')
# request.add_header('Accept-Encoding', 'gzip, deflate')
for i in range(3):
result = urllib2.urlopen(request).read()
if result:
return result
else:
print("返回结果为空,正在第{0}重试".format(i))
except httplib.error as e:
return e
except urllib2.URLError as e:
return e
except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError:
return ('error')

View File

@@ -0,0 +1,66 @@
# -*- coding=utf-8 -*-
import http.client
import ssl
import urllib.request, urllib.parse, urllib.error
import urllib.request, urllib.error, urllib.parse
import sys
from http.cookiejar import LWPCookieJar
# import imp
#
# imp.reload(sys)
# sys.setdefaultencoding('UTF8')
cookiejar = LWPCookieJar()
cookiesuppor = urllib.request.HTTPCookieProcessor(cookiejar)
opener = urllib.request.build_opener(cookiesuppor, urllib.request.HTTPHandler)
urllib.request.install_opener(opener)
ssl._create_default_https_context = ssl._create_unverified_context
def get(url):
try:
request = urllib.request.Request(url=url)
request.add_header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
request.add_header('X-Requested-With', 'xmlHttpRequest')
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36')
request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init')
request.add_header('Accept', '*/*')
result = urllib.request.urlopen(request).read()
assert isinstance(result, object)
return result
except http.client.error as e:
print(e)
pass
except urllib.error.URLError as e:
print(e)
pass
except urllib.request.HTTPBasicAuthHandler as xxx_todo_changeme:
urllib.error.HTTPError = xxx_todo_changeme
pass
def Post(url, data):
try:
request = urllib.request.Request(url=url, data=urllib.parse.urlencode(data).encode(encoding='UTF8'))
# req.add_header('User-Agent', 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0')
# request = urllib2Post.Request(ajax_url, urllib.urlencode(dc))
request.add_header("Content-Type", "application/x-www-form-urlencoded;application/json;charset=utf-8")
request.add_header('X-Requested-With', 'xmlHttpRequest')
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36')
request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init')
request.add_header('Accept', '*/*')
# request.add_header('Accept-Encoding', 'gzip, deflate')
for i in range(3):
result = urllib.request.urlopen(request).read()
if result:
return result
else:
print(("返回结果为空,正在第{0}重试".format(i)))
except http.client.error as e:
return e
except urllib.error.URLError as e:
return e
except urllib.request.HTTPBasicAuthHandler as xxx_todo_changeme1:
urllib.error.HTTPError = xxx_todo_changeme1
return ('error')

View File

@@ -1,6 +1,6 @@
beautifulsoup4==4.5.3
bs4==0.0.1
PyYAML==3.12
PyYaml==3.12
six==1.10.0
requests==2.18.4
Pillow==5.0.0

13
run.py
View File

@@ -1,9 +1,14 @@
# -*- coding=utf-8 -*-
from init import login, select_ticket_info
from concurrent.futures import ThreadPoolExecutor
pool = ThreadPoolExecutor(max_workers=1)
def run(ticket_config):
#login.go_login(ticket_config).login()
select_ticket_info.select(ticket_config).main()
def run():
login.main()
select_ticket_info.select().main()
run()
f1 = pool.submit(run("ticket_config2.yaml"))

9
run.py.bak Normal file
View File

@@ -0,0 +1,9 @@
# -*- coding=utf-8 -*-
from init import login, select_ticket_info
def run():
login.main()
select_ticket_info.select().main()
run()

0
test Normal file
View File

BIN
tkcode

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB