Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f6541c521 | ||
|
|
89a7cae001 | ||
|
|
f2f87ac10f | ||
|
|
5e0a435c3e | ||
|
|
8bfd3864c3 | ||
|
|
69df1ac189 | ||
|
|
95354cefd8 | ||
|
|
2b0580e20c | ||
|
|
5a9f095319 | ||
|
|
0ffbe102e2 | ||
|
|
aa599d7d70 | ||
|
|
62f1785203 | ||
|
|
4d68360a24 | ||
|
|
8b78cab389 | ||
|
|
c1b572d9ec | ||
|
|
0747e2b01a |
51
.idea/workspace.xml
generated
51
.idea/workspace.xml
generated
@@ -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接口无响应的时候给出合理提示 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>
|
||||
|
||||
@@ -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分支
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
77
agency/agency_tools.py.bak
Normal file
77
agency/agency_tools.py.bak
Normal 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
46
config/emailConf.py
Normal 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()
|
||||
@@ -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"]
|
||||
#
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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里面有ret,id,result,cookie,根据自己的需要获取
|
||||
@@ -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
18
init/gol.py
Normal 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
|
||||
421
init/login.py
421
init/login.py
@@ -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.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8
|
||||
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×tamp=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.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8
|
||||
# 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
204
init/login.py.bak
Normal 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.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8
|
||||
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()
|
||||
@@ -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()
|
||||
671
init/select_ticket_info.py.bak
Normal file
671
init/select_ticket_info.py.bak
Normal 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()
|
||||
@@ -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
54
myUrllib/httpUtils.py.bak
Normal 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))
|
||||
@@ -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
63
myUrllib/myurllib2.py.bak
Normal 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')
|
||||
66
myUrllib/myurllib2.py.bak2.py
Normal file
66
myUrllib/myurllib2.py.bak2.py
Normal 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')
|
||||
@@ -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
|
||||
Pillow==5.0.0
|
||||
|
||||
13
run.py
13
run.py
@@ -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
9
run.py.bak
Normal 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()
|
||||
Reference in New Issue
Block a user