前些日子知道了DailyCheckIn这个项目,能将无聊的每日签到工作中解放出来。它里面有抢茅台预约的功能,那么就试试。
安装
哎,萝卜白菜各有所爱吧。比如我就觉得官网上的教程过于详细了,不如直接给个 docker-compose.yaml 直接一把梭跑。
version: "3"
services:
dailycheckin:
volumes:
- /PATH/TO/SOME/FOLDER:/dailycheckin
restart: always
image: sitoi/dailycheckin
或者直接一行命令也不是不可以
docker run -v /PATH/TO/SOME/FOLDER:/dailycheckin --restart always sitoi/dailycheckin
用K8s部署的话,大概搞成这样(emm,自从有了K8s集群后,啥啥啥都想K8s解决……明明人家docker compose会更简单…… )
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dailycheckin
spec:
resources:
requests:
storage: 50Mi
accessModes:
- ReadWriteMany
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dailycheckin
spec:
replicas: 1
selector:
matchLabels:
app: dailycheckin
template:
metadata:
labels:
app: dailycheckin
spec:
containers:
- name: dailycheckin
image: sitoi/dailycheckin
imagePullPolicy: IfNotPresent
volumeMounts:
- name: dailycheckin
mountPath: /dailycheckin
volumes:
- name: dailycheckin
persistentVolumeClaim:
claimName: dailycheckin
茅台配置
官网教程里面说,需要先申请一个高德地图的开发者账号,然后再运行一个脚本。申请账号是为了获取到当前定位,然后预约离你最近的门店。
我在这里卡住了:我输入手机号,说已被绑定,反正死活不让我开通开发者。
然后看了下官网上提供的脚本,似乎只是需要一个经纬度,和一个文字格式的地址。那么我似乎可以从其他地方获取到这些信息。
首先,来到高德开放平台-坐标拾取器,直接搜索你需要的位置。网页上面写了「游客和未认证开发者仅显示经纬度小数点后2位」,但是茅台脚本里面需要的坐标似乎精度更高一点。没关系,我们打开F12,切换到「网络」tab,再在地图上点击一下你想要的坐标,哎,有个请求,里面列出了详细的信息,精确到了小数点后6位——够用了。
好了,那么那个取获Token的脚本就可以变成这样了:
import hashlib
import json
import time
import requests
GEO_INFO = {
"province": "", # 接口的 province 字段直接复制过来
"city": [], # 这里如果有看到就填,看不到就空着
"location": "" # 接口的location字段直接复制过来
}
ITEM_CODES = ["10941", "10942"]
SALT = "2af72f100c356273d46284f6fd1dfc08"
CURRENT_TIME = str(int(time.time() * 1000))
headers_base = {
'MT-Lat': '28.499562',
'MT-K': '1675213490331',
'MT-Lng': '102.182324',
'Host': 'app.moutai519.com.cn',
'MT-User-Tag': '0',
'Accept': '*/*',
'MT-Network-Type': 'WIFI',
'MT-Token': '1',
'MT-Team-ID': '1',
'MT-Info': '028e7f96f6369cafe1d105579c5b9377',
'MT-Device-ID': '2F2075D0-B66C-4287-A903-DBFF6358342A',
'MT-Bundle-ID': 'com.moutai.mall',
'Accept-Language': 'en-CN;q=1, zh-Hans-CN;q=0.9',
'MT-Request-ID': '167560018873318465',
'MT-APP-Version': '1.3.7',
'User-Agent': 'iOS;16.3;Apple;?unrecognized?',
'MT-R': 'clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==',
'Content-Length': '93',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'userId': '2'
}
headers = {}
mt_version = json.loads(requests.get("https://itunes.apple.com/cn/lookup?id=1600482450").text)["results"][0]["version"]
# 初始化请求头
def init_headers(user_id: str = "1", token: str = "2", lat: str = "29.83826", lng: str = "119.74375"):
global headers
headers = {
**headers_base,
"userId": user_id,
"MT-Token": token,
"MT-Lat": lat,
"MT-Lng": lng,
"MT-APP-Version": mt_version,
}
def signature(data: dict):
keys = sorted(data.keys())
temp_v = ""
for item in keys:
temp_v += data[item]
text = SALT + temp_v + CURRENT_TIME
hl = hashlib.md5()
hl.update(text.encode(encoding="utf8"))
md5 = hl.hexdigest()
return md5
# 获取登录手机验证码
def get_vcode(mobile: str):
params = {"mobile": mobile}
md5 = signature(params)
params.update({
"md5": md5,
"timestamp": CURRENT_TIME,
"MT-APP-Version": mt_version
})
responses = requests.post(
"https://app.moutai519.com.cn/xhr/front/user/register/vcode",
json=params,
headers=headers,
)
if responses.status_code != 200:
print(f"get v_code: "
f"params: {params}, "
f"response code: {responses.status_code}, "
f"response body: {responses.text}")
# 执行登录操作
def login(mobile: str, v_code: str):
params = {"mobile": mobile, "vCode": v_code, "ydToken": "", "ydLogId": ""}
md5 = signature(params)
params.update({
"md5": md5,
"timestamp": CURRENT_TIME,
"MT-APP-Version": mt_version
})
responses = requests.post(
"https://app.moutai519.com.cn/xhr/front/user/register/login",
json=params,
headers=headers,
)
if responses.status_code != 200:
print(f"login: "
f"params: {params}, "
f"response code: {responses.status_code}, "
f"response body: {responses.text}")
rsp_json = responses.json()
# headers.update({"MT-Token": rsp_json["data"]["token"], "userId": rsp_json["data"]["userId"]})
return rsp_json["data"]["token"], rsp_json["data"]["userId"]
if __name__ == "__main__":
items = []
while True:
init_headers()
location_select: dict = GEO_INFO
province = location_select["province"]
city = location_select["city"]
location: str = location_select["location"]
mobile = input("输入手机号[18888888888]:").strip()
get_vcode(mobile)
code = input(f"输入 [{mobile}] 验证码[8888]:").strip()
token, userId = login(mobile, code)
item = {
"city": str(city),
"lat": location.split(",")[1],
"lng": location.split(",")[0],
"mobile": str(mobile),
"province": province,
"token": str(token),
"userid": str(userId),
"reserve_rule": 0,
"item_codes": ITEM_CODES,
}
items.append(item)
condition = input("是否继续添加账号[y/n]:").strip()
if condition.lower() == "n":
break
with open("account.json", "w") as f:
f.write(json.dumps(items, ensure_ascii=False, indent=4))
print("Done")
好了,安心食用吧。
反正,我是觉得,就是营销做得好。
我是对酒类不感兴趣。不如来瓶可乐。
另外我超烦「签到」这种东西。
发表回复