From 6b849c1201b97448bfd3c0b8def06a1f9e2310a7 Mon Sep 17 00:00:00 2001
From: wenxianping <931128603@qq.com>
Date: Wed, 29 Aug 2018 19:19:13 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93?=
=?UTF-8?q?=E6=9E=84=20=E6=96=B0=E5=A2=9E=E5=8F=8C=E4=B8=8B=E5=8D=95?=
=?UTF-8?q?=E6=96=B9=E6=B3=95=20=E4=BF=AE=E5=A4=8D=E4=B8=80=E7=9B=B4bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/12306.iml | 5 +-
.idea/12306login.iml | 11 -
.idea/codeStyleSettings.xml | 14 -
.idea/dictionaries/wenxianping.xml | 3 -
.idea/inspectionProfiles/Project_Default.xml | 49 +-
.../inspectionProfiles/profiles_settings.xml | 7 -
.idea/misc.xml | 5 +-
.idea/workspace.xml | 1810 ++++-------------
README.md | 166 +-
Update.md | 118 ++
config/TicketEnmu.py | 5 +
config/ticketConf.py | 17 +-
config/ticket_config.yaml | 114 +-
config/urlConf.py | 4 +-
init/SelectTicketInfoFast.py | 292 ---
init/login.py | 150 +-
init/select_ticket_info.py | 771 ++-----
inter/AutoSubmitOrderRequest.py | 74 +-
inter/CheckOrderInfo.py | 73 +
inter/CheckRandCodeAnsyn.py | 27 +
inter/CheckUser.py | 33 +
inter/ConfirmSingleForQueue.py | 96 +
inter/ConfirmSingleForQueueAsys.py | 14 +-
inter/GetPassCodeNewOrderAndLogin.py | 22 +
inter/GetPassengerDTOs.py | 3 +-
inter/GetQueueCount.py | 109 +
inter/GetQueueCountAsync.py | 59 +-
inter/GetRandCode.py | 79 +
inter/GetRepeatSubmitToken.py | 36 +
inter/Query.py | 40 +-
inter/QueryOrderWaitTime.py | 3 +-
inter/SubmitOrderRequest.py | 69 +
myUrllib/MySocketUtils.py | 202 ++
myUrllib/httpUtils.py | 78 +-
requirements.txt | 3 +-
run.py | 14 +-
36 files changed, 1686 insertions(+), 2889 deletions(-)
delete mode 100644 .idea/12306login.iml
delete mode 100644 .idea/codeStyleSettings.xml
delete mode 100755 .idea/dictionaries/wenxianping.xml
delete mode 100755 .idea/inspectionProfiles/profiles_settings.xml
create mode 100644 Update.md
delete mode 100755 init/SelectTicketInfoFast.py
create mode 100644 inter/CheckOrderInfo.py
create mode 100644 inter/CheckRandCodeAnsyn.py
create mode 100644 inter/CheckUser.py
create mode 100644 inter/ConfirmSingleForQueue.py
create mode 100644 inter/GetPassCodeNewOrderAndLogin.py
create mode 100644 inter/GetQueueCount.py
create mode 100644 inter/GetRandCode.py
create mode 100644 inter/GetRepeatSubmitToken.py
create mode 100644 inter/SubmitOrderRequest.py
create mode 100644 myUrllib/MySocketUtils.py
diff --git a/.idea/12306.iml b/.idea/12306.iml
index 774d532..3ae6b30 100644
--- a/.idea/12306.iml
+++ b/.idea/12306.iml
@@ -2,10 +2,11 @@
-
+
-
+
+
\ No newline at end of file
diff --git a/.idea/12306login.iml b/.idea/12306login.iml
deleted file mode 100644
index 774d532..0000000
--- a/.idea/12306login.iml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
deleted file mode 100644
index ffd7416..0000000
--- a/.idea/codeStyleSettings.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/dictionaries/wenxianping.xml b/.idea/dictionaries/wenxianping.xml
deleted file mode 100755
index 3891a03..0000000
--- a/.idea/dictionaries/wenxianping.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 2be4900..36e6057 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,10 +1,49 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100755
index c23ecac..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0ed3b43..1842d96 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,7 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 74336b6..808810c 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,24 +1,51 @@
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-=======
-
-
-
-
-
->>>>>>> Stashed changes
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -28,209 +55,54 @@
-
-
-
-
-<<<<<<< Updated upstream
-
-=======
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-=======
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
+
-
-
+
+
-<<<<<<< Updated upstream
-
-
-=======
-
-
->>>>>>> Stashed changes
-
-
-
+
+
-<<<<<<< Updated upstream
-
-
+
+
-
-
-
-=======
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-=======
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-
-=======
-
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-=======
-
-
+
+
-
-
-
+
+
->>>>>>> Stashed changes
+
+
+
+
+
+
+
-<<<<<<< Updated upstream
-
-
-=======
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-=======
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-=======
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-=======
-
->>>>>>> Stashed changes
-
+
+
@@ -246,142 +118,67 @@
-<<<<<<< Updated upstream
- 该车次小于上次提交时间
- 学生票
- checkRandCodeAnsyn
+ dto
+ get_passengerDTOs
+ passengerTicketStr
+ left_ticket_init
+ is_aotu_code
+ aotu_code_type
+ self.urlConf
+ self.httpClint
+ user_time
+ is_check_user
+ 加入小黑屋
+ _get_yaml
+ 小黑
+ sendConfirmSingleForQueueAsys
+ flo
+ unquote
+ confirmSingleForQueueAsys
+ getQueueCountAsync
+ is_more_ticket
+ damatu
select_refresh_interval
- checkOrderInfoUrl
- passenger
- checkOrderInfo
- resultOrderForDcQueue
- expect_refresh_interval
- validateMessages
- submitOrderRequest
- initdc_url
- confirmSingleForQueue
- initDc
- secretStr
- time
- state
- autoSubmitOrderRequest
- checkQueueOrderUrl
- map
- cdn_list
- req_url
- func
- is_logger
- is_logg
- 超时
- 118.180.15.113
- checku
- {u'status': True, u'validateMessagesShowId': u'_validatorMessage', u'messages': [], u'httpstatus': 200, u'validateMessages': {}, u'data': {u'flag': False}}
- init
-=======
- expect_refresh_interval
- validateMessages
- submitOrderRequest
- initdc_url
- confirmSingleForQueue
- initDc
- secretStr
- time
- state
- autoSubmitOrderRequest
- checkQueueOrderUrl
- map
- cdn_list
- req_url
- func
- is_logger
- is_logg
- 超时
- 118.180.15.113
- checku
- {u'status': True, u'validateMessagesShowId': u'_validatorMessage', u'messages': [], u'httpstatus': 200, u'validateMessages': {}, u'data': {u'flag': False}}
- threading
- init
- 下载验证码成功
- 正在获取cookie
- 获取
- loginInit
- check
- checkRandCodeAnsyn
- select_url
->>>>>>> Stashed changes
+ wap
+ 小黑屋
+
+ is_auto_code
+ auto_code_type
+ self.session.urls
+ self.session.httpClint
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
+
-
-
-
-
-
-=======
-
-
-
-
-
-
-
-
-
-
+
->>>>>>> Stashed changes
+
+
+
@@ -391,33 +188,19 @@
true
DEFINITION_ORDER
-
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
@@ -433,49 +216,41 @@
-<<<<<<< Updated upstream
-=======
+
+
+
+
->>>>>>> Stashed changes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-=======
->>>>>>> Stashed changes
-
-
-
-
-
-
-<<<<<<< Updated upstream
-=======
-
-
-
-
->>>>>>> Stashed changes
-
+
@@ -489,38 +264,9 @@
-<<<<<<< Updated upstream
-
-=======
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- project
-
-
-
-
-
-
+
+
@@ -531,53 +277,39 @@
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
-
+
-
-
-
+
-
+
@@ -588,64 +320,46 @@
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
@@ -653,520 +367,105 @@
-
+
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-=======
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
+
+
-
- 1495609226162
+
+ 1535103824843
- 1495609226162
+ 1535103824843
-
- 1515290076322
-
-
-
- 1515290076322
-
-
- 1515290185480
-
-
-
- 1515290185480
-
-
- 1515294755271
-
-
-
- 1515294755271
-
-
- 1515299804937
-
-
-
- 1515299804937
-
-
- 1515301465660
-
-
-
- 1515301465660
-
-
- 1515302485621
-
-
-
- 1515302485621
-
-
- 1515305208201
-
-
-
- 1515305208201
-
-
- 1515305972202
-
-
-
- 1515305972202
-
-
- 1515378140868
-
-
-
- 1515378140868
-
-
- 1515378364014
-
-
-
- 1515378364015
-
-
- 1515390735321
-
-
-
- 1515390735322
-
-
- 1515390744718
-
-
-
- 1515390744718
-
-
- 1515392209200
-
-
-
- 1515392209200
-
-
- 1515396490603
-
-
-
- 1515396490603
-
-
- 1515397442645
-
-
-
- 1515397442645
-
-
- 1515562610299
-
-
-
- 1515562610299
-
-
- 1515648875452
-
-
-
- 1515648875452
-
-
- 1515655531118
-
-
-
- 1515655531118
-
-
- 1515656580743
-
-
-
- 1515656580743
-
-
- 1515657697172
-
-
-
- 1515657697172
-
-
- 1515662814175
-
-
-
- 1515662814175
-
-
- 1515662876057
-
-
-
- 1515662876057
-
-
- 1515678242134
-
-
-
- 1515678242134
-
-
- 1515678353449
-
-
-
- 1515678353449
-
-
- 1516714146751
-
-
-
- 1516714146751
-
-
- 1516759585724
-
-
-
- 1516759585724
-
-
- 1516769778850
-
-
-
- 1516769778850
-
-
- 1516769863674
-
-
-
- 1516769863674
-
-
- 1516804524397
-
-
-
- 1516804524397
-
-
- 1516860947755
-
-
-
- 1516860947755
-
-
- 1516866756742
-
-
-
- 1516866756742
-
-
- 1516869457581
-
-
-
- 1516869457581
-
-
- 1516887378591
-
-
-
- 1516887378591
-
-
- 1516887559529
-
-
-
- 1516887559529
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-
-
-
-
-
-
-=======
-
- 1517234341941
-
-
-
- 1517234341941
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-=======
->>>>>>> Stashed changes
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1200,514 +499,279 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-=======
-
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-<<<<<<< Updated upstream
-
-
-=======
->>>>>>> Stashed changes
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-=======
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
+
+
-
+
-
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
-
-
-
-
+
-
-
-
+
+
-
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-=======
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-
-=======
-
-
-
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
+
-<<<<<<< Updated upstream
+
+
+
+
+
-
-
-
-=======
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-=======
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-=======
-
-
-
-
-
-
-
-
-
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-
-
-=======
-
-
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-
-
-
-=======
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-<<<<<<< Updated upstream
-
-
-=======
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
-
-
-
->>>>>>> Stashed changes
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index 0b9f55a..63b22a1 100755
--- a/README.md
+++ b/README.md
@@ -1,60 +1,16 @@
-### 12306
+#### 12306 购票小助手
- python版本支持
- - 2.7
+ - 2.7.10 - 2.7.15
- 依赖库
- - 依赖打码兔 需要去打码兔注册(用户)账号,打码兔账号地址:http://www.dama2.com, 一般充值1元就够用了,充值打码兔之后,首次运行是需要到官网黑白名单授权
- - 依赖若快 若快注册地址:http://www.ruokuai.com/client/index?6726 推荐用若快,打码兔在12306验证码更新之后识别率不是很高
+ - 依赖若快 若快注册地址:http://www.ruokuai.com/client/index?6726 推荐用若快,打码兔平台已经关闭
- 项目依赖包 requirements.txt
- 安装方法 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
- 项目使用说明
- 需要配置邮箱,可以配置可以不配置,配置邮箱的格式在yaml里面可以看到ex
- 提交订单验证码哪里依赖打码兔,所以如果是订票遇到验证码的时候,没有打码兔是过不了的,不推荐手动,手动太慢
- - 配置yaml文件的时候,需注意空格和遵循yaml语法格式,项目的yaml配置ex:
- - ticket_config.yaml 配置说明
- ```
- #station_date:出发日期改为多日期查询,格式ex:
- - "2018-02-03"
- - "2018-02-04"
- - "2018-02-05"
- #station_trains:过滤车次,格式ex:
- # - "G1353"
- # - "G1329"
- # - "G1355"
- # - "G1303"
- # - "G1357"
- # - "G1305"
- # - "G1359"
- # - "G1361"
- # - "G1373"
- # - "G1363"
- #from_station: 始发站
- #to_station: 到达站
- #set_type: 坐席(商务座,二等座,特等座,软卧,硬卧,硬座,无座)
- #is_more_ticket:余票不足是否自动提交
- #select_refresh_interval:抢票刷新间隔时间,1为一秒,0.1为100毫秒,以此类推 如果捡漏推荐为1秒,刷票设置0.01
- #expect_refresh_interval:售票未开始,等待刷新间隔时间,1为一秒,0.1为100毫秒,以此类推
- #ticket_black_list:加入小黑屋的等待时间,默认3 min 小黑屋的功能是上次买票失败,证明此票已无机会,下次刷新看到此票跳过
- #enable_proxy:是否开启代理模式,代理速度比较慢,如果是抢票阶段,不建议开启
- #ticke_peoples: 乘客 ex: "张三"
- #damatu:打码兔账号,用于自动登录和订单自动打码
- #is_aotu_code是否自动打码,如果选择Ture,则调用打码兔打码,默认不使用打码兔
- #is_email: 是否需要邮件通知 ex: True or False 切记,邮箱加完一定到config目录下测试emailConf功能是否正常
-
- #邮箱配置 列举163
- # email: "xxx@163.com"
- # notice_email_list: "123@qq.com"
- # username: "xxxxx"
- # password: "xxxxx
- # host: "smtp.163.com"
- #邮箱配置 列举qq ,qq设置比较复杂,需要在邮箱--账户--开启smtp服务,取得授权码==邮箱登录密码
- # email: "xxx@qq.com"
- # notice_email_list: "123@qq.com"
- # username: "xxxxx"
- # password: "授权码"
- # host: "smtp.qq.com"
- ```
+ - 配置yaml文件的时候,需注意空格和遵循yaml语法格式
- 项目开始
- 修改config/ticket_config.yaml文件,按照提示更改自己想要的信息
@@ -94,118 +50,6 @@
恭喜您订票成功,订单号为:EB52743573, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!
```
-- 2017.5.13跟新
- - 增加登陆错误判断(密码错误&ip校验)
- - 修改queryOrderWaitTime,校验orderId字段bug,校验msg字段bug,校验messagesbug
- - 修改checkQueueOrder 校验 data 字段的列表推导式bug
- - 增加代理ip方法,目前已可以过滤有用ip
-
-
-- 2018.1.7 号更新
- - 增加自动配置
- ```
- #station_date:出发日期,格式ex:2018-01-06
- #from_station: 始发站
- #to_station: 到达站
- #set_type: 坐席(商务座,二等座,特等座,软卧,硬卧,硬座,无座)
- #is_more_ticket:余票不足是否自动提交
- #select_refresh_interval:刷新间隔时间,1为一秒,0.1为100毫秒,以此类推
- #ticke_peoples: 乘客
- #damatu:打码图账号,用于自动登录
- ```
- - 优化订票流程
- - 支持自动刷票,自动订票
-
-- 2018.1.8 更新
- - 增加小黑屋功能
- - 修复bug若干
- - 增加多账号同时订票功能
- - 增加按照选定车次筛选购买车次
-
-- 2018.1.9 更新
-
- - 增加手动打码,只是登录接口,完全不用担心提交票的效率问题,要挂linux系统的话,还是去注册个打码兔吧
- ```
- 思路
- 1.调用PIL显示图片
- 2.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8
- 3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码,
- ```
- - 修改无座和硬座的座位号提交是个字符串的问题
- - 增加校验下单需要验证码功能
- - 增强下单成功判断接口校验
-
-- 2018.1.10 更新
- - 优化查票流程
- - 修改二等座的余票数返回为字符串的问题
- - 优化订单查询bug
-- 2018.1.12更新
- - 优化抢票页面逻辑
- -增强代码稳定性
-
-- 2018.1.13更新
- - 修改下单验证码功能
- - 优化大量调用user接口导致联系人不能用,理论加快订票速度
- - 增加邮箱功能
- ```
- #is_email: 是否需要邮件通知 ex: True or False 切记,邮箱加完一定要到config目录下测试emailConf功能是否正常
- #email: 发送的邮箱地址 ex: 1@qq.com
- #notice_email_list: 被通知人邮箱 ex: 2@qq.com
- #username: 邮箱账号
- #password: 邮箱密码
- #host: 邮箱地址
- ```
-
-- 2018.1.14更新
- - 优化订票流程
- - 优化挂机功能
- - 修改之前程序到11点自动跳出功能,现在修改为到早上7点自动开启刷票
- - 需要开启打码兔代码功能,is_aotu_code 设置为True
- - 增加异常判断
-
-- 2018.1.15更新
- - 增加捡漏自动检测是否登录功能,建议捡漏不要刷新太快,2S最好,否则会封IP
- - 优化提交订单有很大记录无限排队的情况,感谢群里的小伙伴提供的思路
- - 修改休眠时间为早上6点
-
-- 2018.1.20更新,好久没跟新了,群里的小伙伴说登录不行了,今晚抽空改了一版登录,妥妥的
- - 更新新版登录功能,经测试,更稳定有高效
- - 优化手动打码功能
- - 更新请求第三方库
- - 优化若干代码,小伙伴尽情的放肆起来
-
-- 2018.1.21跟新
- - 修复若干bug
- - 合并dev
- - 恢复之前因为12306改版引起的订票功能
- - 增加派对失败自动取消订单功能
- - 优化接口请求规范
- - 增加多日期查询,请严格按照yaml格式添加 即可
- - 注意:如果多日期查询的话,可能查询时间会比较长
- - 增加如果排队时间超过一分钟,自动取消订单
-
-- 2018.1.23更新
- - 增加若快平台打码,yaml新增字段aotu_code_type,1=打码兔,2=若快 若快注册地址:http://www.ruokuai.com/client/index?6726
- - 修改is_aotu_code字段为全部是否自动打码字段,也就是说字段为rue,则全部自动打码,为False全部手动打码,包括提交订单,注意centOs不可设置手动打码
- - 修复bug
- - 优化抢票功能
-
-- 2018.1.25更新
- - 删除 expect_refresh_interval 无用字段,优化代码
-
-- 2018.1.29更新
- - 增加cdn轮训功能,优势, is_cdn=1为开启cdn,2为普通查询
- - 能够一定程度躲避封ip
- - 查询余票快人一步
- - 提交订单快人一步
- - 僵尸票可能会少很多
- - 兼容Windows cmd命令乱码问题
- - 规范12306接口提交参数
- - 修改已知bug
- - 最后感谢群里提供测试和代码的小伙伴,能为你们买到一张回家的票真的感到灰常开心
-
-- 2018.2.28更新,收12306风控影响,代码可能有时候会进入慢排队,请自行调整刷新参数
- - 修改已知bug
- - 优化接口提交参数规范
+- [更新日志](Update.md)
diff --git a/Update.md b/Update.md
new file mode 100644
index 0000000..90cc739
--- /dev/null
+++ b/Update.md
@@ -0,0 +1,118 @@
+- 2017.5.13跟新
+ - 增加登陆错误判断(密码错误&ip校验)
+ - 修改queryOrderWaitTime,校验orderId字段bug,校验msg字段bug,校验messagesbug
+ - 修改checkQueueOrder 校验 data 字段的列表推导式bug
+ - 增加代理ip方法,目前已可以过滤有用ip
+
+
+- 2018.1.7 号更新
+ - 增加自动配置
+ ```
+ #station_date:出发日期,格式ex:2018-01-06
+ #from_station: 始发站
+ #to_station: 到达站
+ #set_type: 坐席(商务座,二等座,特等座,软卧,硬卧,硬座,无座)
+ #is_more_ticket:余票不足是否自动提交
+ #select_refresh_interval:刷新间隔时间,1为一秒,0.1为100毫秒,以此类推
+ #ticke_peoples: 乘客
+ #damatu:打码图账号,用于自动登录
+ ```
+ - 优化订票流程
+ - 支持自动刷票,自动订票
+
+- 2018.1.8 更新
+ - 增加小黑屋功能
+ - 修复bug若干
+ - 增加多账号同时订票功能
+ - 增加按照选定车次筛选购买车次
+
+- 2018.1.9 更新
+
+ - 增加手动打码,只是登录接口,完全不用担心提交票的效率问题,要挂linux系统的话,还是去注册个打码兔吧
+ ```
+ 思路
+ 1.调用PIL显示图片
+ 2.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8
+ 3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码,
+ ```
+ - 修改无座和硬座的座位号提交是个字符串的问题
+ - 增加校验下单需要验证码功能
+ - 增强下单成功判断接口校验
+
+- 2018.1.10 更新
+ - 优化查票流程
+ - 修改二等座的余票数返回为字符串的问题
+ - 优化订单查询bug
+- 2018.1.12更新
+ - 优化抢票页面逻辑
+ -增强代码稳定性
+
+- 2018.1.13更新
+ - 修改下单验证码功能
+ - 优化大量调用user接口导致联系人不能用,理论加快订票速度
+ - 增加邮箱功能
+ ```
+ #is_email: 是否需要邮件通知 ex: True or False 切记,邮箱加完一定要到config目录下测试emailConf功能是否正常
+ #email: 发送的邮箱地址 ex: 1@qq.com
+ #notice_email_list: 被通知人邮箱 ex: 2@qq.com
+ #username: 邮箱账号
+ #password: 邮箱密码
+ #host: 邮箱地址
+ ```
+
+- 2018.1.14更新
+ - 优化订票流程
+ - 优化挂机功能
+ - 修改之前程序到11点自动跳出功能,现在修改为到早上7点自动开启刷票
+ - 需要开启打码兔代码功能,is_auto_code 设置为True
+ - 增加异常判断
+
+- 2018.1.15更新
+ - 增加捡漏自动检测是否登录功能,建议捡漏不要刷新太快,2S最好,否则会封IP
+ - 优化提交订单有很大记录无限排队的情况,感谢群里的小伙伴提供的思路
+ - 修改休眠时间为早上6点
+
+- 2018.1.20更新,好久没跟新了,群里的小伙伴说登录不行了,今晚抽空改了一版登录,妥妥的
+ - 更新新版登录功能,经测试,更稳定有高效
+ - 优化手动打码功能
+ - 更新请求第三方库
+ - 优化若干代码,小伙伴尽情的放肆起来
+
+- 2018.1.21跟新
+ - 修复若干bug
+ - 合并dev
+ - 恢复之前因为12306改版引起的订票功能
+ - 增加派对失败自动取消订单功能
+ - 优化接口请求规范
+ - 增加多日期查询,请严格按照yaml格式添加 即可
+ - 注意:如果多日期查询的话,可能查询时间会比较长
+ - 增加如果排队时间超过一分钟,自动取消订单
+
+- 2018.1.23更新
+ - 增加若快平台打码,yaml新增字段auto_code_type,1=打码兔,2=若快 若快注册地址:http://www.ruokuai.com/client/index?6726
+ - 修改is_auto_code字段为全部是否自动打码字段,也就是说字段为rue,则全部自动打码,为False全部手动打码,包括提交订单,注意centOs不可设置手动打码
+ - 修复bug
+ - 优化抢票功能
+
+- 2018.1.25更新
+ - 删除 expect_refresh_interval 无用字段,优化代码
+
+- 2018.1.29更新
+ - 增加cdn轮训功能,优势, is_cdn=1为开启cdn,2为普通查询
+ - 能够一定程度躲避封ip
+ - 查询余票快人一步
+ - 提交订单快人一步
+ - 僵尸票可能会少很多
+ - 兼容Windows cmd命令乱码问题
+ - 规范12306接口提交参数
+ - 修改已知bug
+ - 最后感谢群里提供测试和代码的小伙伴,能为你们买到一张回家的票真的感到灰常开心
+
+- 2018.2.28更新,收12306风控影响,代码可能有时候会进入慢排队,请自行调整刷新参数
+ - 修改已知bug
+ - 优化接口提交参数规范
+
+- 2018.8.29更新,解决慢排队问题,增加双订票接口
+ - 修改已知bug
+ - 优化代码结构
+ - 新增第三方库wrapcache,需要重新安装requirements.txt
\ No newline at end of file
diff --git a/config/TicketEnmu.py b/config/TicketEnmu.py
index 21958a8..377e09f 100644
--- a/config/TicketEnmu.py
+++ b/config/TicketEnmu.py
@@ -33,3 +33,8 @@ class ticket(object):
CANCEL_ORDER_SUCCESS = u"排队超时,已为您自动取消订单,订单编号: {0}"
CANCEL_ORDER_FAIL = u"排队超时,取消订单失败, 订单号{0}"
+ REST_TIME = u"12306休息时间,本程序自动停止,明天早上6点将自动运行"
+ REST_TIME_PAST = u"休息时间已过,重新开启检票功能"
+
+ LOGIN_SESSION_FAIL = u"用户检查失败:{0},可能未登录,可能session已经失效, 正在重新登录中"
+
diff --git a/config/ticketConf.py b/config/ticketConf.py
index 9053b08..514aba3 100755
--- a/config/ticketConf.py
+++ b/config/ticketConf.py
@@ -13,19 +13,4 @@ def _get_yaml():
f = open(path)
s = yaml.load(f)
f.close()
- return s
-
-
-# def get_set_info():
-# return _get_yaml()["set"]
-#
-#
-# def get_ticke_peoples():
-# return _get_yaml()["ticke_peoples"]
-#
-#
-# def get_damatu():
-# return _get_yaml()["damatu"]
-#
-#
-# print _get_yaml()["set"]["12306count"]
\ No newline at end of file
+ return s
\ No newline at end of file
diff --git a/config/ticket_config.yaml b/config/ticket_config.yaml
index e5dc98b..6a5361b 100755
--- a/config/ticket_config.yaml
+++ b/config/ticket_config.yaml
@@ -1,78 +1,63 @@
---
-#station_date:出发日期,格式ex:2018-01-06
-#station_trains:过滤车次,格式ex:
- # - "G1353"
- # - "G1329"
- # - "G1355"
- # - "G1303"
- # - "G1357"
- # - "G1305"
- # - "G1359"
- # - "G1361"
- # - "G1373"
- # - "G1363"
-#from_station: 始发站
-#to_station: 到达站
-#set_type: 坐席(商务座,二等座,特等座,软卧,硬卧,硬座,无座)
-#is_more_ticket:余票不足是否自动提交
-#select_refresh_interval:抢票刷新间隔时间,1为一秒,0.1为100毫秒,以此类推 如果捡漏推荐为1秒,刷票设置0.01
-#expect_refresh_interval:售票未开始,等待刷新间隔时间,1为一秒,0.1为100毫秒,以此类推
-#ticket_black_list:加入小黑屋的等待时间,默认3 min
-#enable_proxy:是否开启代理模式,代理速度比较慢,如果是抢票阶段,不建议开启
-#ticke_peoples: 乘客
-#damatu:打码兔账号,用于自动登录
-#is_aotu_code是否自动打码,如果选择Ture,则调用打码兔打码,默认不使用打码兔
-#aotu_code_type 1为打码兔,2为若快
-#is_email: 是否需要邮件通知 ex: True or False 切记,邮箱加完一定到config目录下测试emailConf功能是否正常
+set:
+ # 出发日期,格式ex:2018-01-06
+ station_dates:
+ - "2018-09-05"
-#邮箱配置 列举163
+ # 过滤车次,格式ex:- "G1353" - "G1329"
+ station_trains:
+ - "G6504"
+
+ # 出发城市,比如深圳北,就填深圳就搜得到
+ from_station: "深圳"
+
+ # 到达城市 比如深圳北,就填深圳就搜得到
+ to_station: "广州"
+
+ # 座位 多个座位ex: - "二等座" - "一等座"
+ set_type:
+ - "二等座"
+
+ # 余票不足是否自动提交,目前应该没什么卵用
+ is_more_ticket: True
+
+ # 乘车人 多个乘车人ex: - "张三" - "李四"
+ ticke_peoples:
+ - ""
+ # 12306登录账号
+ 12306account:
+ - uesr: ""
+ - pwd: ""
+
+select_refresh_interval: 1
+
+# 加入小黑屋时间,此功能为了防止僵尸票导致一直下单不成功错过正常的票
+ticket_black_list_time: 5
+
+# 自动打码
+is_auto_code: False
+
+# 打码平台, 2 为若快平台(目前只支持若快平台打码,打码兔已经关闭), 若快注册地址:http://www.ruokuai.com/client/index?6726
+auto_code_type: 2
+
+# 打码平台账号
+auto_code_account:
+ uesr: ""
+ pwd: ""
+
+# 邮箱配置,如果抢票成功,将通过邮件配置通知给您
+# 列举163
# email: "xxx@163.com"
# notice_email_list: "123@qq.com"
# username: "xxxxx"
# password: "xxxxx
# host: "smtp.163.com"
-#邮箱配置 列举qq ,qq设置比较复杂,需要在邮箱--账户--开启smtp服务,取得授权码==邮箱登录密码
+# 列举qq ,qq设置比较复杂,需要在邮箱-->账户-->开启smtp服务,取得授权码==邮箱登录密码
# email: "xxx@qq.com"
# notice_email_list: "123@qq.com"
# username: "xxxxx"
# password: "授权码"
# host: "smtp.qq.com"
-
-
-set:
- station_dates:
- - "2018-06-21"
- - "2018-06-22"
-
- station_trains:
- - "G1321"
-
- from_station: "上海"
- to_station: "长沙"
- set_type:
- - "二等座"
- - "商务座"
- - "一等座"
- is_more_ticket: True
- ticke_peoples:
- - "文贤平"
-# - "彭淑杰"
- 12306count:
-# - uesr: ""
-# - pwd: "apple1995"
- - uesr: "931128603@qq.com"
- - pwd: "QWERTY"
-
-select_refresh_interval: 1
-ticket_black_list_time: 5
-is_aotu_code: False
-aotu_code_type: 2
-#enable_proxy: False
-
-damatu:
- uesr: ""
- pwd: "qazWSX1995"
-
email_conf:
is_email: True
email: "@qq.com "
@@ -81,8 +66,11 @@ email_conf:
password: ""
host: "smtp.qq.com"
+# 是否开启cdn查询,可以更快的检测飘飘 1为开启,2为关闭
is_cdn: 2
+# 下单接口分为两种,1 为快速下单,2 是普通下单
+order_type: 1
diff --git a/config/urlConf.py b/config/urlConf.py
index 1a79097..7671483 100755
--- a/config/urlConf.py
+++ b/config/urlConf.py
@@ -71,7 +71,7 @@ urls = {
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/index/init",
"Host": "kyfw.12306.cn",
- "re_try": 10,
+ "re_try": 1,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": False,
@@ -157,7 +157,7 @@ urls = {
},
"select_url": { # 查询余票
"req_url": "/otn/leftTicket/query?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT",
- "req_type": "post",
+ "req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Host": "kyfw.12306.cn",
"re_try": 10,
diff --git a/init/SelectTicketInfoFast.py b/init/SelectTicketInfoFast.py
deleted file mode 100755
index 15460df..0000000
--- a/init/SelectTicketInfoFast.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# -*- coding=utf-8 -*-
-import datetime
-import json
-import random
-import re
-import socket
-import sys
-import threading
-import time
-import urllib
-from collections import OrderedDict
-
-import collections
-
-from agency.cdn_utils import CDNProxy
-from config import urlConf
-from config.TicketEnmu import ticket
-from config.emailConf import sendEmail
-from config.ticketConf import _get_yaml
-from init import login
-from init.login import GoLogin
-from inter.AutoSubmitOrderRequest import autoSubmitOrderRequest
-from inter.ConfirmSingleForQueueAsys import confirmSingleForQueueAsys
-from inter.GetPassengerDTOs import getPassengerDTOs
-from inter.GetQueueCountAsync import getQueueCountAsync
-from inter.LiftTicketInit import liftTicketInit
-from inter.Query import query
-from inter.QueryOrderWaitTime import queryOrderWaitTime
-from myException.PassengerUserException import PassengerUserException
-from myException.UserPasswordException import UserPasswordException
-from myException.ticketConfigException import ticketConfigException
-from myException.ticketIsExitsException import ticketIsExitsException
-from myException.ticketNumOutException import ticketNumOutException
-from myUrllib.httpUtils import HTTPClient
-
-reload(sys)
-sys.setdefaultencoding('utf-8')
-
-
-class selectFast:
- """
- 快速提交车票通道
- """
-
- def __init__(self):
- self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time = self.get_ticket_info()
- self.is_aotu_code = _get_yaml()["is_aotu_code"]
- self.aotu_code_type = _get_yaml()["aotu_code_type"]
- self.is_cdn = _get_yaml()["is_cdn"]
- self.httpClint = HTTPClient()
- self.urls = urlConf.urls
- self.login = GoLogin(self.httpClint, self.urls, self.is_aotu_code, self.aotu_code_type)
- self.is_download_img = False
- self.cdn_list = []
- self.is_check_user = dict()
- self.ticket_black_list = dict()
- self.passengerTicketStrList = ""
- self.oldPassengerStr = ""
-
-
- 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_dates = ticket_info_config["set"]["station_dates"]
- 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"]
- ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
- print u"*" * 20
- print u"12306刷票小助手,最后更新于2018.2.28,请勿作为商业用途,交流群号:286271084"
- print u"如果有好的margin,请联系作者,表示非常感激\n"
- print u"当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:随机(1-4S)\n候选购买车次:{7}\n僵尸票关小黑屋时长:{8}\n".format \
- (
- from_station,
- to_station,
- station_dates,
- ",".join(set_type),
- is_more_ticket,
- ",".join(ticke_peoples),
- select_refresh_interval,
- ",".join(station_trains),
- ticket_black_list_time,
- )
- print u"*" * 20
- return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, ticket_black_list_time
-
- 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 call_login(self, auth=False):
- """
- 登录回调方法
- :return:
- """
- if auth:
- return self.login.auth()
- else:
- self.login.go_login()
-
- def check_user(self):
- """
- 检查用户是否达到订票条件
- :return:
- """
- check_user_url = self.urls["check_user_url"]
- data = {"_json_att": ""}
- check_user = self.httpClint.send(check_user_url, data)
- check_user_flag = check_user['data']['flag']
- if check_user_flag is True:
- self.is_check_user["user_time"] = datetime.datetime.now()
- else:
- if check_user['messages']:
- print (u'用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0])
- print (u'正在尝试重新登录')
- self.call_login()
- self.is_check_user["user_time"] = datetime.datetime.now()
- else:
- print (u'用户检查失败: %s,可能未登录,可能session已经失效' % check_user)
- print (u'正在尝试重新登录')
- self.call_login()
- self.is_check_user["user_time"] = datetime.datetime.now()
-
- def main(self):
- l = liftTicketInit(session=self)
- l.reqLiftTicketInit()
- self.call_login()
- self.check_user()
- from_station, to_station = self.station_table(self.from_station, self.to_station)
- passengerTicketStrList, oldPassengerStr, set_type = "", "", ""
- 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 > 5:
- # 5分钟检查一次用户是否登录
- self.check_user()
- time.sleep(self.select_refresh_interval)
- if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00" or time.strftime('%H:%M:%S',
- time.localtime(
- time.time())) < "06:00:00":
- print(u"12306休息时间,本程序自动停止,明天早上6点将自动运行")
- while 1:
- time.sleep(1)
- if "06:00:00" < time.strftime('%H:%M:%S', time.localtime(time.time())) < "23:00:00":
- print(u"休息时间已过,重新开启检票功能")
- self.call_login()
- break
- start_time = datetime.datetime.now()
-
- q = query(session=self,
- from_station=from_station,
- to_station=to_station,
- from_station_h=self.from_station,
- to_station_h=self.to_station,
- _station_seat=self._station_seat,
- station_trains=self.station_trains,
- station_dates=self.station_dates,)
- queryResult = q.sendQuery()
- # 查询接口
- if queryResult.get("status", False):
- secretStr = queryResult.get("secretStr", "")
- train_no = queryResult.get("train_no", "")
- stationTrainCode = queryResult.get("stationTrainCode", "")
- train_date = queryResult.get("train_date", "")
- query_from_station_name = queryResult.get("query_from_station_name", "")
- query_to_station_name = queryResult.get("query_to_station_name", "")
- set_type = queryResult.get("set_type", "")
- leftTicket = queryResult.get("leftTicket", "")
- 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(ticket.QUEUE_WARNING_MSG.format(train_no))
- else:
- # 获取联系人
- if not self.passengerTicketStrList and not self.oldPassengerStr:
- s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=set_type)
- getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr()
- if getPassengerDTOsResult.get("status", False):
- self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "")
- self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "")
- set_type = getPassengerDTOsResult.get("set_type", "")
- # 提交订单
- a = autoSubmitOrderRequest(session=self,
- secretStr=secretStr,
- train_date=train_date,
- query_from_station_name=self.from_station,
- query_to_station_name=self.to_station,
- passengerTicketStr=self.passengerTicketStrList,
- oldPassengerStr=self.oldPassengerStr
- )
- submitResult = a.sendAutoSubmitOrderRequest()
- if submitResult.get("status", False):
- result = submitResult.get("result", "")
- # 订单排队
- time.sleep(submitResult.get("ifShowPassCodeTime", 1))
- g = getQueueCountAsync(session=self,
- train_no=train_no,
- stationTrainCode=stationTrainCode,
- fromStationTelecode=query_from_station_name,
- toStationTelecode=query_to_station_name,
- leftTicket=leftTicket,
- set_type=set_type,
- users=len(self.ticke_peoples),
- )
- getQueueCountAsyncResult = g.sendGetQueueCountAsync()
- time.sleep(submitResult.get("ifShowPassCodeTime", 1))
- if getQueueCountAsyncResult.get("is_black", False):
- black_train_no = getQueueCountAsyncResult.get("train_no", "")
- self.ticket_black_list[black_train_no] = datetime.datetime.now()
- if getQueueCountAsyncResult.get("status", False):
- # 请求订单快读接口
- c = confirmSingleForQueueAsys(session=self,
- passengerTicketStr=self.passengerTicketStrList,
- oldPassengerStr=self.oldPassengerStr,
- result=result, )
- confirmSingleForQueueAsysResult = c.sendConfirmSingleForQueueAsys()
- # 排队
- if confirmSingleForQueueAsysResult.get("status", False):
- qwt = queryOrderWaitTime(session=self)
- qwt.sendQueryOrderWaitTime()
- else:
- self.httpClint.del_cookies()
-
- else:
- s_time = random.randint(0, 4)
- time.sleep(s_time)
- print u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP:{4}当前cdn总数:{5} 总耗时:{3}ms".format(num,
- ",".join(
- self.station_dates),
- ",".join(
- self.station_trains),
- (
- datetime.datetime.now() - start_time).microseconds / 1000,
- self.httpClint.cdn,
- len(
- self.cdn_list),
- s_time)
- 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 UserPasswordException as e:
- print e.message
- break
- except ValueError as e:
- if e.message == "No JSON object could be decoded":
- print(u"12306接口无响应,正在重试")
- else:
- print(e.message)
- except KeyError as e:
- print(e.message)
- # except TypeError as e:
- # print(u"12306接口无响应,正在重试 {0}".format(e.message))
- except socket.error as e:
- print(e.message)
-
-
-if __name__ == '__main__':
- s = selectFast()
- s.main()
- # a = select('上海', '北京')
- # a.main()
diff --git a/init/login.py b/init/login.py
index ccdd82f..09db4d7 100755
--- a/init/login.py
+++ b/init/login.py
@@ -1,5 +1,6 @@
#!/bin/env python
# -*- coding=utf-8 -*-
+import copy
import random
import json
import re
@@ -10,118 +11,25 @@ from config.ticketConf import _get_yaml
from PIL import Image
from damatuCode.damatuWeb import DamatuApi
from damatuCode.ruokuai import RClient
+from inter.GetPassCodeNewOrderAndLogin import getPassCodeNewOrderAndLogin
+from inter.GetRandCode import getRandCode
from myException.UserPasswordException import UserPasswordException
from myException.balanceException import balanceException
from myUrllib import myurllib2
class GoLogin:
- def __init__(self, httpClint, urlConf, is_aotu_code, aotu_code_type):
- self.httpClint = httpClint
+ def __init__(self, session, is_auto_code, auto_code_type):
+ self.session = session
self.randCode = ""
- self.urlConf = urlConf
- self.is_aotu_code = is_aotu_code
- self.aotu_code_type = aotu_code_type
-
- def cookietp(self):
- print(u"正在获取cookie")
- url = self.urlConf["loginInit"]
- self.httpClint.send(url)
-
- def getRandCode(self):
- """
- 识别验证码
- :return: 坐标
- """
- try:
- if self.is_aotu_code:
- if self.aotu_code_type == 1:
- return DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], "./tkcode").main()
- elif self.aotu_code_type == 2:
- rc = RClient(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"])
- im = open('./tkcode', 'rb').read()
- Result = rc.rk_create(im, 6113)
- if "Result" in Result:
- return self.codexy(Ofset=",".join(list(Result["Result"])), is_raw_input=False)
- else:
- if "Error" in Result and Result["Error"]:
- print Result["Error"]
- return ""
- else:
- img = Image.open('./tkcode')
- img.show()
- return self.codexy()
- except:
- pass
-
- def readImg(self, code_url):
- """
- 增加手动打码,只是登录接口,完全不用担心提交订单效率
- 思路
- 1.调用PIL显示图片
- 2.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8
- 3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码,
- :return:
- """
- print (u"下载验证码...")
- codeimgUrl = code_url
- img_path = './tkcode'
- result = self.httpClint.send(codeimgUrl)
- try:
- print(u"下载验证码成功")
- open(img_path, 'wb').write(result)
- except OSError as e:
- print (e)
-
- def codexy(self, Ofset=None, is_raw_input=True):
- """
- 获取验证码
- :return: str
- """
- if is_raw_input:
- Ofset = raw_input(u"请输入验证码: ")
- select = Ofset.split(',')
- 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(' ', '')
- print(u"验证码识别坐标为{0}".format(randCode))
- return randCode
+ self.is_auto_code = is_auto_code
+ self.auto_code_type = auto_code_type
def auth(self):
"""认证"""
- authUrl = self.urlConf["auth"]
+ authUrl = self.session.urls["auth"]
authData = {"appid": "otn"}
- tk = self.httpClint.send(authUrl, authData)
+ tk = self.session.httpClint.send(authUrl, authData)
return tk
def codeCheck(self):
@@ -129,13 +37,13 @@ class GoLogin:
验证码校验
:return:
"""
- codeCheck = self.urlConf["codeCheck"]
+ codeCheck = self.session.urls["codeCheck"]
codeCheckData = {
"answer": self.randCode,
"rand": "sjrand",
"login_site": "E"
}
- fresult = self.httpClint.send(codeCheck, codeCheckData)
+ fresult = self.session.httpClint.send(codeCheck, codeCheckData)
if "result_code" in fresult and fresult["result_code"] == "4":
print (u"验证码通过,开始登录..")
return True
@@ -143,7 +51,7 @@ class GoLogin:
if "result_message" in fresult:
print(fresult["result_message"])
sleep(1)
- self.httpClint.del_cookies()
+ self.session.httpClint.del_cookies()
def baseLogin(self, user, passwd):
"""
@@ -152,13 +60,13 @@ class GoLogin:
:param passwd:
:return: 权限校验码
"""
- logurl = self.urlConf["login"]
+ logurl = self.session.urls["login"]
logData = {
"username": user,
"password": passwd,
"appid": "otn"
}
- tresult = self.httpClint.send(logurl, logData)
+ tresult = self.session.httpClint.send(logurl, logData)
if 'result_code' in tresult and tresult["result_code"] == 0:
print (u"登录成功")
tk = self.auth()
@@ -185,9 +93,9 @@ class GoLogin:
if not uamtk:
return u"权限校验码不能为空"
else:
- uamauthclientUrl = self.urlConf["uamauthclient"]
+ uamauthclientUrl = self.session.urls["uamauthclient"]
data = {"tk": uamtk}
- uamauthclientResult = self.httpClint.send(uamauthclientUrl, data)
+ uamauthclientResult = self.session.httpClint.send(uamauthclientUrl, data)
if uamauthclientResult:
if "result_code" in uamauthclientResult and uamauthclientResult["result_code"] == 0:
print(u"欢迎 {} 登录".format(uamauthclientResult["username"]))
@@ -195,9 +103,9 @@ class GoLogin:
else:
return False
else:
- self.httpClint.send(uamauthclientUrl, data)
- url = self.urlConf["getUserInfo"]
- self.httpClint.send(url)
+ self.session.httpClint.send(uamauthclientUrl, data)
+ url = self.session.urls["getUserInfo"]
+ self.session.httpClint.send(url)
def go_login(self):
"""
@@ -206,27 +114,17 @@ class GoLogin:
:param passwd: 密码
:return:
"""
- if self.is_aotu_code and self.aotu_code_type == 1:
- balance = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"]).getBalance()
+ if self.is_auto_code and self.auto_code_type == 1:
+ balance = DamatuApi(_get_yaml()["auto_code_account"]["uesr"], _get_yaml()["auto_code_account"]["pwd"]).getBalance()
if int(balance) < 40:
raise balanceException(u'余额不足,当前余额为: {}'.format(balance))
- user, passwd = _get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"]
+ user, passwd = _get_yaml()["set"]["12306acount"][0]["uesr"], _get_yaml()["set"]["12306account"][1]["pwd"]
if not user or not passwd:
raise UserPasswordException(u"温馨提示: 用户名或者密码为空,请仔细检查")
login_num = 0
while True:
- self.cookietp()
- # self.httpClint.set_cookies(_jc_save_showIns="true",
- # _jc_save_wfdc_flag="dc",
- # _jc_save_toDate="2018-06-06",
- # _jc_save_fromDate=_get_yaml()["set"]["station_dates"][0],
- # RAIL_EXPIRATION="1528337042724",
- # RAIL_DEVICEID="O6DFHLmFChFrZUI7QyY9xcqj94eZG9JH_kD3zSZt53tkCUq0uqdvlo1fm_CmNxr_QAnMOU79JmHI8jbtj2vaNUnOZKCqcsMNbhCaoDIB3vxgsyzMMGOZF-CknXKEFaCLPGyDNXEknPDs7xgSbanwKqsiSRT41xti",
- #
- # )
- self.urlConf["getCodeImg"]["req_url"] = self.urlConf["getCodeImg"]["req_url"].format(random.random())
- self.readImg(self.urlConf["getCodeImg"])
- self.randCode = self.getRandCode()
+ getPassCodeNewOrderAndLogin(session=self.session, imgType="login")
+ self.randCode = getRandCode(self.is_auto_code, self.auto_code_type)
login_num += 1
self.auth()
if self.codeCheck():
diff --git a/init/select_ticket_info.py b/init/select_ticket_info.py
index f670ac3..20d431e 100755
--- a/init/select_ticket_info.py
+++ b/init/select_ticket_info.py
@@ -1,23 +1,22 @@
# -*- coding=utf-8 -*-
import datetime
-import json
import random
-import re
import socket
import sys
-import threading
import time
-import urllib
-from collections import OrderedDict
-import collections
+import wrapcache
-from agency.cdn_utils import CDNProxy
from config import urlConf
-from config.emailConf import sendEmail
+from config.TicketEnmu import ticket
from config.ticketConf import _get_yaml
-from init import login
from init.login import GoLogin
+from inter.AutoSubmitOrderRequest import autoSubmitOrderRequest
+from inter.CheckUser import checkUser
+from inter.GetPassengerDTOs import getPassengerDTOs
+from inter.LiftTicketInit import liftTicketInit
+from inter.Query import query
+from inter.SubmitOrderRequest import submitOrderRequest
from myException.PassengerUserException import PassengerUserException
from myException.UserPasswordException import UserPasswordException
from myException.ticketConfigException import ticketConfigException
@@ -30,28 +29,23 @@ sys.setdefaultencoding('utf-8')
class select:
+ """
+ 快速提交车票通道
+ """
+
def __init__(self):
- self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time = self.get_ticket_info()
- self.is_aotu_code = _get_yaml()["is_aotu_code"]
- self.aotu_code_type = _get_yaml()["aotu_code_type"]
+ self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, \
+ self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time, \
+ self.order_type = self.get_ticket_info()
+ self.is_auto_code = _get_yaml()["is_auto_code"]
+ self.auto_code_type = _get_yaml()["auto_code_type"]
self.is_cdn = _get_yaml()["is_cdn"]
- self.order_request_params = {} # 订单提交时的参数
- self.ticketInfoForPassengerForm = {} # 初始化当前页面参数
- self.current_seats = {} # 席别信息
- self.token = ""
- self.set_type = ""
- self.user_info = ""
- self.secretStr = ""
- self.ticket_black_list = dict()
- self.ticket_black_list_time = dict()
- self.is_check_user = dict()
self.httpClint = HTTPClient()
- self.confUrl = urlConf.urls
- self.login = GoLogin(self.httpClint, self.confUrl, self.is_aotu_code, self.aotu_code_type)
- self.is_download_img = False
- self.randCode = ""
+ self.urls = urlConf.urls
+ self.login = GoLogin(self, self.is_auto_code, self.auto_code_type)
self.cdn_list = []
- self.buy_ticket_time = ""
+ self.passengerTicketStrList = ""
+ self.oldPassengerStr = ""
def get_ticket_info(self):
"""
@@ -68,58 +62,26 @@ class select:
select_refresh_interval = ticket_info_config["select_refresh_interval"]
station_trains = ticket_info_config["set"]["station_trains"]
ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
- print u"*"*20
+ order_type = ticket_info_config["order_type"]
+ print u"*" * 20
print u"12306刷票小助手,最后更新于2018.2.28,请勿作为商业用途,交流群号:286271084"
print u"如果有好的margin,请联系作者,表示非常感激\n"
- print u"当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:{6}s(如果想随机刷新,请自行修改)\n候选购买车次:{7}\n僵尸票关小黑屋时长:{8}\n".format\
- (
- from_station,
- to_station,
- station_dates,
- ",".join(set_type),
- is_more_ticket,
- ",".join(ticke_peoples),
- select_refresh_interval,
- ",".join(station_trains),
- ticket_black_list_time,
+ print u"当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n" \
+ u"刷新间隔:随机(1-4S)\n候选购买车次:{7}\n僵尸票关小黑屋时长:{8}\n 下单接口:{9}\n".format \
+ (
+ from_station,
+ to_station,
+ station_dates,
+ ",".join(set_type),
+ is_more_ticket,
+ ",".join(ticke_peoples),
+ select_refresh_interval,
+ ",".join(station_trains),
+ ticket_black_list_time,
+ order_type,
)
- print u"*"*20
- return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, 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]
+ print u"*" * 20
+ return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, ticket_black_list_time, order_type
def station_table(self, from_station, to_station):
"""
@@ -138,534 +100,6 @@ class select:
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 today.strftime('%Y-%m-%d')
-
- def callReadImg(self, code_url):
- """
- 下载验证码
- :param code_url: 验证码url
- :return:
- """
- self.login.readImg(code_url=code_url)
- self.is_aotu_code = True
-
- def callRandCode(self):
- """
- 识别验证码
- :return:
- """
- while True:
- if self.is_aotu_code:
- self.randCode = self.login.getRandCode()
- self.is_aotu_code = False
-
- def getRepeatSubmitToken(self):
- """
- 获取提交车票请求token
- :return: token
- """
- initdc_url = self.confUrl["initdc_url"]
- initdc_result = self.httpClint.send(initdc_url,)
- token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'")
- ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?')
- order_request_params_name = re.compile(r'var orderRequestDTO=(\{.+\})?')
- 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 GetJS(self):
- getJSUrl = self.confUrl["GetJS"]
- self.httpClint.send(getJSUrl)
- odxmfwgUrl = self.confUrl["odxmfwg"]
- self.httpClint.send(odxmfwgUrl)
-
- def getPassengerDTOs(self):
- """
- 获取乘客信息
- :return:
- """
- get_passengerDTOs = self.confUrl["get_passengerDTOs"]
- get_data = {
- '_json_att': None,
- 'REPEAT_SUBMIT_TOKEN': self.token
- }
- jsonData = self.httpClint.send(get_passengerDTOs, get_data)
- if 'data' in jsonData and jsonData['data'] and 'l' in jsonData['data'] and 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(u"未查找到常用联系人")
- raise PassengerUserException(u"未查找到常用联系人,请先添加联系人在试试")
-
- def submitOrderRequestFunc(self, from_station, to_station, station_date=None):
- self.confUrl["select_url"]["req_url"] = self.confUrl["select_url"]["req_url"].format(
- station_date, from_station, to_station)
- station_ticket = self.httpClint.send(self.confUrl["select_url"])
- return json.loads(station_ticket)
-
- def submitOrderRequestImplement(self, from_station, to_station,):
- """
- 提交车次信息
- 车次对应字典
- {32: '商务座 ',
- 31: '一等座 ',
- 30: '二等座 ',
- 25: '特等座 ',
- 23: '软卧 ',
- 28: '硬卧 ',
- 29: '硬座 ',
- 26: '无座 '
- } 参照station_seat()方法
- :return:
- """
- station_tickets = [self.submitOrderRequestFunc(from_station, to_station, station_date) for station_date in self.station_dates]
- for station_ticket in station_tickets:
- value = station_ticket['data']
- if not value:
- print (u'{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 (u'车次: ' + 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(u"该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
- break
- else:
- print (u'正在尝试提交订票...')
- self.buy_ticket_time = datetime.datetime.now()
- # self.submitOrderRequestFunc(from_station, to_station, self.time())
- self.submit_station()
- self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
- self.getRepeatSubmitToken()
- if not self.user_info: # 修改每次都调用用户接口导致用户接口不能用
- self.user_info = self.getPassengerDTOs()
- codeImgByOrder = self.confUrl["codeImgByOrder"]
- self.login.readImg(codeImgByOrder)
- if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")):
- break
- else:
- pass
- else:
- pass
- # time.sleep(self.expect_refresh_interval)
- else:
- print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
-
- def check_user(self):
- """
- 检查用户是否达到订票条件
- :return:
- """
- check_user_url = self.confUrl["check_user_url"]
- data = {"_json_att": ""}
- check_user = self.httpClint.send(check_user_url, data)
- check_user_flag = check_user['data']['flag']
- if check_user_flag is True:
- self.is_check_user["user_time"] = datetime.datetime.now()
- else:
- if check_user['messages']:
- print (u'用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0])
- print (u'正在尝试重新登录')
- self.call_login()
- self.is_check_user["user_time"] = datetime.datetime.now()
- else:
- print (u'用户检查失败: %s,可能未登录,可能session已经失效' % check_user)
- print (u'正在尝试重新登录')
- self.call_login()
- self.is_check_user["user_time"] = datetime.datetime.now()
-
- def submit_station(self):
- """
- 提交车次
- 预定的请求参数,注意参数顺序
- 注意这里为了防止secretStr被urllib.parse过度编码,在这里进行一次解码
- 否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败
- :param self:
- :param secretStr: 提交车次加密
- :return:
- """
- submit_station_url = self.confUrl["submit_station_url"]
- data = [('secretStr', urllib.unquote(self.secretStr)), # 字符串加密
- ('train_date', self.station_dates[0]), # 出发时间
- ('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 = self.httpClint.send(submit_station_url, data)
- if 'data' in submitResult and submitResult['data']:
- if submitResult['data'] == 'N':
- print (u'出票成功')
- else:
- print (u'出票失败')
- 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(u"联系人不在列表中,请查证后添加")
- if len(self.user_info) is 1:
- passengerTicketStrList.append(
- '0,' + self.user_info[0]['passenger_type'] + "," + self.user_info[0][
- "passenger_name"] + "," +
- self.user_info[0]['passenger_id_type_code'] + "," + 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_id_type_code'] + "," +
- 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_type'] + "," + self.user_info[i][
- "passenger_name"] + "," + self.user_info[i]['passenger_id_type_code'] + "," + 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_id_type_code'] + "," +
- 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 = self.confUrl["checkOrderInfoUrl"]
- data = collections.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 = self.httpClint.send(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 (u'车票提交通过,正在尝试排队')
- 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 = self.confUrl["getQueueCountUrl"]
- data = collections.OrderedDict()
- data['train_date'] = str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)",
- data['train_no'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'],
- data['stationTrainCode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['station_train_code'],
- data['seatType'] = self.set_type,
- data['fromStationTelecode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['from_station'],
- data['toStationTelecode'] = self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['to_station'],
- data['leftTicket'] = self.get_ticketInfoForPassengerForm()['leftTicketStr'],
- data['purpose_codes'] = self.get_ticketInfoForPassengerForm()['purpose_codes'],
- data['train_location'] = self.get_ticketInfoForPassengerForm()['train_location'],
- data['REPEAT_SUBMIT_TOKEN'] = self.get_token(),
- getQueueCountResult = self.httpClint.send(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
- countT = getQueueCountResult["data"]["countT"]
- if int(countT) is 0:
- if int(ticket_split) < len(self.user_info):
- print(u"当前余票数小于乘车人数,放弃订票")
- else:
- print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split))
- if self.checkQueueOrder(is_need_code):
- return True
- else:
- print(u"当前排队人数: {1} 当前余票还剩余:{0} 张,继续排队中".format(ticket_split, countT))
- else:
- print(u"排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountResult, train_no))
- self.ticket_black_list[train_no] = datetime.datetime.now()
- elif "messages" in getQueueCountResult and getQueueCountResult["messages"]:
- print(u"排队异常,错误信息:{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(u"未知错误 {0}".format("".join(getQueueCountResult)))
-
- def checkRandCodeAnsyn(self, randCode):
- """
- 识别验证码
- :return: 识别结果
- """
- checkRandCodeAnsyn = self.confUrl["checkRandCodeAnsyn"]
- randData = {
- "randCode": randCode,
- "rand": "randp",
- "_json_att": None,
- "REPEAT_SUBMIT_TOKEN": self.get_token()
- }
- fresult = self.httpClint.send(checkRandCodeAnsyn, randData) # 校验验证码是否正确
- return fresult['data']['msg']
-
- def checkQueueOrder(self, is_node_code=False):
- """
- 模拟提交订单是确认按钮,参数获取方法还是get_ticketInfoForPassengerForm 中获取
- :return:
- """
-
- passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
- checkQueueOrderUrl = self.confUrl["checkQueueOrderUrl"]
- 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": "",
- "randCode": "",
- "choose_seats": "",
- "REPEAT_SUBMIT_TOKEN": self.get_token(),
- }
- try:
- if is_node_code:
- print(u"正在使用自动识别验证码功能")
- for i in range(3):
- randCode = self.login.getRandCode()
- checkcode = self.checkRandCodeAnsyn(randCode)
- if checkcode == 'TRUE':
- print(u"验证码通过,正在提交订单")
- data['randCode'] = randCode
- break
- else:
- print (u"验证码有误, {0}次尝试重试".format(i+1))
- print(u"验证码超过限定次数3次,放弃此次订票机会!")
- else:
- print(u"不需要验证码")
- buy_end_time = (datetime.datetime.now() - self.buy_ticket_time).seconds
- print(u"总共花费时长{0}S".format(buy_end_time))
- time.sleep(8-buy_end_time if buy_end_time<8 else 0)
- checkQueueOrderResult = self.httpClint.send(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(u"提交订单成功!")
- self.queryOrderWaitTime()
- else:
- if 'errMsg' in c_data and c_data['errMsg']:
- print(u"提交订单失败,{0}".format(c_data['errMsg']))
- else:
- print(c_data)
- print(u'订票失败!很抱歉,请重试提交预订功能!')
- elif "messages" in checkQueueOrderResult and checkQueueOrderResult["messages"]:
- print(u"提交订单失败,错误信息: " + checkQueueOrderResult["messages"])
- else:
- print(u"提交订单中,请耐心等待:" + checkQueueOrderResult["message"])
- except ValueError:
- print(u"接口 {} 无响应".format(checkQueueOrderUrl))
-
- def queryOrderWaitTime(self):
- """
- 排队获取订单等待信息,每隔3秒请求一次,最高请求次数为20次!
- :return:
- """
- num = 1
- while True:
- _random = int(round(time.time() * 1000))
- num += 1
- if num > 30:
- print(u"超出排队时间,自动放弃,正在重新刷票")
- order_id = self.queryMyOrderNoComplete() # 排队失败,自动取消排队订单
- if order_id:
- self.cancelNoCompleteMyOrder(order_id)
- break
- try:
- data = {"random": _random, "tourFlag": "dc"}
- queryOrderWaitTimeUrl = self.confUrl["queryOrderWaitTimeUrl"]
- queryOrderWaitTimeResult = self.httpClint.send(queryOrderWaitTimeUrl, data)
- 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(u"恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!".format(queryOrderWaitTimeResult["data"]["orderId"]))
- raise ticketIsExitsException(u"恭喜您订票成功,订单号为:{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(u"排队等待时间预计还剩 {0} ms".format(0-queryOrderWaitTimeResult["data"]["waitTime"]))
- else:
- print (u"正在等待中")
- elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
- print(u"排队等待失败: " + queryOrderWaitTimeResult["messages"])
- else:
- print(u"第{}次排队中,请耐心等待".format(num+1))
- else:
- print(u"排队中")
- time.sleep(2)
-
- else:
- print(ticketNumOutException(u"订单提交失败!,正在重新刷票"))
-
- def queryMyOrderNoComplete(self):
- """
- 获取订单列表信息
- :return:
- """
- self.initNoComplete()
- queryMyOrderNoCompleteUrl = self.confUrl["queryMyOrderNoCompleteUrl"]
- data = {"_json_att": ""}
- try:
- queryMyOrderNoCompleteResult = self.httpClint.send(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(u"接口 {} 无响应".format(queryMyOrderNoCompleteUrl))
-
- def initNoComplete(self):
- """
- 获取订单前需要进入订单列表页,获取订单列表页session
- :return:
- """
- self.httpClint.set_cookies(acw_tc="AQAAAEnFJnekLwwAtGHjZZCr79B6dpXk", current_captcha_type="Z")
- initNoCompleteUrl = self.confUrl["initNoCompleteUrl"]
- data = {"_json_att": ""}
- self.httpClint.send(initNoCompleteUrl, data)
-
- def cancelNoCompleteMyOrder(self, sequence_no):
- """
- 取消订单
- :param sequence_no: 订单编号
- :return:
- """
- cancelNoCompleteMyOrderUrl = self.confUrl["cancelNoCompleteMyOrder"]
- cancelNoCompleteMyOrderData = {
- "sequence_no": sequence_no,
- "cancel_flag": "cancel_order",
- "_json_att": ""
- }
- cancelNoCompleteMyOrderResult = self.httpClint.send(cancelNoCompleteMyOrderUrl, cancelNoCompleteMyOrderData)
- if "data" in cancelNoCompleteMyOrderResult and "existError" in cancelNoCompleteMyOrderResult["data"] and cancelNoCompleteMyOrderResult["data"]["existError"] == "N":
- print(u"排队超时,已为您自动取消订单,订单编号: {0}".format(sequence_no))
- time.sleep(2)
- return True
- else:
- print(u"排队超时,取消订单失败, 订单号{0}".format(sequence_no))
-
- def set_cdn(self):
- """
- 设置cdn
- :return:
- """
- if self.is_cdn == 1:
- while True:
- if self.cdn_list:
- self.httpClint.cdn = self.cdn_list[random.randint(0, len(self.cdn_list)-1)]
- break
- else:
- pass
-
def call_login(self, auth=False):
"""
登录回调方法
@@ -676,67 +110,96 @@ class select:
else:
self.login.go_login()
- def cdn_req(self, cdn):
- for i in range(len(cdn)-1):
- http = HTTPClient()
- urls = self.confUrl["loginInit"]
- start_time = datetime.datetime.now()
- http.cdn = cdn[i].replace("\n", "")
- rep = http.send(urls)
- if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 200:
- self.cdn_list.append(cdn[i].replace("\n", ""))
- print(u"所有cdn解析完成...")
-
- def cdn_certification(self):
- """
- cdn 认证
- :return:
- """
- if self.is_cdn == 1:
- CDN = CDNProxy()
- all_cdn = CDN.all_cdn()
- if all_cdn:
- print(u"开启cdn查询")
- print(u"本次待筛选cdn总数为{}".format(len(all_cdn)))
- t = threading.Thread(target=self.cdn_req, args=(all_cdn,))
- t.start()
- else:
- raise ticketConfigException(u"cdn列表为空,请先加载cdn")
- else:
- pass
-
def main(self):
- self.cdn_certification()
- self.set_cdn()
+ l = liftTicketInit(session=self)
+ l.reqLiftTicketInit()
self.call_login()
+ checkUser(self).sendCheckUser()
from_station, to_station = self.station_table(self.from_station, self.to_station)
- self.check_user()
- time.sleep(0.1)
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 > 5:
- # 5分钟检查一次用户是否登录
- self.check_user()
+ checkUser(self).sendCheckUser()
time.sleep(self.select_refresh_interval)
- if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00" or time.strftime('%H:%M:%S', time.localtime(time.time())) < "06:00:00":
- print(u"12306休息时间,本程序自动停止,明天早上6点将自动运行")
+ if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00" or time.strftime('%H:%M:%S',
+ time.localtime(
+ time.time())) < "06:00:00":
+ print(ticket.REST_TIME)
while 1:
time.sleep(1)
- if time.strftime('%H:%M:%S', time.localtime(time.time())) > "06:00:00":
- print(u"休息时间已过,重新开启检票功能")
+ if "06:00:00" < time.strftime('%H:%M:%S', time.localtime(time.time())) < "23:00:00":
+ print(ticket.REST_TIME_PAST)
self.call_login()
break
start_time = datetime.datetime.now()
- self.submitOrderRequestImplement(from_station, to_station)
- print u"正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 cdn轮询IP {4} 当前cdn总数{5} 总耗时{3}ms".format(num,
- ",".join(self.station_dates),
- ",".join(self.station_trains),
- (datetime.datetime.now()-start_time).microseconds/1000,
- self.httpClint.cdn,
- len(self.cdn_list))
- self.set_cdn()
+
+ q = query(session=self,
+ from_station=from_station,
+ to_station=to_station,
+ from_station_h=self.from_station,
+ to_station_h=self.to_station,
+ _station_seat=self._station_seat,
+ station_trains=self.station_trains,
+ station_dates=self.station_dates, )
+ queryResult = q.sendQuery()
+ # 查询接口
+ if queryResult.get("status", False):
+ train_no = queryResult.get("train_no", "")
+ train_date = queryResult.get("train_date", "")
+ stationTrainCode = queryResult.get("stationTrainCode", "")
+ set_type = queryResult.get("set_type", "")
+ secretStr = queryResult.get("secretStr", "")
+ leftTicket = queryResult.get("leftTicket", "")
+ query_from_station_name = queryResult.get("query_from_station_name", "")
+ query_to_station_name = queryResult.get("query_to_station_name", "")
+ if wrapcache.get(train_no):
+ print(ticket.QUEUE_WARNING_MSG.format(train_no))
+ else:
+ # 获取联系人
+ if not self.passengerTicketStrList and not self.oldPassengerStr:
+ s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=set_type)
+ getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr()
+ if getPassengerDTOsResult.get("status", False):
+ self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "")
+ self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "")
+ set_type = getPassengerDTOsResult.get("set_type", "")
+ # 提交订单
+ if self.order_type == 1: # 快读下单
+ a = autoSubmitOrderRequest(session=self,
+ secretStr=secretStr,
+ train_date=train_date,
+ passengerTicketStr=self.passengerTicketStrList,
+ oldPassengerStr=self.oldPassengerStr,
+ train_no=train_no,
+ stationTrainCode=stationTrainCode,
+ leftTicket=leftTicket,
+ set_type=set_type,
+ query_from_station_name=query_from_station_name,
+ query_to_station_name=query_to_station_name,
+ )
+ a.sendAutoSubmitOrderRequest()
+ elif self.order_type == 2: # 普通下单
+ sor = submitOrderRequest(self, secretStr, from_station, to_station, train_no, set_type,
+ self.passengerTicketStrList, self.oldPassengerStr, train_date,
+ self.ticke_peoples)
+ sor.sendSubmitOrderRequest()
+
+
+ else:
+ s_time = random.randint(0, 4)
+ time.sleep(s_time)
+ print u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP:{4}当前cdn总数:{5} 总耗时:{3}ms".format(num,
+ ",".join(
+ self.station_dates),
+ ",".join(
+ self.station_trains),
+ (
+ datetime.datetime.now() - start_time).microseconds / 1000,
+ self.httpClint.cdn,
+ len(
+ self.cdn_list),
+ s_time)
except PassengerUserException as e:
print e.message
break
@@ -766,6 +229,4 @@ class select:
if __name__ == '__main__':
- login()
- # a = select('上海', '北京')
- # a.main()
\ No newline at end of file
+ pass
\ No newline at end of file
diff --git a/inter/AutoSubmitOrderRequest.py b/inter/AutoSubmitOrderRequest.py
index f9a7053..e4639f3 100644
--- a/inter/AutoSubmitOrderRequest.py
+++ b/inter/AutoSubmitOrderRequest.py
@@ -3,6 +3,10 @@ import urllib
from collections import OrderedDict
from config.TicketEnmu import ticket
+from config.ticketConf import _get_yaml
+from inter.CheckRandCodeAnsyn import checkRandCodeAnsyn
+from inter.GetQueueCountAsync import getQueueCountAsync
+from inter.GetRandCode import getRandCode
class autoSubmitOrderRequest:
@@ -15,7 +19,11 @@ class autoSubmitOrderRequest:
query_from_station_name,
query_to_station_name,
passengerTicketStr,
- oldPassengerStr):
+ oldPassengerStr,
+ train_no,
+ stationTrainCode,
+ leftTicket,
+ set_type,):
self.secretStr = urllib.unquote(secretStr)
self.train_date = train_date
self.query_from_station_name = query_from_station_name
@@ -23,6 +31,10 @@ class autoSubmitOrderRequest:
self.passengerTicketStr = passengerTicketStr
self.oldPassengerStr = oldPassengerStr
self.session = session
+ self.train_no = train_no
+ self.stationTrainCode = stationTrainCode
+ self.leftTicket = leftTicket
+ self.set_type = set_type
def data_par(self):
"""
@@ -46,8 +58,8 @@ class autoSubmitOrderRequest:
data["train_date"] = self.train_date
data["tour_flag"] = "dc"
data["purpose_codes"] = "ADULT"
- data["query_from_station_name"] = self.query_from_station_name
- data["query_to_station_name"] = self.query_to_station_name
+ data["query_from_station_name"] = self.session.from_station
+ data["query_to_station_name"] = self.session.to_station
data["cancel_flag"] = 2
data["bed_level_order_num"] = "000000000000000000000000000000"
data["passengerTicketStr"] = self.passengerTicketStr
@@ -69,40 +81,42 @@ class autoSubmitOrderRequest:
if requestResultData:
result = requestResultData.get("result", "")
ifShowPassCode = requestResultData.get("ifShowPassCode", "N")
+ ifShowPassCodeTime = int(requestResultData.get("ifShowPassCodeTime", "1000")) / float(1000)
print(ticket.AUTO_SUBMIT_ORDER_REQUEST_C)
+ g = getQueueCountAsync(session=self.session,
+ train_no=self.train_no,
+ stationTrainCode=self.stationTrainCode,
+ fromStationTelecode=self.query_from_station_name,
+ toStationTelecode=self.query_to_station_name,
+ leftTicket=self.leftTicket,
+ set_type=self.set_type,
+ users=len(self.session.ticke_peoples),
+ station_dates=self.train_date,
+ passengerTicketStr=self.passengerTicketStr,
+ oldPassengerStr=self.oldPassengerStr,
+ result=result,
+ ifShowPassCodeTime=ifShowPassCodeTime,
+ )
+ g.sendGetQueueCountAsync()
if ifShowPassCode == "Y": # 如果需要验证码
- print(ticket.AUTO_SUBMIT_NEED_CODE)
- return {
- "result": result,
- "ifShowPassCode": ifShowPassCode,
- "code": ticket.SUCCESS_CODE,
- "ifShowPassCodeTime": requestResultData.get("requestResultData", 2000) / float(1000),
- "status": True,
- }
- else:
- print(ticket.AUTO_SUBMIT_NOT_NEED_CODE)
- return {
- "result": result,
- "ifShowPassCode": ifShowPassCode,
- "code": ticket.SUCCESS_CODE,
- "ifShowPassCodeTime": requestResultData.get("requestResultData", 2000) / float(1000),
- "status": True,
- }
+ print(u"需要验证码")
+ print(u"正在使用自动识别验证码功能")
+ for i in range(3):
+ randCode = getRandCode(is_auto_code=True, auto_code_type=_get_yaml()["auto_code_type"])
+ checkcode = checkRandCodeAnsyn(self.session, randCode, "")
+ if checkcode == 'TRUE':
+ print(u"验证码通过,正在提交订单")
+ data['randCode'] = randCode
+ break
+ else:
+ print (u"验证码有误, {0}次尝试重试".format(i + 1))
+ print(u"验证码超过限定次数3次,放弃此次订票机会!")
+ g.sendGetQueueCountAsync()
else:
print(ticket.AUTO_SUBMIT_ORDER_REQUEST_F)
if autoSubmitOrderRequestResult.get("messages", ""):
print(autoSubmitOrderRequestResult.get("messages", ""))
- return {
- "code": ticket.FAIL_CODE,
- "status": False,
- }
elif autoSubmitOrderRequestResult.get("validateMessages", ""):
print(autoSubmitOrderRequestResult.get("validateMessages", ""))
- return {
- "code": ticket.FAIL_CODE,
- "status": False,
- }
-
-
diff --git a/inter/CheckOrderInfo.py b/inter/CheckOrderInfo.py
new file mode 100644
index 0000000..76ea92c
--- /dev/null
+++ b/inter/CheckOrderInfo.py
@@ -0,0 +1,73 @@
+# coding=utf-8
+from collections import OrderedDict
+from inter.GetQueueCount import getQueueCount
+from inter.GetRepeatSubmitToken import getRepeatSubmitToken
+
+
+class checkOrderInfo:
+
+ def __init__(self, session, train_no, set_type, passengerTicketStrList, oldPassengerStr, station_dates, ticket_peoples):
+ self.train_no = train_no
+ self.set_type = set_type
+ self.passengerTicketStrList = passengerTicketStrList
+ self.oldPassengerStr = oldPassengerStr
+ self.station_dates = station_dates
+ self.ticket_peoples = ticket_peoples
+ self.RepeatSubmitToken = getRepeatSubmitToken(session)
+ self.getTicketInfoForPassengerForm = self.RepeatSubmitToken.sendGetRepeatSubmitToken()
+ self.ticketInfoForPassengerForm = self.getTicketInfoForPassengerForm.get("ticketInfoForPassengerForm", "")
+ self.token = self.getTicketInfoForPassengerForm.get("token", "")
+ self.session = self.getTicketInfoForPassengerForm.get("session", "")
+
+ def data_par(self):
+ """
+ 参数结构
+ :return:
+ """
+ data = OrderedDict()
+ data['passengerTicketStr'] = self.passengerTicketStrList.rstrip("_{0}".format(self.set_type))
+ data['oldPassengerStr'] = self.oldPassengerStr
+ data['REPEAT_SUBMIT_TOKEN'] = self.token
+ data['randCode'] = ""
+ data['cancel_flag'] = 2
+ data['bed_level_order_num'] = "000000000000000000000000000000"
+ data['tour_flag'] = 'dc'
+ data['_json_att'] = ""
+ return data
+
+ def sendCheckOrderInfo(self):
+ """
+ 检查支付订单,需要提交REPEAT_SUBMIT_TOKEN
+ passengerTicketStr : 座位编号,0,票类型,乘客名,证件类型,证件号,手机号码,保存常用联系人(Y或N)
+ oldPassengersStr: 乘客名,证件类型,证件号,乘客类型
+ :return:
+ """
+ CheckOrderInfoUrls = self.session.urls["checkOrderInfoUrl"]
+ data = self.data_par()
+ checkOrderInfoRep = self.session.httpClint.send(CheckOrderInfoUrls, data)
+ if 'data' in checkOrderInfoRep:
+ print (u'车票提交通过,正在尝试排队')
+ ifShowPassCodeTime = int(checkOrderInfoRep["data"]["ifShowPassCodeTime"]) / float(1000)
+ if "ifShowPassCode" in checkOrderInfoRep["data"] and checkOrderInfoRep["data"]["ifShowPassCode"] == "Y":
+ is_need_code = True
+ elif "ifShowPassCode" in checkOrderInfoRep["data"] and checkOrderInfoRep['data']['submitStatus'] is True:
+ is_need_code = False
+ else:
+ is_need_code = False
+ QueueCount = getQueueCount(self.session,
+ is_need_code,
+ ifShowPassCodeTime,
+ self.set_type,
+ self.station_dates,
+ self.train_no,
+ self.ticket_peoples,
+ self.ticketInfoForPassengerForm,
+ self.token,
+ self.oldPassengerStr,
+ self.passengerTicketStrList,
+ )
+ QueueCount.sendGetQueueCount()
+ elif "errMsg" in checkOrderInfoRep['data'] and checkOrderInfoRep['data']["errMsg"]:
+ print checkOrderInfoRep['data']["errMsg"]
+ elif 'messages' in checkOrderInfoRep and checkOrderInfoRep['messages']:
+ print (checkOrderInfoRep['messages'][0])
\ No newline at end of file
diff --git a/inter/CheckRandCodeAnsyn.py b/inter/CheckRandCodeAnsyn.py
new file mode 100644
index 0000000..d541288
--- /dev/null
+++ b/inter/CheckRandCodeAnsyn.py
@@ -0,0 +1,27 @@
+# coding=utf-8
+class checkRandCodeAnsyn:
+ def __init__(self, session, randCode, token):
+ self.session = session
+ self.randCode = randCode
+ self.token = token
+
+ def data_par(self):
+ """
+ :return:
+ """
+ data = {
+ "randCode": self.randCode,
+ "rand": "randp",
+ "_json_att": "",
+ "REPEAT_SUBMIT_TOKEN": self.token
+ }
+ return data
+
+ def sendCheckRandCodeAnsyn(self):
+ """
+ 下单验证码识别
+ :return:
+ """
+ checkRandCodeAnsynUrl = self.session.urls["checkRandCodeAnsyn"]
+ fresult = self.session.httpClint.send(checkRandCodeAnsynUrl, self.data_par()) # 校验验证码是否正确
+ return fresult['data']['msg']
\ No newline at end of file
diff --git a/inter/CheckUser.py b/inter/CheckUser.py
new file mode 100644
index 0000000..81af1ea
--- /dev/null
+++ b/inter/CheckUser.py
@@ -0,0 +1,33 @@
+# coding=utf-8
+import datetime
+import wrapcache
+
+from config.TicketEnmu import ticket
+
+
+class checkUser:
+ def __init__(self, session):
+ self.session = session
+
+ def sendCheckUser(self):
+ """
+ 检查用户登录, 检查间隔为五分钟
+ :return:
+ """
+ if wrapcache.get("user_time") is None:
+ check_user_url = self.session.urls["check_user_url"]
+ data = {"_json_att": ""}
+ check_user = self.session.httpClint.send(check_user_url, data)
+ if check_user.get("data", False):
+ check_user_flag = check_user["data"]["flag"]
+ if check_user_flag is True:
+ wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * 5)
+ else:
+ if check_user['messages']:
+ print (ticket.LOGIN_SESSION_FAIL.format(check_user['messages']))
+ self.session.call_login()
+ wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * 5)
+ else:
+ print (ticket.LOGIN_SESSION_FAIL.format(check_user['messages']))
+ self.session.call_login()
+ wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * 5)
\ No newline at end of file
diff --git a/inter/ConfirmSingleForQueue.py b/inter/ConfirmSingleForQueue.py
new file mode 100644
index 0000000..afa1ac4
--- /dev/null
+++ b/inter/ConfirmSingleForQueue.py
@@ -0,0 +1,96 @@
+# coding=utf-8
+import datetime
+import time
+
+from config.ticketConf import _get_yaml
+from inter.CheckRandCodeAnsyn import checkRandCodeAnsyn
+from inter.GetPassengerDTOs import getPassengerDTOs
+from inter.GetRandCode import getRandCode
+from inter.QueryOrderWaitTime import queryOrderWaitTime
+
+
+class confirmSingleForQueue:
+ def __init__(self, session, ifShowPassCodeTime, is_node_code, token, set_type, ticket_peoples, ticketInfoForPassengerForm,
+ oldPassengerStr, passengerTicketStrList):
+ self.session = session
+ self.ifShowPassCodeTime = ifShowPassCodeTime
+ self.is_node_code = is_node_code
+ self.token = token
+ self.set_type = set_type
+ self.ticket_peoples = ticket_peoples
+ self.ticketInfoForPassengerForm = ticketInfoForPassengerForm
+ self.passengerTicketStrList = passengerTicketStrList
+ self.oldPassengerStr = oldPassengerStr
+
+ def data_par(self):
+ """
+ 模拟提交订单是确认按钮,参数获取方法还是get_ticketInfoForPassengerForm 中获取
+ :return:
+ """
+ if not self.passengerTicketStrList and not self.oldPassengerStr:
+ s = getPassengerDTOs(session=self.session, ticket_peoples=self.ticket_peoples, set_type=self.set_type)
+ getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr()
+ if getPassengerDTOsResult.get("status", False):
+ self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "")
+ self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "")
+ data = {
+ "passengerTicketStr": self.passengerTicketStrList.rstrip("_{0}".format(self.set_type)),
+ "oldPassengerStr": "".join(self.oldPassengerStr),
+ "purpose_codes": self.ticketInfoForPassengerForm["purpose_codes"],
+ "key_check_isChange": self.ticketInfoForPassengerForm["key_check_isChange"],
+ "leftTicketStr": self.ticketInfoForPassengerForm["leftTicketStr"],
+ "train_location": self.ticketInfoForPassengerForm["train_location"],
+ "seatDetailType": "", # 开始需要选择座位,但是目前12306不支持自动选择作为,那这个参数为默认
+ "roomType": "00", # 好像是根据一个id来判断选中的,两种 第一种是00,第二种是10,但是我在12306的页面没找到该id,目前写死是00,不知道会出什么错
+ "dwAll": "N",
+ "whatsSelect": 1,
+ "_json_at": "",
+ "randCode": "",
+ "choose_seats": "",
+ "REPEAT_SUBMIT_TOKEN": self.token,
+ }
+ return data
+
+ def sendConfirmSingleForQueue(self):
+ """
+ # 模拟查询当前的列车排队人数的方法
+ # 返回信息组成的提示字符串
+ :return:
+ """
+ data = self.data_par()
+ checkQueueOrderUrl = self.session.urls["checkQueueOrderUrl"]
+ try:
+ if self.is_node_code:
+ print(u"正在使用自动识别验证码功能")
+ for i in range(3):
+ randCode = getRandCode(is_auto_code=True, auto_code_type=_get_yaml()["auto_code_type"])
+ checkcode = checkRandCodeAnsyn(self.session, randCode, self.token)
+ if checkcode == 'TRUE':
+ print(u"验证码通过,正在提交订单")
+ data['randCode'] = randCode
+ break
+ else:
+ print (u"验证码有误, {0}次尝试重试".format(i + 1))
+ print(u"验证码超过限定次数3次,放弃此次订票机会!")
+ else:
+ print(u"不需要验证码")
+ time.sleep(self.ifShowPassCodeTime)
+ checkQueueOrderResult = self.session.httpClint.send(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(u"提交订单成功!")
+ qow = queryOrderWaitTime(self.session)
+ qow.sendQueryOrderWaitTime()
+ else:
+ if 'errMsg' in c_data and c_data['errMsg']:
+ print(u"提交订单失败,{0}".format(c_data['errMsg']))
+ else:
+ print(c_data)
+ print(u'订票失败!很抱歉,请重试提交预订功能!')
+ elif "messages" in checkQueueOrderResult and checkQueueOrderResult["messages"]:
+ print(u"提交订单失败,错误信息: " + checkQueueOrderResult["messages"])
+ else:
+ print(u"提交订单中,请耐心等待:" + checkQueueOrderResult["message"])
+ except ValueError:
+ print(u"接口 {} 无响应".format(checkQueueOrderUrl))
\ No newline at end of file
diff --git a/inter/ConfirmSingleForQueueAsys.py b/inter/ConfirmSingleForQueueAsys.py
index 0499dc6..194fa2b 100644
--- a/inter/ConfirmSingleForQueueAsys.py
+++ b/inter/ConfirmSingleForQueueAsys.py
@@ -3,6 +3,8 @@ import json
import urllib
from collections import OrderedDict
+from inter.QueryOrderWaitTime import queryOrderWaitTime
+
class confirmSingleForQueueAsys:
"""
@@ -64,15 +66,7 @@ class confirmSingleForQueueAsys:
if confirmSingleForQueueAsysResult.get("status", False) and confirmSingleForQueueAsysResult.get("data", False):
queueData = confirmSingleForQueueAsysResult.get("data", {})
if queueData.get("submitStatus", False):
- return {
- "status": True
- }
+ qwt = queryOrderWaitTime(session=self.session)
+ qwt.sendQueryOrderWaitTime()
else:
print(queueData.get("errMsg", ""))
- return {
- "status": False
- }
- else:
- return {
- "status": False
- }
\ No newline at end of file
diff --git a/inter/GetPassCodeNewOrderAndLogin.py b/inter/GetPassCodeNewOrderAndLogin.py
new file mode 100644
index 0000000..3445b14
--- /dev/null
+++ b/inter/GetPassCodeNewOrderAndLogin.py
@@ -0,0 +1,22 @@
+# coding=utf-8
+
+
+def getPassCodeNewOrderAndLogin(session, imgType):
+ """
+ 下载验证码
+ :param session:
+ :param imgType: 下载验证码类型,login=登录验证码,其余为订单验证码
+ :return:
+ """
+ if imgType == "login":
+ codeImgUrl = session.urls["getCodeImg"]
+ else:
+ codeImgUrl = session.urls["codeImgByOrder"]
+ print (u"下载验证码...")
+ img_path = './tkcode'
+ result = session.httpClint.send(codeImgUrl)
+ try:
+ print(u"下载验证码成功")
+ open(img_path, 'wb').write(result)
+ except OSError as e:
+ print (e)
diff --git a/inter/GetPassengerDTOs.py b/inter/GetPassengerDTOs.py
index a50c572..f577cb9 100644
--- a/inter/GetPassengerDTOs.py
+++ b/inter/GetPassengerDTOs.py
@@ -56,7 +56,7 @@ class getPassengerDTOs:
"""
获取提交车次人内容格式
passengerTicketStr O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N
- oldPassengerStr 文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1_
+ oldPassengerStr 文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1
:return:
"""
passengerTicketStrList = []
@@ -89,4 +89,5 @@ class getPassengerDTOs:
"code": ticket.SUCCESS_CODE,
"set_type": set_type,
"status": True,
+ "user_info": user_info,
}
diff --git a/inter/GetQueueCount.py b/inter/GetQueueCount.py
new file mode 100644
index 0000000..f2fc0a2
--- /dev/null
+++ b/inter/GetQueueCount.py
@@ -0,0 +1,109 @@
+# coding=utf-8
+import datetime
+import time
+from collections import OrderedDict
+import wrapcache
+
+from config.ticketConf import _get_yaml
+from inter.ConfirmSingleForQueue import confirmSingleForQueue
+
+
+def conversion_int(str):
+ return int(str)
+
+
+class getQueueCount:
+ def __init__(self, session, is_need_code, ifShowPassCodeTime, set_type, station_dates, train_no, ticket_peoples,
+ ticketInfoForPassengerForm, token, oldPassengerStr, passengerTicketStrList):
+ self.station_dates = station_dates
+ self.session = session
+ self.is_need_code = is_need_code
+ self.ifShowPassCodeTime = ifShowPassCodeTime
+ self.set_type = set_type
+ self.train_no = train_no
+ self.ticket_peoples = ticket_peoples
+ self.ticket_black_list = {}
+ self.ticketInfoForPassengerForm = ticketInfoForPassengerForm
+ self.token = token
+ self.oldPassengerStr = oldPassengerStr
+ self.passengerTicketStrList = passengerTicketStrList
+
+ def data_par(self):
+ """
+ 参数结构
+ 自动提交代码接口-autoSubmitOrderRequest
+ - 字段说明
+ - secretStr 车票代码
+ - train_date 乘车日期
+ - tour_flag 乘车类型
+ - purpose_codes 学生还是成人
+ - query_from_station_name 起始车站
+ - query_to_station_name 结束车站
+ - cancel_flag 默认2,我也不知道干嘛的
+ - bed_level_order_num 000000000000000000000000000000
+ - passengerTicketStr 乘客乘车代码
+ - oldPassengerStr 乘客编号代码
+ :return:
+ """
+
+ new_train_date = filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" "))
+ data = OrderedDict()
+ data['train_date'] = "{0} {1} 0{2} {3} 00:00:00 GMT+0800 (中国标准时间)".format(
+ new_train_date[0],
+ new_train_date[1],
+ new_train_date[2],
+ new_train_date[4],
+ ),
+ data['train_no'] = self.ticketInfoForPassengerForm['queryLeftTicketRequestDTO']['train_no'],
+ data['stationTrainCode'] = self.ticketInfoForPassengerForm['queryLeftTicketRequestDTO'][
+ 'station_train_code'],
+ data['seatType'] = self.set_type,
+ data['fromStationTelecode'] = self.ticketInfoForPassengerForm['queryLeftTicketRequestDTO'][
+ 'from_station'],
+ data['toStationTelecode'] = self.ticketInfoForPassengerForm['queryLeftTicketRequestDTO']['to_station'],
+ data['leftTicket'] = self.ticketInfoForPassengerForm['leftTicketStr'],
+ data['purpose_codes'] = self.ticketInfoForPassengerForm['purpose_codes'],
+ data['train_location'] = self.ticketInfoForPassengerForm['train_location'],
+ data['REPEAT_SUBMIT_TOKEN'] = self.token,
+ return data
+
+ def sendGetQueueCount(self):
+ """
+ # 模拟查询当前的列车排队人数的方法
+ # 返回信息组成的提示字符串
+ :return:
+ """
+ getQueueCountResult = self.session.httpClint.send(self.session.urls["getQueueCountUrl"], self.data_par())
+ if "status" in getQueueCountResult and getQueueCountResult["status"] is True:
+ if "countT" in getQueueCountResult["data"]:
+ ticket = getQueueCountResult["data"]["ticket"]
+ ticket_split = sum(map(conversion_int, ticket.split(","))) if ticket.find(",") != -1 else ticket
+ countT = getQueueCountResult["data"]["countT"]
+ if int(countT) is 0:
+ if int(ticket_split) < len(self.ticket_peoples):
+ print(u"当前余票数小于乘车人数,放弃订票")
+ else:
+ print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split))
+ csf = confirmSingleForQueue(self.session, self.ifShowPassCodeTime, self.is_need_code, self.token,
+ self.set_type, self.ticket_peoples, self.ticketInfoForPassengerForm,
+ self.oldPassengerStr, self.passengerTicketStrList)
+ csf.sendConfirmSingleForQueue()
+ else:
+ print(u"当前排队人数: {1} 当前余票还剩余:{0} 张,继续排队中".format(ticket_split, countT))
+ else:
+ print(u"排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountResult, self.train_no))
+ wrapcache.set(key=self.train_no, value=datetime.datetime.now(),
+ timeout=int(_get_yaml()["ticket_black_list_time"]) * 60)
+ elif "messages" in getQueueCountResult and getQueueCountResult["messages"]:
+ print(u"排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋".format(getQueueCountResult["messages"][0], self.train_no))
+ wrapcache.set(key=self.train_no, value=datetime.datetime.now(), timeout=int(_get_yaml()["ticket_black_list_time"]) * 60)
+ else:
+ if "validateMessages" in getQueueCountResult and getQueueCountResult["validateMessages"]:
+ print(str(getQueueCountResult["validateMessages"]))
+ wrapcache.set(key=self.train_no, value=datetime.datetime.now(),
+ timeout=int(_get_yaml()["ticket_black_list_time"]) * 60)
+ else:
+ print(u"未知错误 {0}".format("".join(getQueueCountResult)))
+
+
+
diff --git a/inter/GetQueueCountAsync.py b/inter/GetQueueCountAsync.py
index 040810f..b9ef235 100644
--- a/inter/GetQueueCountAsync.py
+++ b/inter/GetQueueCountAsync.py
@@ -1,8 +1,13 @@
# coding=utf-8
+import datetime
import time
from collections import OrderedDict
+import wrapcache
+
from config.TicketEnmu import ticket
+from config.ticketConf import _get_yaml
+from inter.ConfirmSingleForQueueAsys import confirmSingleForQueueAsys
class getQueueCountAsync:
@@ -17,7 +22,12 @@ class getQueueCountAsync:
toStationTelecode,
leftTicket,
set_type,
- users,):
+ users,
+ station_dates,
+ passengerTicketStr,
+ oldPassengerStr,
+ result,
+ ifShowPassCodeTime):
self.train_no = train_no
self.session = session
self.stationTrainCode = stationTrainCode
@@ -26,6 +36,11 @@ class getQueueCountAsync:
self.set_type = set_type
self.leftTicket = leftTicket
self.users = users
+ self.station_dates = station_dates
+ self.passengerTicketStr = passengerTicketStr
+ self.oldPassengerStr = oldPassengerStr
+ self.result = result
+ self.ifShowPassCodeTime=ifShowPassCodeTime
def data_par(self):
"""
@@ -41,11 +56,15 @@ class getQueueCountAsync:
- _json_att 没啥卵用,还是带上吧
:return:
"""
- l_time = time.localtime(time.time())
- new_train_date = time.strftime("%b %d %Y %H:%M:%S", l_time)
+ new_train_date = filter(None, str(time.asctime(time.strptime(self.station_dates, "%Y-%m-%d"))).split(" "))
data = OrderedDict()
- # data["train_date"] = "Fri " + str(new_train_date) + " GMT+0800 (CST)"
- data["train_date"] = "Fri Jun 21 2018 18:23:54 GMT+0800 (CST)"
+ data['train_date'] = "{0} {1} {2} {3} 00:00:00 GMT+0800 (中国标准时间)".format(
+ new_train_date[0],
+ new_train_date[1],
+ new_train_date[2],
+ new_train_date[4],
+ time.strftime("%H:%M:%S", time.localtime(time.time()))
+ ),
data["train_no"] = self.train_no
data["stationTrainCode"] = self.stationTrainCode
data["seatType"] = self.set_type
@@ -76,27 +95,27 @@ class getQueueCountAsync:
countT = getQueueCountAsyncResult["data"]["countT"]
if int(countT) is 0:
if int(ticket_split) < self.users:
- print(ticket.QUEUE_TICKET_SHORT)
- return {"status": False, "is_black": False}
+ print(u"当前余票数小于乘车人数,放弃订票")
else:
- print(ticket.QUEUE_TICKET_SUCCESS.format(ticket_split))
- return {"status": True, "is_black": False}
- else:
- return {"status": False, "is_black": True}
+ print(u"排队成功, 当前余票还剩余: {0} 张".format(ticket_split))
+ c = confirmSingleForQueueAsys(session=self.session,
+ passengerTicketStr=self.passengerTicketStr,
+ oldPassengerStr=self.oldPassengerStr,
+ result=self.result,)
+ print(u"验证码提交安全期,等待{}MS".format(self.ifShowPassCodeTime))
+ time.sleep(self.ifShowPassCodeTime)
+ c.sendConfirmSingleForQueueAsys()
else:
- print(ticket.QUEUE_JOIN_BLACK.format(getQueueCountAsyncResult, self.train_no))
- return {"status": False, "is_black": True, "train_no": self.train_no}
+ print(u"排队发现未知错误{0},将此列车 {1}加入小黑屋".format(getQueueCountAsyncResult, self.train_no))
+ wrapcache.set(key=self.train_no, value=datetime.datetime.now(),
+ timeout=int(_get_yaml()["ticket_black_list_time"]) * 60)
elif "messages" in getQueueCountAsyncResult and getQueueCountAsyncResult["messages"]:
- print(ticket.QUEUE_WARNING_MSG.format(getQueueCountAsyncResult["messages"][0], self.train_no))
- return {"status": False, "is_black": True, "train_no": self.train_no}
+ print(u"排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋".format(getQueueCountAsyncResult["messages"][0], self.train_no))
+ wrapcache.set(key=self.train_no, value=datetime.datetime.now(),
+ timeout=int(_get_yaml()["ticket_black_list_time"]) * 60)
else:
if "validateMessages" in getQueueCountAsyncResult and getQueueCountAsyncResult["validateMessages"]:
print(str(getQueueCountAsyncResult["validateMessages"]))
- return {"status": False, "is_black": False}
- else:
- return {"status": False, "is_black": False}
- else:
- return {"status": False, "is_black": False}
diff --git a/inter/GetRandCode.py b/inter/GetRandCode.py
new file mode 100644
index 0000000..ae6402e
--- /dev/null
+++ b/inter/GetRandCode.py
@@ -0,0 +1,79 @@
+# coding=utf-8
+from PIL import Image
+
+from config.ticketConf import _get_yaml
+from damatuCode.ruokuai import RClient
+
+
+def getRandCode(is_auto_code, auto_code_type):
+ """
+ 识别验证码
+ :return: 坐标
+ """
+ try:
+ if is_auto_code:
+ if auto_code_type == 1:
+ print(u"打码兔已关闭, 如需使用自动识别,请使用如果平台 auto_code_type == 2")
+ return
+ if auto_code_type == 2:
+ rc = RClient(_get_yaml()["auto_code_account"]["uesr"], _get_yaml()["auto_code_account"]["pwd"])
+ im = open('./tkcode', 'rb').read()
+ Result = rc.rk_create(im, 6113)
+ if "Result" in Result:
+ return codexy(Ofset=",".join(list(Result["Result"])), is_raw_input=False)
+ else:
+ if "Error" in Result and Result["Error"]:
+ print Result["Error"]
+ return ""
+ else:
+ img = Image.open('./tkcode')
+ img.show()
+ return codexy()
+ except:
+ pass
+
+
+def codexy(Ofset=None, is_raw_input=True):
+ """
+ 获取验证码
+ :return: str
+ """
+ if is_raw_input:
+ Ofset = raw_input(u"请输入验证码: ")
+ Ofset = Ofset.replace(",", ",")
+ select = Ofset.split(',')
+ 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(' ', '')
+ print(u"验证码识别坐标为{0}".format(randCode))
+ return randCode
diff --git a/inter/GetRepeatSubmitToken.py b/inter/GetRepeatSubmitToken.py
new file mode 100644
index 0000000..0d49cb4
--- /dev/null
+++ b/inter/GetRepeatSubmitToken.py
@@ -0,0 +1,36 @@
+# coding=utf-8
+import json
+import re
+
+
+class getRepeatSubmitToken:
+ def __init__(self, session):
+ self.session = session
+
+ def sendGetRepeatSubmitToken(self):
+ """
+ 获取提交车票请求token
+ :return: token
+ """
+ initdc_url = self.session.urls["initdc_url"]
+ initdc_result = self.session.httpClint.send(initdc_url, )
+ token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'")
+ ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?')
+ order_request_params_name = re.compile(r'var orderRequestDTO=(\{.+\})?')
+ token = re.search(token_name, initdc_result).group(1)
+ re_tfpf = re.findall(ticketInfoForPassengerForm_name, initdc_result)
+ re_orp = re.findall(order_request_params_name, initdc_result)
+ if re_tfpf:
+ ticketInfoForPassengerForm = json.loads(re_tfpf[0].replace("'", '"'))
+ else:
+ ticketInfoForPassengerForm = ""
+ if re_orp:
+ order_request_params = json.loads(re_orp[0].replace("'", '"'))
+ else:
+ order_request_params = ""
+ return {
+ "token": token,
+ "ticketInfoForPassengerForm": ticketInfoForPassengerForm,
+ "order_request_params": order_request_params,
+ "session": self.session
+ }
\ No newline at end of file
diff --git a/inter/Query.py b/inter/Query.py
index f87a2f7..d5a9ec1 100644
--- a/inter/Query.py
+++ b/inter/Query.py
@@ -1,9 +1,7 @@
# coding=utf-8
import copy
import datetime
-import random
-import time
-
+import wrapcache
from config.TicketEnmu import ticket
@@ -45,11 +43,9 @@ class query:
查询
:return:
"""
-
for station_date in self.station_dates:
select_url = copy.copy(self.session.urls["select_url"])
- select_url["req_url"] = select_url["req_url"].format(
- station_date, self.from_station, self.to_station)
+ select_url["req_url"] = select_url["req_url"].format(station_date, self.from_station, self.to_station)
station_ticket = self.session.httpClint.send(select_url)
value = station_ticket.get("data", "")
if not value:
@@ -62,52 +58,42 @@ class query:
if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订": # 筛选未在开始时间内的车次
for j in xrange(len(self._station_seat)):
is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))]
- if is_ticket_pass != '' and is_ticket_pass != '无' and ticket_info[
- 3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次
+ if is_ticket_pass != '' and is_ticket_pass != '无' and ticket_info[3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次
secretStr = ticket_info[0]
train_no = ticket_info[2]
query_from_station_name = ticket_info[6]
query_to_station_name = ticket_info[7]
train_location = ticket_info[15]
stationTrainCode = ticket_info[3]
- train_date = station_date
leftTicket = ticket_info[12]
set_type = self._station_seat[j]
print (u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'.format(train_no,
- self.from_station_h,
- self.to_station_h,
- self._station_seat[j].encode(
- "utf8"),
- ticket_info[self.station_seat(
- self._station_seat[
- j].encode("utf8"))]
- ))
- if "train_no" in self.ticket_black_list and (
- datetime.datetime.now() - self.ticket_black_list[
- train_no]).seconds / 60 < int(ticket.TICKET_BLACK_LIST_TIME):
+ self.from_station_h,
+ self.to_station_h,
+ self._station_seat[j].encode(
+ "utf8"),
+ ticket_info[self.station_seat(
+ self._station_seat[
+ j].encode("utf8"))]
+ ))
+ if wrapcache.get(train_no):
print(ticket.QUERY_IN_BLACK_LIST.format(train_no))
break
else:
print (ticket.QUERY_C)
- # self.buy_ticket_time = datetime.datetime.now()
return {
"secretStr": secretStr,
"train_no": train_no,
"stationTrainCode": stationTrainCode,
- "train_date": train_date,
+ "train_date": station_date,
"query_from_station_name": query_from_station_name,
"query_to_station_name": query_to_station_name,
- # "buy_ticket_time": self.buy_ticket_time,
"set_type": set_type,
"leftTicket": leftTicket,
"train_location": train_location,
"code": ticket.SUCCESS_CODE,
"status": True,
}
- else:
- pass
- else:
- pass
else:
print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
return {"code": ticket.FAIL_CODE, "status": False}
diff --git a/inter/QueryOrderWaitTime.py b/inter/QueryOrderWaitTime.py
index b93b221..f676f5c 100644
--- a/inter/QueryOrderWaitTime.py
+++ b/inter/QueryOrderWaitTime.py
@@ -89,7 +89,7 @@ class queryOrderWaitTime:
else:
return False
else:
- print(u"接口 {} 无响应".format(queryMyOrderNoCompleteUrl))
+ return False
def initNoComplete(self):
"""
@@ -121,3 +121,4 @@ class queryOrderWaitTime:
return True
else:
print(ticket.CANCEL_ORDER_FAIL.format(sequence_no))
+ return False
diff --git a/inter/SubmitOrderRequest.py b/inter/SubmitOrderRequest.py
new file mode 100644
index 0000000..decac11
--- /dev/null
+++ b/inter/SubmitOrderRequest.py
@@ -0,0 +1,69 @@
+# coding=utf-8
+import datetime
+import urllib
+
+from inter.CheckOrderInfo import checkOrderInfo
+from myException.ticketIsExitsException import ticketIsExitsException
+
+
+def time():
+ """
+ 获取日期
+ :return:
+ """
+ today = datetime.date.today()
+ return today.strftime('%Y-%m-%d')
+
+
+class submitOrderRequest:
+ def __init__(self, session, secretStr, from_station, to_station, train_no, set_type,
+ passengerTicketStrList, oldPassengerStr, train_date, ticke_peoples):
+ self.session = session
+ self.secretStr = secretStr
+ self.from_station = from_station
+ self.to_station = to_station
+ self.to_station = to_station
+ self.train_no = train_no
+ self.set_type = set_type
+ self.passengerTicketStrList = passengerTicketStrList
+ self.oldPassengerStr = oldPassengerStr
+ self.train_date = train_date
+ self.ticke_peoples = ticke_peoples
+
+ def data_apr(self):
+ """
+ :return:
+ """
+ data = [('secretStr', urllib.unquote(self.secretStr)), # 字符串加密
+ ('train_date', self.train_date), # 出发时间
+ ('back_train_date', time()), # 返程时间
+ ('tour_flag', 'dc'), # 旅途类型
+ ('purpose_codes', 'ADULT'), # 成人票还是学生票
+ ('query_from_station_name', self.from_station), # 起始车站
+ ('query_to_station_name', self.to_station), # 终点车站
+ ]
+ return data
+
+ def sendSubmitOrderRequest(self):
+ """
+ 提交车次
+ 预定的请求参数,注意参数顺序
+ 注意这里为了防止secretStr被urllib.parse过度编码,在这里进行一次解码
+ 否则调用HttpTester类的post方法将会将secretStr编码成为无效码,造成提交预定请求失败
+ :param self:
+ :param secretStr: 提交车次加密
+ :return:
+ """
+ submit_station_url = self.session.urls["submit_station_url"]
+ submitResult = self.session.httpClint.send(submit_station_url, self.data_apr())
+ if 'data' in submitResult and submitResult['data']:
+ if submitResult['data'] == 'N':
+ print (u'出票成功')
+ coi = checkOrderInfo(self.session, self.train_no, self.set_type, self.passengerTicketStrList,
+ self.oldPassengerStr,
+ self.train_date, self.ticke_peoples)
+ coi.sendCheckOrderInfo()
+ else:
+ print (u'出票失败')
+ elif 'messages' in submitResult and submitResult['messages']:
+ raise ticketIsExitsException(submitResult['messages'][0])
diff --git a/myUrllib/MySocketUtils.py b/myUrllib/MySocketUtils.py
new file mode 100644
index 0000000..a43d0de
--- /dev/null
+++ b/myUrllib/MySocketUtils.py
@@ -0,0 +1,202 @@
+# coding=utf-8
+import json
+import socket
+import re
+# s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# s.connect(('183.232.189.31', 80))
+# get_str = 'GET {0} HTTP/1.1\r\nConnection: close\r\n' \
+# 'Host: %s\r\n' \
+# 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' \
+# '\r\nAccept: */*\r\n' \
+# '\r\n'
+# post_str = "POST {0} HTTP/1.1\r\n" \
+# "Host: kyfw.12306.cn\r\n" \
+# "Connection: close\r\n"\
+# "Origin: https://kyfw.12306.cn\r\n" \
+# "X-Requested-With: XMLHttpRequest\r\n" \
+# "Referer: https://kyfw.12306.cn/otn/leftTicket/init\r\n" \
+# "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n" \
+# "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" \
+# "Accept: application/json, text/javascript, */*; q=0.01\r\n" \
+# "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5\r\n" \
+# "Content-Length: 9\r\n"\
+# "Cookie: _passport_session=a459aba69761497eb31de76c27795e999613; _passport_ct=9116b2cb0bf443e1a01d22ac8c1ae449t5007; route=9036359bb8a8a461c164a04f8f50b252; BIGipServerpool_passport=200081930.50215.0000; BIGipServerotn=484704778.64545.0000\r\n\n"\
+# "appid=otn\r\n"
+# # s.sendall(get_str.format("https://kyfw.12306.cn/otn/login/init"))
+# s.sendall(post_str.format("https://kyfw.12306.cn/passport/web/auth/uamtk"))
+from config.urlConf import urls
+
+
+def default_get_data():
+ """
+ get请求默认组装字符串
+ 需要拼接的字符串
+ -- url 发送请求的全连接
+ :return:
+ """
+ return 'GET {0} HTTP/1.1\r\nConnection: close\r\n' \
+ 'Host: kyfw.12306.cn\r\n' \
+ "Referer: {1}\r\n" \
+ 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' \
+ '\r\nAccept: */*\r\n' \
+ "Cookie: {2}\r\n\n"\
+ '\r\n'
+ # return 'GET {0} HTTP/1.1\r\nConnection: close\r\n' \
+ # 'Host: kyfw.12306.cn\r\n' \
+ # 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' \
+ # '\r\nAccept: */*\r\n' \
+ # '\r\n'
+
+
+def default_post_data():
+ """
+ post请求默认组装字符串
+ 需要拼接的字符串
+ -- url 发送请求的全连接
+ -- Referer 请求页面来源
+ -- Content-Length: body 长度
+ -- Cookie 页面请求的身份认证
+ -- appid 接口请求报文
+ :return:
+ """
+ return "POST https://kyfw.12306.cn{0} HTTP/1.1\r\n" \
+ "Host: kyfw.12306.cn\r\n" \
+ "Connection: close\r\n"\
+ "Origin: https://kyfw.12306.cn\r\n" \
+ "X-Requested-With: XMLHttpRequest\r\n" \
+ "Referer: {3}\r\n" \
+ "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n" \
+ "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" \
+ "Accept: application/json, text/javascript, */*; q=0.01\r\n" \
+ "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5\r\n" \
+ "Content-Length: {2}\r\n"\
+ "Cookie: {4}\r\n\n"\
+ "{1}\r\n"\
+ # "\r\n"
+
+
+class socketUtils:
+ def __init__(self, host, port=80):
+ self.host = host
+ self.port = port
+ self.s = self.connect_socket(self.host, self.port)
+
+ def connect_socket(self, host, port):
+ """
+ 连接socket
+ :param host:
+ :param port:
+ :return:
+ """
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.connect((host if isinstance(host, str) else str(host),
+ port if isinstance(port, int) else int(port)))
+ return s
+
+ def close_s(self):
+ self.s.close()
+
+ # def send(self, urls, Cookie=None, data=None):
+ # """
+ # 发送请求
+ # :param urls:
+ # :param data:
+ # :param cookie:
+ # :return:
+ # """
+ # url = urls.get("req_url", "")
+ # Referer = urls.get("Referer", "")
+ # if urls.get("req_type", "get") == "post":
+ # Content_Length = len(data)
+ # Cookie = "tk=pnidlCoFy2B7wxO_X_pESbrkZFSq3OtVA_xzXwuba2a0; JSESSIONID=C6144324BFCE36AC5082E543E934E8B3; current_captcha_type=Z; _jc_save_fromDate=2018-08-03; _jc_save_fromStation=%u6DF1%u5733%2CSZQ; _jc_save_toDate=2018-08-03; _jc_save_toStation=%u957F%u6C99%2CCSQ; _jc_save_wfdc_flag=dc; ten_key=b5L6aMWfnzBm8CgQe8pcAKQsmVBS2PYH; BIGipServerpool_passport=166527498.50215.0000; BIGipServerotn=165937674.50210.0000; route=c5c62a339e7744272a54643b3be5bf64; RAIL_DEVICEID=fC-yepiUqNjsBiRvtLBXW4JqQmabCfB9QxI3FifJZK9YDRsImhJLSz4sAQ4HiGF7uQAFdFyISg6jA7KAhtpEldJV9ZMNsn6Dzm_psA5CBDwSNfiORf42w-LIRvkeGvdKFtegZwWGlkA2fVuEWKu-1xAYdCXRnsMD; RAIL_EXPIRATION=1533420302032; _jc_save_detail=true"
+ # if data:
+ # send_value = default_post_data().format(url,
+ # data,
+ # Content_Length,
+ # Referer,
+ # Cookie
+ # )
+ # print("send_value: " + send_value)
+ # self.s.sendall(send_value)
+ # else:
+ # self.s.sendall(default_get_data().format(url,
+ # Referer,
+ # Cookie))
+ # total_data = ""
+ # while 1:
+ # data = self.s.recv(1024)
+ # total_data += data
+ # if not data:
+ # break
+ # self.close_s()
+ # print(total_data)
+ # return self.recv_data(total_data)
+
+ def recv_data(self, r_data):
+ cookie = self.get_cookie(r_data)
+ status_code = self.get_status_code(r_data)
+ r_body = self.get_rep_body(r_data)
+ return {
+ "cookie": cookie,
+ "status_code": status_code,
+ "r_body": r_body
+ }
+
+ @staticmethod
+ def get_cookie(recv_data):
+ """
+ 提取cookie
+ :param recv_data:
+ :return:
+ """
+ if not isinstance(recv_data, str):
+ recv_data = str(recv_data)
+ cookies_re = re.compile(r"Set-Cookie: (\S+);")
+ cookies = re.findall(cookies_re, recv_data)
+ return "; ".join(cookies)
+
+ @staticmethod
+ def get_status_code(recv_data):
+ """
+ 获取状态码
+ :return:
+ """
+ if not isinstance(recv_data, str):
+ recv_data = str(recv_data)
+ http_code_re = re.compile(r"HTTP/1.1 (\S+) ")
+ status_code = re.search(http_code_re, recv_data).group(1)
+ return status_code
+
+ @staticmethod
+ def get_rep_body(recv_data):
+ """
+ 获取返回值
+ :param recv_data:
+ :return:
+ """
+ if not isinstance(recv_data, str):
+ recv_data = str(recv_data)
+ if recv_data.find("{") != -1 and recv_data.find("}") != -1:
+ data = json.loads(recv_data.split("\n")[-1])
+ return data
+ else:
+ print(recv_data)
+
+
+if __name__ == "__main__":
+ so = socketUtils('183.232.189.31', 80)
+ train_date = "2018-08-03"
+ from_station = "SZQ"
+ to_station = "CSQ"
+ urls["select_url"]["req_url"] = "https://kyfw.12306.cn" + urls["select_url"]["req_url"].format(train_date, from_station, to_station)
+ result = so.send(urls=urls["select_url"])
+ print(result)
+
+ so = socketUtils('183.232.189.31', 80)
+
+ data = "secretStr=Vgo534nDZiCH8NCvyEPcGepzJoRCjvYr34gKFv5CW1K1XtM6mtKHoiFPjUYvaVKoe06SMhUUpT%2FK%0AxIEIsBD4zHgJPpVyKiTPx80y6OCWhNgcKjib2LLMXMJfgTgh0RKPISjkDjVFmO9p905O%2FegDeKjp%0A1fhIeqCuYraHjNhI0PjQY39BAY4AHLzW0iGgDq8b%2FtpyOY8Td2XfIWNZJCWzgyPkNXOk0HUguB2G%0AKh2T8nlko6zb5ra%2B%2BA%3D%3D&train_date=2018-08-03&back_train_date=2018-08-03&tour_flag=dc&purpose_codes=ADULT&query_from_station_name=深圳&query_to_station_name=长沙&undefined"
+ result1 = so.send(urls=urls["submit_station_url"], data=data)
+ print(result1)
+ # so = socketUtils('183.232.189.31', 80)
+ # result = so.send(url="https://kyfw.12306.cn/passport/web/login", s_data="")
+ # print(result)
\ No newline at end of file
diff --git a/myUrllib/httpUtils.py b/myUrllib/httpUtils.py
index a3c1ae3..1b404d9 100755
--- a/myUrllib/httpUtils.py
+++ b/myUrllib/httpUtils.py
@@ -12,49 +12,14 @@ from config import logger
def _set_header_default():
header_dict = OrderedDict()
- header_dict["Host"] = "kyfw.12306.cn"
- header_dict["Connection"] = "keep-alive"
- header_dict["Accept"] = "application/json, text/javascript, */*; q=0.01"
- header_dict["Origin"] = "https://kyfw.12306.cn"
- header_dict["X-Requested-With"] = "XMLHttpRequest"
+ header_dict["Accept"] = "application/json, text/plain, */*"
+ header_dict["Accept-Encoding"] = "gzip, deflate"
header_dict[
- "User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
+ "User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) 12306-electron/1.0.1 Chrome/59.0.3071.115 Electron/1.8.4 Safari/537.36"
header_dict["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"
- header_dict["Referer"] = "https://kyfw.12306.cn/otn/leftTicket/init"
- header_dict["Accept-Encoding"] = "gzip, deflate, br"
- header_dict["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8"
return header_dict
-def _set_header_j():
- """设置header"""
- return {
- "Content-Type": "application/json; charset=UTF-8",
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5",
- "Accept": "application/json, text/javascript, */*; q=0.01",
- "Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
- "Accept-Encoding": "gzip, deflate, br",
- "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
- "Origin": "https://kyfw.12306.cn",
- "Connection": "keep-alive",
- }
-
-
-def _set_header_x():
- """设置header"""
- return {
- "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
- "X-Requested-With": "XMLHttpRequest",
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5",
- "Accept": "application/json, text/javascript, */*; q=0.01",
- "Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
- "Accept-Encoding": "gzip, deflate, br",
- "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
- "Origin": "https://kyfw.12306.cn",
- "Connection": "keep-alive",
- }
-
-
class HTTPClient(object):
def __init__(self):
@@ -67,7 +32,7 @@ class HTTPClient(object):
def initS(self):
self._s = requests.Session()
- self._s.headers.update(_set_header_j())
+ self._s.headers.update(_set_header_default())
return self
def set_cookies(self, **kwargs):
@@ -79,6 +44,13 @@ class HTTPClient(object):
for k, v in kwargs.items():
self._s.cookies.set(k, v)
+ def get_cookies(self):
+ """
+ 获取cookies
+ :return:
+ """
+ return self._s.cookies.values()
+
def del_cookies(self):
"""
删除所有的key
@@ -97,12 +69,9 @@ class HTTPClient(object):
self._s.headers.update(headers)
return self
- def resetHeaders(self, header_type):
+ def resetHeaders(self):
self._s.headers.clear()
- if header_type == 1:
- self._s.headers.update(_set_header_x())
- else:
- self._s.headers.update(_set_header_j())
+ self._s.headers.update(_set_header_default())
def getHeadersHost(self):
return self._s.headers["Host"]
@@ -126,14 +95,6 @@ class HTTPClient(object):
def cdn(self, cdn):
self._cdn = cdn
- # def send_socket(self, urls, data=None, **kwargs):
- # data = """
- # POST {0} HTTP/1.1
- # {0}
- # """.format(urls["req_url"], self._set_header())
- # fack = socket.create_connection(urls["Host"], 443)
- # fack.send()
-
def send(self, urls, data=None, **kwargs):
"""send request to url.If response 200,return response, else return None."""
allow_redirects = False
@@ -141,31 +102,22 @@ class HTTPClient(object):
req_url = urls.get("req_url", "")
re_try = urls.get("re_try", 0)
s_time = urls.get("s_time", 0)
- contentType = urls.get("Content-Type", 0)
error_data = {"code": 99999, "message": u"重试次数达到上限"}
if data:
method = "post"
self.setHeaders({"Content-Length": "{0}".format(len(data))})
else:
method = "get"
- self.resetHeaders(contentType)
+ self.resetHeaders()
self.setHeadersReferer(urls["Referer"])
if is_logger:
logger.log(
u"url: {0}\n入参: {1}\n请求方式: {2}\n".format(req_url, data, method, ))
- self.setHeadersHost(urls["Host"])
+ # self.setHeadersHost(urls["Host"])
if self.cdn:
url_host = self.cdn
else:
url_host = urls["Host"]
- if contentType == 1:
- # 普通from表单
- self.resetHeaders(contentType)
- if method == "post":
- pass
- data = urllib.urlencode(data)
- elif contentType == 0:
- self.resetHeaders(contentType)
for i in range(re_try):
try:
# sleep(urls["s_time"]) if "s_time" in urls else sleep(0.001)
diff --git a/requirements.txt b/requirements.txt
index f59c823..4b5100f 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,4 +3,5 @@ bs4==0.0.1
PyYAML==3.12
six==1.10.0
requests==2.18.4
-Pillow==5.0.0
\ No newline at end of file
+Pillow==5.0.0
+wrapcache==1.0.8
\ No newline at end of file
diff --git a/run.py b/run.py
index 61d0f07..097690b 100755
--- a/run.py
+++ b/run.py
@@ -1,12 +1,16 @@
# -*- coding=utf-8 -*-
-from init import login, select_ticket_info, SelectTicketInfoFast
+from config.emailConf import sendEmail
+from init import select_ticket_info
def run():
- # login.main()
- SelectTicketInfoFast.selectFast().main()
- # select_ticket_info.select().main()
+ select_ticket_info.select().main()
+
+
+def testEmail():
+ sendEmail(u"订票小助手测试一下")
if __name__ == '__main__':
- run()
\ No newline at end of file
+ run()
+ # testEmail()
\ No newline at end of file