背景
这个五一是疫情后得第一个五一,出行人数真的恐怖,早早定了嵊泗得酒店(不退款),提前7天开始抢船票,但是早起来抢都铩羽而归,只能写个脚本抢了。最后,结果还是好的 ,抢到了合适得班次。
代码
代码里有些隐私信息替换成了”**”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import traceback
import requests
import time
import hmac
import hashlib
import base64
import urllib.parse
def update_dict(origin, target):
for k in origin:
if k in target:
origin[k] = target[k]
order_data_tmp = {"accountTypeId": "0", "userId": "****", "buyTicketType": 1, "contactNum": "17521080261",
"lineNum": 4973, "lineName": "洋山加枸嵊", "lineNo": 23005, "shipName": "碧海9轮", "startPortNo": 28,
"startPortName": "嵊泗(沈家湾)", "endPortNo": 17, "endPortName": "嵊泗(枸杞)", "sailDate": "2023-04-28",
"sailTime": "13:00", "lineDirect": 1, "totalFee": 220, "totalPayFee": 220, "sx": 0,
"orderItemRequests": [
{"passName": "**", "credentialType": 1, "passId": 3593485, "seatClassName": "上舱", "seatClass": 31,
"ticketFee": 110, "realFee": 110, "freeChildCount": 0, "passType": 1},
{"passName": "**", "credentialType": 1, "passId": 3593483, "seatClassName": "上舱", "seatClass": 31,
"ticketFee": 110, "realFee": 110, "freeChildCount": 0, "passType": 1}], "busStartTime": "",
"clxm": "高速客船",
"clxh": 3, "hxlxh": 1, "hxlxm": "旅游增开班", "bus": 0, "bus2": 0, "dwh": 23}
timestamp = str(round(time.time() * 1000))
secret = '*****'
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
headers = {'Content-Type': 'application/json'}
dingtalk_hook = "https://oapi.dingtalk.com/robot/send?access_token=*******×tamp={}&sign={}".format(
timestamp, sign)
# 南浦(1046)到枸杞(1017) 白名单 4994,1775
query1 = {"startPortNo": 1046, "endPortNo": 1017, "startDate": "2023-04-29"}
# 南浦到嵊山 4973
query2 = {"startPortNo": 1046, "endPortNo": 1016, "startDate": "2023-04-29"}
# 沈家湾(1028)到枸杞 白名单 1775
query3 = {"startPortNo": 1028, "endPortNo": 1017, "startDate": "2023-04-29"}
# 沈家湾到嵊山
query4 = {"startPortNo": 1028, "endPortNo": 1016, "startDate": "2023-04-29"}
# 枸杞到沈家湾
query5 = {"startPortNo": 1017, "endPortNo": 1028, "startDate": "2023-04-30", "accountTypeId": "0"}
# 枸杞到南浦 白名单 1777
query6 = {"startPortNo":1017,"endPortNo":1046,"startDate":"2023-04-30","accountTypeId":"0"}
# 嵊山到南浦
query7={"startPortNo":1016,"endPortNo":1046,"startDate":"2023-04-30","accountTypeId":"0"}
white_list =[4994, 1775, 4973, 1775, 1777]
forward_querys = [query1, query2, query3, query6]
backward_querys = [query6]
import time
import datetime
switch = True
debug = False
while True:
try:
if switch:
querys = forward_querys
else:
querys = backward_querys
switch = not switch
# 请求所有query
data = []
for query in querys:
url = 'https://www.ssky123.com/api/v2/line/ship/enq'
response = requests.post(url, headers=headers, json=query)
if response.status_code == 200:
res = response.json()
if len(res['data']) > 0:
data.extend(res['data'])
# filter 有余票得
lefts = []
try:
for d in data:
# 白名单过滤
if d['lineNum'] not in white_list:
continue
seatClasses = d['seatClasses']
for cls in seatClasses:
if cls["pubCurrentCount"] >= 2:
tickets = {}
tickets['startPortName'] = d['startPortName']
tickets['endPortName'] = d['endPortName']
tickets['className'] = cls['className']
tickets['pubCurrentCount'] = cls['pubCurrentCount']
tickets['sailDate'] = d['sailDate']
tickets['origin_data'] = d
tickets['seatClassesInfo'] = cls
lefts.append(tickets)
except Exception as e:
traceback.print_exc()
if len(lefts) > 0:
# 发消息
content = ''
for l in lefts:
content = content + '\n' + "{}: {}到{}, {}, 余票:{}, 开船时间:{}".format(l['sailDate'], l['startPortName'],
l["endPortName"], l['className'],
str(l['pubCurrentCount']), l['origin_data']['sailTime'])
ding_msg = {"msgtype": "text", "text": {"content": content}}
if debug:
print(content)
else:
response = requests.post(dingtalk_hook, headers=headers, json=ding_msg)
# 下订单
target = lefts[0]['origin_data']
order_data = order_data_tmp.copy()
update_dict(order_data, target)
for orderItem in order_data['orderItemRequests']:
update_dict(orderItem, lefts[0]['seatClassesInfo'])
orderItem['ticketFee'] = int(lefts[0]['seatClassesInfo']['localPrice'])
orderItem['realFee'] = int(lefts[0]['seatClassesInfo']['localPrice'])
orderItem['seatClassName'] = lefts[0]['seatClassesInfo']['className']
orderItem['seatClass'] = lefts[0]['seatClassesInfo']['classNum']
order_data['totalFee'] = int(lefts[0]['seatClassesInfo']['localPrice']) * 2
order_data['totalPayFee'] = int(lefts[0]['seatClassesInfo']['localPrice']) * 2
order_data['sailDate'] = order_data['sailDate'].replace('/', '-')
order_url = "https://www.ssky123.com/api/v2/holding/save"
header = headers.copy()
header['Cookie'] = '*****'
header['authentication'] = '***'
header['token'] = '****'
if not debug:
response = requests.post(order_url, headers=header, json=order_data)
if response.status_code == 200:
ding_msg = {"msgtype": "text", "text": {"content": "已经完成订票,请尽快付款"}}
else:
content = "自动购票失败。 错误信息:" + response.text
ding_msg = {"msgtype": "text", "text": {"content": content}}
response = requests.post(dingtalk_hook, headers=headers, json=ding_msg)
if not debug:
time.sleep(15)
except Exception as e:
print("异常退出,等待")
traceback.print_exc()
time.sleep(60)