├── README.md ├── SendNotify.py ├── bd_ikuuu.py ├── bd_xtb.py └── bd_yl.py /README.md: -------------------------------------------------------------------------------- 1 | 青龙拉库:ql repo https://github.com/Bidepanlong/ql.git "bd_" "README" "SendNotify" 2 | 3 | WX机器人 4 | 5 | ![机器人二维码](https://github.com/Bidepanlong/ql/assets/115330776/115c94e8-d5da-404d-9505-faa8e7dbfcc8) 6 | -------------------------------------------------------------------------------- /SendNotify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # _*_ coding:utf-8 _*_ 3 | import base64 4 | import hashlib 5 | import hmac 6 | import json 7 | import os 8 | import re 9 | import threading 10 | import time 11 | import urllib.parse 12 | import smtplib 13 | from email.mime.text import MIMEText 14 | from email.header import Header 15 | from email.utils import formataddr 16 | 17 | import requests 18 | 19 | # 原先的 print 函数和主线程的锁 20 | _print = print 21 | mutex = threading.Lock() 22 | 23 | 24 | # 定义新的 print 函数 25 | def print(text, *args, **kw): 26 | """ 27 | 使输出有序进行,不出现多线程同一时间输出导致错乱的问题。 28 | """ 29 | with mutex: 30 | _print(text, *args, **kw) 31 | 32 | 33 | # 通知服务 34 | # fmt: off 35 | push_config = { 36 | 'HITOKOTO': False, # 启用一言(随机句子) 37 | 38 | 'BARK_PUSH': '', # bark IP 或设备码,例:https://api.day.app/DxHcxxxxxRxxxxxxcm/ 39 | 'BARK_ARCHIVE': '', # bark 推送是否存档 40 | 'BARK_GROUP': '', # bark 推送分组 41 | 'BARK_SOUND': '', # bark 推送声音 42 | 'BARK_ICON': '', # bark 推送图标 43 | 44 | 'CONSOLE': True, # 控制台输出 45 | 46 | 'DD_BOT_SECRET': '', # 钉钉机器人的 DD_BOT_SECRET 47 | 'DD_BOT_TOKEN': '', # 钉钉机器人的 DD_BOT_TOKEN 48 | 49 | 'FSKEY': '', # 飞书机器人的 FSKEY 50 | 51 | 'GOBOT_URL': '', # go-cqhttp 52 | # 推送到个人QQ:http://127.0.0.1/send_private_msg 53 | # 群:http://127.0.0.1/send_group_msg 54 | 'GOBOT_QQ': '', # go-cqhttp 的推送群或用户 55 | # GOBOT_URL 设置 /send_private_msg 时填入 user_id=个人QQ 56 | # /send_group_msg 时填入 group_id=QQ群 57 | 'GOBOT_TOKEN': '', # go-cqhttp 的 access_token 58 | 59 | 'GOTIFY_URL': '', # gotify地址,如https://push.example.de:8080 60 | 'GOTIFY_TOKEN': '', # gotify的消息应用token 61 | 'GOTIFY_PRIORITY': 0, # 推送消息优先级,默认为0 62 | 63 | 'IGOT_PUSH_KEY': '', # iGot 聚合推送的 IGOT_PUSH_KEY 64 | 65 | 'PUSH_KEY': '', # server 酱的 PUSH_KEY,兼容旧版与 Turbo 版 66 | 67 | 'DEER_KEY': '', # PushDeer 的 PUSHDEER_KEY 68 | 'DEER_URL': '', # PushDeer 的 PUSHDEER_URL 69 | 70 | 'CHAT_URL': '', # synology chat url 71 | 'CHAT_TOKEN': '', # synology chat token 72 | 73 | 'PUSH_PLUS_TOKEN': '', # push+ 微信推送的用户令牌 74 | 'PUSH_PLUS_USER': '', # push+ 微信推送的群组编码 75 | 76 | 'QMSG_KEY': '', # qmsg 酱的 QMSG_KEY 77 | 'QMSG_TYPE': '', # qmsg 酱的 QMSG_TYPE 78 | 79 | 'QYWX_ORIGIN': '', # 企业微信代理地址 80 | 81 | 'QYWX_AM': '', # 企业微信应用 82 | 83 | 'QYWX_KEY': '', # 企业微信机器人 84 | 85 | 'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN,例:1407203283:AAG9rt-6RDaaX0HBLZQq0laNOh898iFYaRQ 86 | 'TG_USER_ID': '', # tg 机器人的 TG_USER_ID,例:1434078534 87 | 'TG_API_HOST': '', # tg 代理 api 88 | 'TG_PROXY_AUTH': '', # tg 代理认证参数 89 | 'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST 90 | 'TG_PROXY_PORT': '', # tg 机器人的 TG_PROXY_PORT 91 | 92 | 'AIBOTK_KEY': '', # 智能微秘书 个人中心的apikey 文档地址:http://wechat.aibotk.com/docs/about 93 | 'AIBOTK_TYPE': '', # 智能微秘书 发送目标 room 或 contact 94 | 'AIBOTK_NAME': '', # 智能微秘书 发送群名 或者好友昵称和type要对应好 95 | 96 | 'SMTP_SERVER': '', # SMTP 发送邮件服务器,形如 smtp.exmail.qq.com:465 97 | 'SMTP_SSL': 'false', # SMTP 发送邮件服务器是否使用 SSL,填写 true 或 false 98 | 'SMTP_EMAIL': '', # SMTP 收发件邮箱,通知将会由自己发给自己 99 | 'SMTP_PASSWORD': '', # SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定 100 | 'SMTP_NAME': '', # SMTP 收发件人姓名,可随意填写 101 | 102 | 'PUSHME_KEY': '', # PushMe 酱的 PUSHME_KEY 103 | } 104 | notify_function = [] 105 | # fmt: on 106 | 107 | # 首先读取 面板变量 或者 github action 运行变量 108 | for k in push_config: 109 | if os.getenv(k): 110 | v = os.getenv(k) 111 | push_config[k] = v 112 | 113 | 114 | def bark(title: str, content: str) -> None: 115 | """ 116 | 使用 bark 推送消息。 117 | """ 118 | if not push_config.get("BARK_PUSH"): 119 | print("bark 服务的 BARK_PUSH 未设置!!\n取消推送") 120 | return 121 | print("bark 服务启动") 122 | 123 | if push_config.get("BARK_PUSH").startswith("http"): 124 | url = f'{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 125 | else: 126 | url = f'https://api.day.app/{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 127 | 128 | bark_params = { 129 | "BARK_ARCHIVE": "isArchive", 130 | "BARK_GROUP": "group", 131 | "BARK_SOUND": "sound", 132 | "BARK_ICON": "icon", 133 | } 134 | params = "" 135 | for pair in filter( 136 | lambda pairs: pairs[0].startswith("BARK_") 137 | and pairs[0] != "BARK_PUSH" 138 | and pairs[1] 139 | and bark_params.get(pairs[0]), 140 | push_config.items(), 141 | ): 142 | params += f"{bark_params.get(pair[0])}={pair[1]}&" 143 | if params: 144 | url = url + "?" + params.rstrip("&") 145 | response = requests.get(url).json() 146 | 147 | if response["code"] == 200: 148 | print("bark 推送成功!") 149 | else: 150 | print("bark 推送失败!") 151 | 152 | 153 | def console(title: str, content: str) -> None: 154 | """ 155 | 使用 控制台 推送消息。 156 | """ 157 | # print(f"{title}\n\n{content}") 158 | 159 | 160 | def dingding_bot(title: str, content: str) -> None: 161 | """ 162 | 使用 钉钉机器人 推送消息。 163 | """ 164 | if not push_config.get("DD_BOT_SECRET") or not push_config.get("DD_BOT_TOKEN"): 165 | print("钉钉机器人 服务的 DD_BOT_SECRET 或者 DD_BOT_TOKEN 未设置!!\n取消推送") 166 | return 167 | print("钉钉机器人 服务启动") 168 | 169 | timestamp = str(round(time.time() * 1000)) 170 | secret_enc = push_config.get("DD_BOT_SECRET").encode("utf-8") 171 | string_to_sign = "{}\n{}".format(timestamp, push_config.get("DD_BOT_SECRET")) 172 | string_to_sign_enc = string_to_sign.encode("utf-8") 173 | hmac_code = hmac.new( 174 | secret_enc, string_to_sign_enc, digestmod=hashlib.sha256 175 | ).digest() 176 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) 177 | url = f'https://oapi.dingtalk.com/robot/send?access_token={push_config.get("DD_BOT_TOKEN")}×tamp={timestamp}&sign={sign}' 178 | headers = {"Content-Type": "application/json;charset=utf-8"} 179 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 180 | response = requests.post( 181 | url=url, data=json.dumps(data), headers=headers, timeout=15 182 | ).json() 183 | 184 | if not response["errcode"]: 185 | print("钉钉机器人 推送成功!") 186 | else: 187 | print("钉钉机器人 推送失败!") 188 | 189 | 190 | def feishu_bot(title: str, content: str) -> None: 191 | """ 192 | 使用 飞书机器人 推送消息。 193 | """ 194 | if not push_config.get("FSKEY"): 195 | print("飞书 服务的 FSKEY 未设置!!\n取消推送") 196 | return 197 | print("飞书 服务启动") 198 | 199 | url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{push_config.get("FSKEY")}' 200 | data = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}} 201 | response = requests.post(url, data=json.dumps(data)).json() 202 | 203 | if response.get("StatusCode") == 0: 204 | print("飞书 推送成功!") 205 | else: 206 | print("飞书 推送失败!错误信息如下:\n", response) 207 | 208 | 209 | def go_cqhttp(title: str, content: str) -> None: 210 | """ 211 | 使用 go_cqhttp 推送消息。 212 | """ 213 | if not push_config.get("GOBOT_URL") or not push_config.get("GOBOT_QQ"): 214 | print("go-cqhttp 服务的 GOBOT_URL 或 GOBOT_QQ 未设置!!\n取消推送") 215 | return 216 | print("go-cqhttp 服务启动") 217 | 218 | url = f'{push_config.get("GOBOT_URL")}?access_token={push_config.get("GOBOT_TOKEN")}&{push_config.get("GOBOT_QQ")}&message=标题:{title}\n内容:{content}' 219 | response = requests.get(url).json() 220 | 221 | if response["status"] == "ok": 222 | print("go-cqhttp 推送成功!") 223 | else: 224 | print("go-cqhttp 推送失败!") 225 | 226 | 227 | def gotify(title: str, content: str) -> None: 228 | """ 229 | 使用 gotify 推送消息。 230 | """ 231 | if not push_config.get("GOTIFY_URL") or not push_config.get("GOTIFY_TOKEN"): 232 | print("gotify 服务的 GOTIFY_URL 或 GOTIFY_TOKEN 未设置!!\n取消推送") 233 | return 234 | print("gotify 服务启动") 235 | 236 | url = f'{push_config.get("GOTIFY_URL")}/message?token={push_config.get("GOTIFY_TOKEN")}' 237 | data = { 238 | "title": title, 239 | "message": content, 240 | "priority": push_config.get("GOTIFY_PRIORITY"), 241 | } 242 | response = requests.post(url, data=data).json() 243 | 244 | if response.get("id"): 245 | print("gotify 推送成功!") 246 | else: 247 | print("gotify 推送失败!") 248 | 249 | 250 | def iGot(title: str, content: str) -> None: 251 | """ 252 | 使用 iGot 推送消息。 253 | """ 254 | if not push_config.get("IGOT_PUSH_KEY"): 255 | print("iGot 服务的 IGOT_PUSH_KEY 未设置!!\n取消推送") 256 | return 257 | print("iGot 服务启动") 258 | 259 | url = f'https://push.hellyw.com/{push_config.get("IGOT_PUSH_KEY")}' 260 | data = {"title": title, "content": content} 261 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 262 | response = requests.post(url, data=data, headers=headers).json() 263 | 264 | if response["ret"] == 0: 265 | print("iGot 推送成功!") 266 | else: 267 | print(f'iGot 推送失败!{response["errMsg"]}') 268 | 269 | 270 | def serverJ(title: str, content: str) -> None: 271 | """ 272 | 通过 serverJ 推送消息。 273 | """ 274 | if not push_config.get("PUSH_KEY"): 275 | print("serverJ 服务的 PUSH_KEY 未设置!!\n取消推送") 276 | return 277 | print("serverJ 服务启动") 278 | 279 | data = {"text": title, "desp": content.replace("\n", "\n\n")} 280 | if push_config.get("PUSH_KEY").find("SCT") != -1: 281 | url = f'https://sctapi.ftqq.com/{push_config.get("PUSH_KEY")}.send' 282 | else: 283 | url = f'https://sc.ftqq.com/{push_config.get("PUSH_KEY")}.send' 284 | response = requests.post(url, data=data).json() 285 | 286 | if response.get("errno") == 0 or response.get("code") == 0: 287 | print("serverJ 推送成功!") 288 | else: 289 | print(f'serverJ 推送失败!错误码:{response["message"]}') 290 | 291 | 292 | def pushdeer(title: str, content: str) -> None: 293 | """ 294 | 通过PushDeer 推送消息 295 | """ 296 | if not push_config.get("DEER_KEY"): 297 | print("PushDeer 服务的 DEER_KEY 未设置!!\n取消推送") 298 | return 299 | print("PushDeer 服务启动") 300 | data = { 301 | "text": title, 302 | "desp": content, 303 | "type": "markdown", 304 | "pushkey": push_config.get("DEER_KEY"), 305 | } 306 | url = "https://api2.pushdeer.com/message/push" 307 | if push_config.get("DEER_URL"): 308 | url = push_config.get("DEER_URL") 309 | 310 | response = requests.post(url, data=data).json() 311 | 312 | if len(response.get("content").get("result")) > 0: 313 | print("PushDeer 推送成功!") 314 | else: 315 | print("PushDeer 推送失败!错误信息:", response) 316 | 317 | 318 | def chat(title: str, content: str) -> None: 319 | """ 320 | 通过Chat 推送消息 321 | """ 322 | if not push_config.get("CHAT_URL") or not push_config.get("CHAT_TOKEN"): 323 | print("chat 服务的 CHAT_URL或CHAT_TOKEN 未设置!!\n取消推送") 324 | return 325 | print("chat 服务启动") 326 | data = "payload=" + json.dumps({"text": title + "\n" + content}) 327 | url = push_config.get("CHAT_URL") + push_config.get("CHAT_TOKEN") 328 | response = requests.post(url, data=data) 329 | 330 | if response.status_code == 200: 331 | print("Chat 推送成功!") 332 | else: 333 | print("Chat 推送失败!错误信息:", response) 334 | 335 | 336 | def pushplus_bot(title: str, content: str) -> None: 337 | """ 338 | 通过 push+ 推送消息。 339 | """ 340 | if not push_config.get("PUSH_PLUS_TOKEN"): 341 | print("PUSHPLUS 服务的 PUSH_PLUS_TOKEN 未设置!!\n取消推送") 342 | return 343 | print("PUSHPLUS 服务启动") 344 | 345 | url = "http://www.pushplus.plus/send" 346 | data = { 347 | "token": push_config.get("PUSH_PLUS_TOKEN"), 348 | "title": title, 349 | "content": content, 350 | "topic": push_config.get("PUSH_PLUS_USER"), 351 | } 352 | body = json.dumps(data).encode(encoding="utf-8") 353 | headers = {"Content-Type": "application/json"} 354 | response = requests.post(url=url, data=body, headers=headers).json() 355 | 356 | if response["code"] == 200: 357 | print("PUSHPLUS 推送成功!") 358 | 359 | else: 360 | url_old = "http://pushplus.hxtrip.com/send" 361 | headers["Accept"] = "application/json" 362 | response = requests.post(url=url_old, data=body, headers=headers).json() 363 | 364 | if response["code"] == 200: 365 | print("PUSHPLUS(hxtrip) 推送成功!") 366 | 367 | else: 368 | print("PUSHPLUS 推送失败!") 369 | 370 | 371 | def qmsg_bot(title: str, content: str) -> None: 372 | """ 373 | 使用 qmsg 推送消息。 374 | """ 375 | if not push_config.get("QMSG_KEY") or not push_config.get("QMSG_TYPE"): 376 | print("qmsg 的 QMSG_KEY 或者 QMSG_TYPE 未设置!!\n取消推送") 377 | return 378 | print("qmsg 服务启动") 379 | 380 | url = f'https://qmsg.zendee.cn/{push_config.get("QMSG_TYPE")}/{push_config.get("QMSG_KEY")}' 381 | payload = {"msg": f'{title}\n\n{content.replace("----", "-")}'.encode("utf-8")} 382 | response = requests.post(url=url, params=payload).json() 383 | 384 | if response["code"] == 0: 385 | print("qmsg 推送成功!") 386 | else: 387 | print(f'qmsg 推送失败!{response["reason"]}') 388 | 389 | 390 | def wecom_app(title: str, content: str) -> None: 391 | """ 392 | 通过 企业微信 APP 推送消息。 393 | """ 394 | if not push_config.get("QYWX_AM"): 395 | print("QYWX_AM 未设置!!\n取消推送") 396 | return 397 | QYWX_AM_AY = re.split(",", push_config.get("QYWX_AM")) 398 | if 4 < len(QYWX_AM_AY) > 5: 399 | print("QYWX_AM 设置错误!!\n取消推送") 400 | return 401 | print("企业微信 APP 服务启动") 402 | 403 | corpid = QYWX_AM_AY[0] 404 | corpsecret = QYWX_AM_AY[1] 405 | touser = QYWX_AM_AY[2] 406 | agentid = QYWX_AM_AY[3] 407 | try: 408 | media_id = QYWX_AM_AY[4] 409 | except IndexError: 410 | media_id = "" 411 | wx = WeCom(corpid, corpsecret, agentid) 412 | # 如果没有配置 media_id 默认就以 text 方式发送 413 | if not media_id: 414 | message = title + "\n\n" + content 415 | response = wx.send_text(message, touser) 416 | else: 417 | response = wx.send_mpnews(title, content, media_id, touser) 418 | 419 | if response == "ok": 420 | print("企业微信推送成功!") 421 | else: 422 | print("企业微信推送失败!错误信息如下:\n", response) 423 | 424 | 425 | class WeCom: 426 | def __init__(self, corpid, corpsecret, agentid): 427 | self.CORPID = corpid 428 | self.CORPSECRET = corpsecret 429 | self.AGENTID = agentid 430 | self.ORIGIN = "https://qyapi.weixin.qq.com" 431 | if push_config.get("QYWX_ORIGIN"): 432 | self.ORIGIN = push_config.get("QYWX_ORIGIN") 433 | 434 | def get_access_token(self): 435 | url = f"{self.ORIGIN}/cgi-bin/gettoken" 436 | values = { 437 | "corpid": self.CORPID, 438 | "corpsecret": self.CORPSECRET, 439 | } 440 | req = requests.post(url, params=values) 441 | data = json.loads(req.text) 442 | return data["access_token"] 443 | 444 | def send_text(self, message, touser="@all"): 445 | send_url = f"{self.ORIGIN}/cgi-bin/message/send?access_token={self.get_access_token()}" 446 | send_values = { 447 | "touser": touser, 448 | "msgtype": "text", 449 | "agentid": self.AGENTID, 450 | "text": {"content": message}, 451 | "safe": "0", 452 | } 453 | send_msges = bytes(json.dumps(send_values), "utf-8") 454 | respone = requests.post(send_url, send_msges) 455 | respone = respone.json() 456 | return respone["errmsg"] 457 | 458 | def send_mpnews(self, title, message, media_id, touser="@all"): 459 | send_url = f"https://{self.HOST}/cgi-bin/message/send?access_token={self.get_access_token()}" 460 | send_values = { 461 | "touser": touser, 462 | "msgtype": "mpnews", 463 | "agentid": self.AGENTID, 464 | "mpnews": { 465 | "articles": [ 466 | { 467 | "title": title, 468 | "thumb_media_id": media_id, 469 | "author": "Author", 470 | "content_source_url": "", 471 | "content": message.replace("\n", "
"), 472 | "digest": message, 473 | } 474 | ] 475 | }, 476 | } 477 | send_msges = bytes(json.dumps(send_values), "utf-8") 478 | respone = requests.post(send_url, send_msges) 479 | respone = respone.json() 480 | return respone["errmsg"] 481 | 482 | 483 | def wecom_bot(title: str, content: str) -> None: 484 | """ 485 | 通过 企业微信机器人 推送消息。 486 | """ 487 | if not push_config.get("QYWX_KEY"): 488 | print("企业微信机器人 服务的 QYWX_KEY 未设置!!\n取消推送") 489 | return 490 | print("企业微信机器人服务启动") 491 | 492 | origin = "https://qyapi.weixin.qq.com" 493 | if push_config.get("QYWX_ORIGIN"): 494 | origin = push_config.get("QYWX_ORIGIN") 495 | 496 | url = f"{origin}/cgi-bin/webhook/send?key={push_config.get('QYWX_KEY')}" 497 | headers = {"Content-Type": "application/json;charset=utf-8"} 498 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 499 | response = requests.post( 500 | url=url, data=json.dumps(data), headers=headers, timeout=15 501 | ).json() 502 | 503 | if response["errcode"] == 0: 504 | print("企业微信机器人推送成功!") 505 | else: 506 | print("企业微信机器人推送失败!") 507 | 508 | 509 | def telegram_bot(title: str, content: str) -> None: 510 | """ 511 | 使用 telegram 机器人 推送消息。 512 | """ 513 | if not push_config.get("TG_BOT_TOKEN") or not push_config.get("TG_USER_ID"): 514 | print("tg 服务的 bot_token 或者 user_id 未设置!!\n取消推送") 515 | return 516 | print("tg 服务启动") 517 | 518 | if push_config.get("TG_API_HOST"): 519 | url = f"https://{push_config.get('TG_API_HOST')}/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 520 | else: 521 | url = ( 522 | f"https://api.telegram.org/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 523 | ) 524 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 525 | payload = { 526 | "chat_id": str(push_config.get("TG_USER_ID")), 527 | "text": f"{title}\n\n{content}", 528 | "disable_web_page_preview": "true", 529 | } 530 | proxies = None 531 | if push_config.get("TG_PROXY_HOST") and push_config.get("TG_PROXY_PORT"): 532 | if push_config.get("TG_PROXY_AUTH") is not None and "@" not in push_config.get( 533 | "TG_PROXY_HOST" 534 | ): 535 | push_config["TG_PROXY_HOST"] = ( 536 | push_config.get("TG_PROXY_AUTH") 537 | + "@" 538 | + push_config.get("TG_PROXY_HOST") 539 | ) 540 | proxyStr = "http://{}:{}".format( 541 | push_config.get("TG_PROXY_HOST"), push_config.get("TG_PROXY_PORT") 542 | ) 543 | proxies = {"http": proxyStr, "https": proxyStr} 544 | response = requests.post( 545 | url=url, headers=headers, params=payload, proxies=proxies 546 | ).json() 547 | 548 | if response["ok"]: 549 | print("tg 推送成功!") 550 | else: 551 | print("tg 推送失败!") 552 | 553 | 554 | def aibotk(title: str, content: str) -> None: 555 | """ 556 | 使用 智能微秘书 推送消息。 557 | """ 558 | if ( 559 | not push_config.get("AIBOTK_KEY") 560 | or not push_config.get("AIBOTK_TYPE") 561 | or not push_config.get("AIBOTK_NAME") 562 | ): 563 | print("智能微秘书 的 AIBOTK_KEY 或者 AIBOTK_TYPE 或者 AIBOTK_NAME 未设置!!\n取消推送") 564 | return 565 | print("智能微秘书 服务启动") 566 | 567 | if push_config.get("AIBOTK_TYPE") == "room": 568 | url = "https://api-bot.aibotk.com/openapi/v1/chat/room" 569 | data = { 570 | "apiKey": push_config.get("AIBOTK_KEY"), 571 | "roomName": push_config.get("AIBOTK_NAME"), 572 | "message": {"type": 1, "content": f"【青龙快讯】\n\n{title}\n{content}"}, 573 | } 574 | else: 575 | url = "https://api-bot.aibotk.com/openapi/v1/chat/contact" 576 | data = { 577 | "apiKey": push_config.get("AIBOTK_KEY"), 578 | "name": push_config.get("AIBOTK_NAME"), 579 | "message": {"type": 1, "content": f"【青龙快讯】\n\n{title}\n{content}"}, 580 | } 581 | body = json.dumps(data).encode(encoding="utf-8") 582 | headers = {"Content-Type": "application/json"} 583 | response = requests.post(url=url, data=body, headers=headers).json() 584 | print(response) 585 | if response["code"] == 0: 586 | print("智能微秘书 推送成功!") 587 | else: 588 | print(f'智能微秘书 推送失败!{response["error"]}') 589 | 590 | 591 | def smtp(title: str, content: str) -> None: 592 | """ 593 | 使用 SMTP 邮件 推送消息。 594 | """ 595 | if ( 596 | not push_config.get("SMTP_SERVER") 597 | or not push_config.get("SMTP_SSL") 598 | or not push_config.get("SMTP_EMAIL") 599 | or not push_config.get("SMTP_PASSWORD") 600 | or not push_config.get("SMTP_NAME") 601 | ): 602 | print( 603 | "SMTP 邮件 的 SMTP_SERVER 或者 SMTP_SSL 或者 SMTP_EMAIL 或者 SMTP_PASSWORD 或者 SMTP_NAME 未设置!!\n取消推送" 604 | ) 605 | return 606 | print("SMTP 邮件 服务启动") 607 | 608 | message = MIMEText(content, "plain", "utf-8") 609 | message["From"] = formataddr( 610 | ( 611 | Header(push_config.get("SMTP_NAME"), "utf-8").encode(), 612 | push_config.get("SMTP_EMAIL"), 613 | ) 614 | ) 615 | message["To"] = formataddr( 616 | ( 617 | Header(push_config.get("SMTP_NAME"), "utf-8").encode(), 618 | push_config.get("SMTP_EMAIL"), 619 | ) 620 | ) 621 | message["Subject"] = Header(title, "utf-8") 622 | 623 | try: 624 | smtp_server = ( 625 | smtplib.SMTP_SSL(push_config.get("SMTP_SERVER")) 626 | if push_config.get("SMTP_SSL") == "true" 627 | else smtplib.SMTP(push_config.get("SMTP_SERVER")) 628 | ) 629 | smtp_server.login( 630 | push_config.get("SMTP_EMAIL"), push_config.get("SMTP_PASSWORD") 631 | ) 632 | smtp_server.sendmail( 633 | push_config.get("SMTP_EMAIL"), 634 | push_config.get("SMTP_EMAIL"), 635 | message.as_bytes(), 636 | ) 637 | smtp_server.close() 638 | print("SMTP 邮件 推送成功!") 639 | except Exception as e: 640 | print(f"SMTP 邮件 推送失败!{e}") 641 | 642 | 643 | def pushme(title: str, content: str) -> None: 644 | """ 645 | 使用 PushMe 推送消息。 646 | """ 647 | if not push_config.get("PUSHME_KEY"): 648 | print("PushMe 服务的 PUSHME_KEY 未设置!!\n取消推送") 649 | return 650 | print("PushMe 服务启动") 651 | 652 | url = f'https://push.i-i.me/?push_key={push_config.get("PUSHME_KEY")}' 653 | data = { 654 | "title": title, 655 | "content": content, 656 | } 657 | response = requests.post(url, data=data) 658 | 659 | if response.status_code == 200 and response.text == "success": 660 | print("PushMe 推送成功!") 661 | else: 662 | print(f"PushMe 推送失败!{response.status_code} {response.text}") 663 | 664 | 665 | def one() -> str: 666 | """ 667 | 获取一条一言。 668 | :return: 669 | """ 670 | url = "https://v1.hitokoto.cn/" 671 | res = requests.get(url).json() 672 | return res["hitokoto"] + " ----" + res["from"] 673 | 674 | 675 | if push_config.get("BARK_PUSH"): 676 | notify_function.append(bark) 677 | if push_config.get("CONSOLE"): 678 | notify_function.append(console) 679 | if push_config.get("DD_BOT_TOKEN") and push_config.get("DD_BOT_SECRET"): 680 | notify_function.append(dingding_bot) 681 | if push_config.get("FSKEY"): 682 | notify_function.append(feishu_bot) 683 | if push_config.get("GOBOT_URL") and push_config.get("GOBOT_QQ"): 684 | notify_function.append(go_cqhttp) 685 | if push_config.get("GOTIFY_URL") and push_config.get("GOTIFY_TOKEN"): 686 | notify_function.append(gotify) 687 | if push_config.get("IGOT_PUSH_KEY"): 688 | notify_function.append(iGot) 689 | if push_config.get("PUSH_KEY"): 690 | notify_function.append(serverJ) 691 | if push_config.get("DEER_KEY"): 692 | notify_function.append(pushdeer) 693 | if push_config.get("CHAT_URL") and push_config.get("CHAT_TOKEN"): 694 | notify_function.append(chat) 695 | if push_config.get("PUSH_PLUS_TOKEN"): 696 | notify_function.append(pushplus_bot) 697 | if push_config.get("QMSG_KEY") and push_config.get("QMSG_TYPE"): 698 | notify_function.append(qmsg_bot) 699 | if push_config.get("QYWX_AM"): 700 | notify_function.append(wecom_app) 701 | if push_config.get("QYWX_KEY"): 702 | notify_function.append(wecom_bot) 703 | if push_config.get("TG_BOT_TOKEN") and push_config.get("TG_USER_ID"): 704 | notify_function.append(telegram_bot) 705 | if ( 706 | push_config.get("AIBOTK_KEY") 707 | and push_config.get("AIBOTK_TYPE") 708 | and push_config.get("AIBOTK_NAME") 709 | ): 710 | notify_function.append(aibotk) 711 | if ( 712 | push_config.get("SMTP_SERVER") 713 | and push_config.get("SMTP_SSL") 714 | and push_config.get("SMTP_EMAIL") 715 | and push_config.get("SMTP_PASSWORD") 716 | and push_config.get("SMTP_NAME") 717 | ): 718 | notify_function.append(smtp) 719 | if push_config.get("PUSHME_KEY"): 720 | notify_function.append(pushme) 721 | 722 | 723 | def send(title: str, content: str) -> None: 724 | if not content: 725 | print(f"{title} 推送内容为空!") 726 | return 727 | 728 | # 根据标题跳过一些消息推送,环境变量:SKIP_PUSH_TITLE 用回车分隔 729 | skipTitle = os.getenv("SKIP_PUSH_TITLE") 730 | if skipTitle: 731 | if title in re.split("\n", skipTitle): 732 | print(f"{title} 在SKIP_PUSH_TITLE环境变量内,跳过推送!") 733 | return 734 | 735 | hitokoto = push_config.get("HITOKOTO") 736 | 737 | text = one() if hitokoto else "" 738 | content += "大自然的搬运工\nhttp://www.bedee.top/\n\n" + text 739 | 740 | ts = [ 741 | threading.Thread(target=mode, args=(title, content), name=mode.__name__) 742 | for mode in notify_function 743 | ] 744 | [t.start() for t in ts] 745 | [t.join() for t in ts] 746 | 747 | 748 | def main(): 749 | send("title", "content") 750 | 751 | 752 | if __name__ == "__main__": 753 | main() 754 | -------------------------------------------------------------------------------- /bd_ikuuu.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | time:2023.7.8 4 | cron: 23 0 * * * 5 | new Env('ikuuu签到'); 6 | 地址:https://ikuuu.pw/ 7 | 环境变量 bd_ikuuu = 邮箱#密码 8 | 多账号新建变量或者用 & 分开 9 | 10 | """ 11 | 12 | import time 13 | import requests 14 | from os import environ, path 15 | from bs4 import BeautifulSoup 16 | 17 | 18 | # 读取通知 19 | def load_send(): 20 | global send 21 | cur_path = path.abspath(path.dirname(__file__)) 22 | if path.exists(cur_path + "/SendNotify.py"): 23 | try: 24 | from SendNotify import send 25 | print("加载通知服务成功!") 26 | except: 27 | send = False 28 | print( 29 | '''加载通知服务失败~\n请使用以下拉库地址\nql repo https://github.com/Bidepanlong/ql.git "bd_" "README" "SendNotify"''') 30 | else: 31 | send = False 32 | print( 33 | '''加载通知服务失败~\n请使用以下拉库地址\nql repo https://github.com/Bidepanlong/ql.git "bd_" "README" "SendNotify"''') 34 | 35 | 36 | load_send() 37 | 38 | 39 | # 获取环境变量 40 | def get_environ(key, default="", output=True): 41 | def no_read(): 42 | if output: 43 | print(f"未填写环境变量 {key} 请添加") 44 | exit(0) 45 | return default 46 | 47 | return environ.get(key) if environ.get(key) else no_read() 48 | 49 | 50 | class ikuuu(): 51 | def __init__(self, ck): 52 | self.msg = '' 53 | self.ck = ck 54 | self.cks = "" 55 | 56 | def sign(self): 57 | time.sleep(0.5) 58 | url = "https://ikuuu.pw/user/checkin" 59 | url1 = 'https://ikuuu.pw/user' 60 | login_url = 'https://ikuuu.pw/auth/login' 61 | 62 | login_header = { 63 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' 64 | } 65 | 66 | data = { 67 | 'email': self.ck[0], 68 | 'passwd': self.ck[1], 69 | } 70 | response = requests.post(login_url, headers=login_header, data=data) 71 | cookies = response.cookies 72 | cookies_dict = cookies.get_dict() 73 | for key, value in cookies_dict.items(): 74 | ck = f"{key}={value}" 75 | self.cks += ck + ';' 76 | 77 | headers = { 78 | 'Cookie': self.cks, 79 | 'sec-ch-ua': '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', 80 | } 81 | time.sleep(0.5) 82 | r = requests.post(url, headers=headers) 83 | time.sleep(0.5) 84 | r1 = requests.get(url1, headers=headers) 85 | try: 86 | soup = BeautifulSoup(r1.text, 'html.parser') 87 | bs = soup.find('span', {'class': 'counter'}) 88 | syll = bs.text 89 | dl = soup.find('div', {'class': 'd-sm-none d-lg-inline-block'}) 90 | name = dl.text 91 | except: 92 | xx = f"[登录]:请检查ck有效性:{self.ck}\n\n" 93 | print(xx) 94 | self.msg += xx 95 | return self.msg 96 | 97 | if r.status_code != 200: 98 | xx = f"[登录]:{name}\n[签到]:请求失败,请检查网络或者ck有效性:{self.ck}\n\n" 99 | print(xx) 100 | self.msg += xx 101 | return self.msg 102 | try: 103 | if "已经签到" in r.json()['msg']: 104 | xx = f"[登录]:{name}\n[签到]:{r.json()['msg']}\n[流量]:{syll}GB\n\n" 105 | print(xx) 106 | self.msg += xx 107 | return self.msg 108 | elif "获得" in r.json()['msg']: 109 | xx = f"[登录]:{name}\n[签到]:{r.json()['msg']}\n[流量]:{syll}GB\n\n" 110 | print(xx) 111 | self.msg += xx 112 | return self.msg 113 | else: 114 | xx = f"[登录]:未知错误,请检查网络或者ck有效性:{self.ck}\n\n" 115 | print(xx) 116 | self.msg += xx 117 | return self.msg 118 | except: 119 | xx = f"[登录]:解析响应失败,请检查网络或者ck有效性:{self.ck}\n\n" 120 | print(xx) 121 | self.msg += xx 122 | return self.msg 123 | 124 | def get_sign_msg(self): 125 | return self.sign() 126 | 127 | 128 | if __name__ == '__main__': 129 | token = get_environ("bd_ikuuu") 130 | msg = '' 131 | cks = token.split("&") 132 | print("检测到{}个ck记录\n开始ikuuu签到\n".format(len(cks))) 133 | for ck_all in cks: 134 | ck = ck_all.split("#") 135 | run = ikuuu(ck) 136 | msg += run.get_sign_msg() 137 | if send: 138 | send("ikuuu签到通知", msg) 139 | -------------------------------------------------------------------------------- /bd_xtb.py: -------------------------------------------------------------------------------- 1 | """ 2 | time:2024.4.19 3 | 定时:一天一次就行了 4 | new Env('团币自备接口版本') 5 | 抓包小程序或者app或者网页的token=Agxxxx 只要token后面的值 6 | 环境变量: 名称:bd_mttoken 值:token的值#uuid的值 7 | 8 | 如果需要一对一推送的用户, 9 | wx打开https://wxpusher.zjiecode.com/wxuser/?type=1&id=67067#/follow 10 | 关注推送应用。在进入"WxPusher消息推送平台"公众号-我的-我的UID。获取自己的UID,需要推送的用户 11 | 环境变量的值就是 token的值#uuid的值#推送UID的值 12 | 13 | 如果没推送,大概的环境变量格式就是 14 | AgXXXXXXXXXX#00000000XXXXXXX 15 | 有推送就是 16 | AgXXXXXXXXXX#00000000XXXXXXX#UID_XXXXXXX 17 | 18 | 19 | 多账号默认新建变量或者用 & 分开 20 | 并发变量: bd_xtbbf 默认不设置为1 21 | 22 | """ 23 | import requests.utils 24 | import json 25 | import random 26 | import base64 27 | import os 28 | import string 29 | from datetime import datetime 30 | import requests 31 | import time 32 | from functools import partial 33 | from user_agent import generate_user_agent 34 | import concurrent.futures 35 | from urllib3.exceptions import InsecureRequestWarning 36 | import threading 37 | from cryptography.hazmat.primitives import padding 38 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 39 | from cryptography.hazmat.backends import default_backend 40 | 41 | # 自己设备的接口穿透的 ip:port 42 | km = '127.0.0.1:12345' 43 | 44 | # 无法获取id的是否使用内置id直接运行!慎用!默认关闭! 45 | nzidrun = False 46 | 47 | # 活动开关 True/False 48 | # 果园刮刮乐 49 | run_ggl = True 50 | 51 | # 自定义变量设置,不需要的不用管。 52 | ######################################################## 53 | # wxpusher管理员运行日志汇总推送 填入管理员的 UID_xxxxxxx 54 | wxpusher_alluid = os.environ.get("bd_wxpusher_alluid") 55 | if wxpusher_alluid is None: 56 | wxpusher_alluid = '' 57 | 58 | # 自定义变量名, 59 | # 可以自己设置一个环境变量在外面调用,默认自定义变量名 bd_zdyblm,默认不设置是bd_mttoken来调用ck 60 | blname = os.environ.get("bd_zdyblm") 61 | if blname is None: 62 | blname = 'bd_mttoken' 63 | 64 | # 自定义变量分隔符,默认是 & 或者 新建变量。比如需要换行分割就改成 \n。 65 | # 可以自己设置一个环境变量在外面调用,默认自定义分割变量名 bd_zdyblm,值 & 66 | zdyfg = os.environ.get("bd_zdyfg") 67 | if zdyfg is None: 68 | zdyfg = '&' 69 | ######################################################## 70 | 71 | 72 | # 调试设置 73 | ######################################################## 74 | # 是否打印详细日志 True/False 75 | isprint = os.environ.get("bd_isprint") 76 | if isprint is None: 77 | isprint = False 78 | else: 79 | isprint = eval(isprint) 80 | 81 | # 今日团币默认大于900就不跑任务了 82 | jrtb_nums = os.environ.get("bd_jrtbnums") 83 | if jrtb_nums is None: 84 | jrtb_nums = 900 85 | else: 86 | jrtb_nums = int(jrtb_nums) 87 | 88 | # 最大游戏任务循环次数 89 | max_gamexh = os.environ.get("bd_gamexh") 90 | if max_gamexh is None: 91 | max_gamexh = 5 92 | else: 93 | max_gamexh = int(max_gamexh) 94 | 95 | # 理论现在我接口生成指纹,这个不需要动,如果没跑成功,改成100。默认最大出现50个提交完成有异常的就不跑! 96 | max_zt3 = os.environ.get("bd_maxzt3") 97 | if max_zt3 is None: 98 | max_zt3 = 500 99 | else: 100 | max_zt3 = int(max_zt3) 101 | 102 | # 玄学数字,默认4,但是如果有时候提示指纹问题,上面改了100还是无法运行,改成5 103 | xxsz = os.environ.get("bd_xxsz") 104 | if xxsz is None: 105 | xxsz = 4 106 | else: 107 | xxsz = int(xxsz) 108 | 109 | # 如果改成100,4和5都没法运行,手动看看能不能正常领取游戏中心的币 110 | ######################################################## 111 | 112 | 113 | # 代理设置 代理池和代理api只能选择一个使用 114 | ######################################################## 115 | # 是否启用代理运行 True/False 116 | # isdl = os.environ.get("bd_isdlt") 117 | isdl = os.environ.get("bd_isdlt") 118 | if isdl is None: 119 | isdl = False 120 | else: 121 | isdl = eval(isdl) 122 | 123 | # 代理api,请保证api打开直接现在一个ip地址和端口即可。环境变量bd_dlapi 值:获取的代理api 124 | proxy_api_url = os.environ.get("bd_dlapi") 125 | if proxy_api_url is None: 126 | proxy_api_url = '' 127 | # 代理api设置每多少秒切换一次 128 | dl_sleep = os.environ.get("bd_dlsleep") 129 | if dl_sleep is None: 130 | dl_sleep = 20 131 | else: 132 | dl_sleep = int(dl_sleep) 133 | 134 | # 代理池的地址 环境变量bd_dlc 值:自己的代理池的 ip:prot 135 | proxy_url = os.environ.get("bd_dlc") 136 | if proxy_url is None: 137 | proxy_url = '' 138 | 139 | # 定义全局变量的 140 | proxy = { 141 | 'http': f'http://{proxy_url}', 142 | 'https': f'http://{proxy_url}' 143 | } 144 | 145 | 146 | ######################################################### 147 | 148 | def start_dlapi(): 149 | dlstart = threading.Thread(target=get_proxy, args=(stop_event,)) 150 | dlstart.start() 151 | 152 | 153 | stop_event = threading.Event() 154 | 155 | 156 | def get_proxy(stop): 157 | a = 0 158 | while not stop.is_set(): 159 | global proxy 160 | a += 1 161 | response = requests.get(proxy_api_url) 162 | if response.status_code == 200: 163 | proxy_data = response.text 164 | if isdl: 165 | print(f'🔔第{a}次获取代理成功: {proxy_data}') 166 | proxy = { 167 | 'http': f'http://{proxy_data}', 168 | 'https': f'http://{proxy_data}' 169 | } 170 | time.sleep(dl_sleep) 171 | continue 172 | else: 173 | if isdl: 174 | print(f'🔔第{a}次获取代理失败!重新获取!') 175 | continue 176 | 177 | 178 | def ts_qb(data): 179 | # WxPusher API地址 180 | api_url = 'https://wxpusher.zjiecode.com/api/send/message' 181 | 182 | # 按照序号字段对数据进行排序 183 | sorted_data = sorted(data, key=lambda x: x['序号']) 184 | 185 | # 构造要推送的表格内容 186 | table_content = '' 187 | for row in sorted_data: 188 | table_content += f"{row['序号']}{row['用户']}{row['今日团币']}{row['总共团币']}" 189 | 190 | table_html = f"{table_content}
🆔用户今日团币总共团币
" 191 | 192 | # 构造请求参数 193 | params = { 194 | "appToken": 'AT_F84lDjyaKceMNQshI4ZYhNyENLlnh5qW', 195 | 'content': table_html, 196 | 'contentType': 3, # 表格类型 197 | 'topicIds': [], # 接收消息的用户ID列表,为空表示发送给所有用户 198 | "summary": f'小团币运行日志汇总', 199 | "uids": [wxpusher_alluid], 200 | } 201 | 202 | # 发送POST请求 203 | response = requests.post(api_url, json=params) 204 | 205 | # 检查API响应 206 | if response.status_code == 200: 207 | result = response.json() 208 | if result['code'] == 1000: 209 | print('🎉管理员汇总推送成功') 210 | else: 211 | print(f'💔管理员汇总推送失败,错误信息:{result["msg"]}') 212 | else: 213 | print('⛔️管理员汇总推送请求失败') 214 | 215 | 216 | class Mttb: 217 | def __init__(self, zh, ck): 218 | self.zw = None 219 | self.title = None 220 | self.xslist = None 221 | self.xs_headers = None 222 | self.xsid = None 223 | self.jobId = None 224 | self.property = None 225 | self.condition = None 226 | self.mtgsig = None 227 | global ts_all 228 | self.num = zh 229 | self.coins = None 230 | try: 231 | if "UID" in ck: 232 | self.ck = ck.split('#')[0] 233 | self.uuid = ck.split('#')[1] 234 | self.uid = ck.split('#')[2] 235 | else: 236 | self.ck = ck.split('#')[0] 237 | self.uuid = ck.split('#')[1] 238 | self.uid = None 239 | except: 240 | print(f'⛔️⛔️⛔️⛔️⛔️⛔️⛔️⛔️账户{self.num}异常!!!') 241 | exit(0) 242 | self.ddmsg = None 243 | self.lisss = None 244 | self.lastGmtCreated = None 245 | self.qdrwids = [10002, 10024, 10041, 10015, 10014] 246 | self.qdid = None 247 | self.llid = None 248 | self.startmsg = '' 249 | self.endmsg = '' 250 | self.llids = [] 251 | self.qdactoken = None 252 | self.xtb = None 253 | self.wcxtb = None 254 | self.t_h = None 255 | self.actoken = None 256 | self.usid = None 257 | self.name = None 258 | self.ua = generate_user_agent(os='android') 259 | self.msg = "" 260 | self.ids = [] 261 | self.noids = [15169, 15170, 15171, 15172, 15173] 262 | self.id = None 263 | self.tid = None 264 | self.data_list = None 265 | self.mtbb = 'meituan' 266 | self.platform = xxsz 267 | self.gglactoken = None 268 | self.ggl_list = None 269 | self.gglid = None 270 | self.cardId = None 271 | 272 | def wxpusher(self): 273 | msg = f'🆔{self.name}
💰今日团币: {self.coins}
🎁总共团币: {self.wcxtb}({int(self.wcxtb) / 1000}元)' 274 | str = f'''
275 |
277 |
278 |

279 | 通知 280 |

281 |
282 |
283 |
286 |
288 |

289 | 🗣 290 |

291 |
292 |
293 |
294 |
295 |
296 |

297 | {msg} 298 |

299 |
300 |
301 |
''' 302 | data = { 303 | "appToken": 'AT_F84lDjyaKceMNQshI4ZYhNyENLlnh5qW', 304 | "content": str, 305 | "summary": f'{self.name}小团币运行日志', 306 | "contentType": 2, 307 | "uids": [self.uid], 308 | } 309 | url = 'http://wxpusher.zjiecode.com/api/send/message' 310 | try: 311 | res = requests.post(url=url, json=data).json() 312 | if res['code'] == 1000: 313 | self.endmsg += f'🎉日志推送完成\n' 314 | return True 315 | else: 316 | self.endmsg += f'💔日志推送失败\n' 317 | return False 318 | except: 319 | self.endmsg += f'⛔️日志推送出错\n' 320 | return False 321 | 322 | def login(self): 323 | try_count = 5 324 | while try_count > 0: 325 | try: 326 | url = "https://open.meituan.com/user/v1/info/auditting?fields=auditAvatarUrl%2CauditUsername" 327 | h = { 328 | 'Connection': 'keep-alive', 329 | 'Origin': 'https://mtaccount.meituan.com', 330 | 'User-Agent': self.ua, 331 | 'token': self.ck, 332 | 'Referer': 'https://mtaccount.meituan.com/user/', 333 | 'Accept-Encoding': 'gzip, deflate', 334 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 335 | 'X-Requested-With': 'com.sankuai.meituan', 336 | } 337 | r = requests.get(url, headers=h) 338 | # print(r.text) 339 | if 'username' in r.text: 340 | rj = r.json() 341 | self.name = rj["user"]["username"] 342 | self.usid = rj["user"]["id"] 343 | self.zw = self.sc_zw() 344 | self.startmsg += f'🆔账号{self.num}-{self.name}({self.usid}) ✅登录成功!\n' 345 | return True 346 | elif '失败' in r.text: 347 | return False 348 | else: 349 | if isprint: 350 | self.startmsg += f'🆔账号{self.num} 登录失败:还有{try_count - 1}次重试机会\n' 351 | try_count -= 1 352 | time.sleep(random.randint(2, 5)) 353 | continue 354 | except: 355 | if isprint: 356 | self.startmsg += f'🆔账号{self.num} 登录异常:还有{try_count - 1}次重试机会\n' 357 | try_count -= 1 358 | time.sleep(random.randint(2, 5)) 359 | continue 360 | 361 | def Getmtgsig_data(self, urls, headers, body): 362 | try_count = 5 363 | while try_count > 0: 364 | try: 365 | encoded_data = base64.b64encode(body.encode('utf-8')) 366 | bodybase64 = encoded_data.decode('utf-8') 367 | data = { 368 | 'km': km, 369 | 'usid': self.usid, 370 | 'method': 'POST', 371 | 'url': urls, 372 | 'ua': self.ua, 373 | 'bbody': bodybase64 374 | } 375 | r = requests.post('http://bedee.top:12333/mtgsig', json=data) 376 | if '成功' in r.text and r.json()['usid'] == self.usid: 377 | if isprint: 378 | print(f'🆔账号{self.num}-{self.name} {r.json()["msg"]}') 379 | self.mtgsig = r.json()['mtgsig'] 380 | headers['mtgsig'] = self.mtgsig 381 | if isdl: 382 | r = requests.post(url=urls, headers=headers, data=body, timeout=10, verify=False,proxies=proxy) 383 | else: 384 | r = requests.post(url=urls, headers=headers, data=body, timeout=10, verify=False) 385 | return r 386 | elif '失败' in r.text: 387 | print(r.json()['msg']) 388 | return False 389 | elif r.json()['usid'] != self.usid: 390 | print(f'🆔账号{self.num}-{self.name} 请求异常,返回的参数不对!\n') 391 | try_count -= 1 392 | time.sleep(random.randint(3, 8)) 393 | continue 394 | else: 395 | try_count -= 1 396 | time.sleep(random.randint(3, 8)) 397 | continue 398 | except Exception as e: 399 | try_count -= 1 400 | if isprint: 401 | self.endmsg += f'🆔账号{self.num}-{self.name} 请求异常,还有{try_count}次重试机会\n' 402 | time.sleep(random.randint(3, 8)) 403 | if try_count == 0: 404 | print(f'🆔账号{self.num}-{self.name} 结束运行~') 405 | return False 406 | 407 | def sc_zw(self): 408 | # 设置加密秘钥和加密Iv 409 | key = b'kwBq8snI' 410 | iv = b'kwBq8snI' 411 | 412 | # 转换加密内容为字节类型 413 | data = b'{"A32":[],"A38":42,"A14":"AA\\u003d\\u003d\\n","A53":"1200190209","A23":"MOLY.LR13.R1.TC8.SP.V2.P59,MOLY.LR13.R1.TC8.SP.V2.P59","A16":97.0,"A21":"Unplugged","A29":1710463703,"A10":"Redmi","A48":"Redmi/begonia/begonia:11/RP1A.200720.011/V12.5.6.0.RGGCNXM:user/release-keys","A8":"RP1A.200720.011","A12":"unknown","A51":"DP","A25":[],"A56":"xiaomi","A33":8,"A20":"2000000","A4":"aarch64","A18":"Redmi Note 8 Pro","A26":"1080,2220","A19":440,"A52":"DP","A54":"3.14159265358979323846264338327950288419716939937510","A40":1710654956463,"A7":"unknown","A35":{"hashInfo":[],"number":0},"A24":"unknown","A34":"unknown","A41":1710857434000,"A3":"unknown","A28":1710857983443,"A57":"////PwAAAgAQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\u003d\\n","A36":null,"A42":1,"A9":"unknown","A55":"428410883","A1":"android","A30":{"hashInfo":[],"number":0},"A11":"WIFI","A15":"","A37":"com.android.browser-com.android.calendar-com.android.camera-com.android.contacts-com.android.contacts-com.android.deskclock-com.android.fileexplorer-com.android.mms-com.android.settings-com.android.thememanager","A22":"11","A13":"unknown","A43":"1230768000000","A5":"dpsheb275afb5fc715339061ebc6571adfccatpu","A44":0,"A6":1,"A2":1710857982866,"A45":5,"A49":"DP","A46":"97460768768@118164561920","A39":"com.android.soundrecorder-com.miui.calculator-com.xiaomi.scanner-bin.mt.plus-com.guoshi.httpcanary.premium-com.jingdong.app.mall-com.jmxxqyand.bingcheng-com.junge.algorithmAide-com.meituan.turbo-com.miui.screenrecorder","A27":0.0,"A50":"000000000000016066FDF138B43928771EF787713DCF1A171003093481310199","A47":"unknown","A31":[],"A17":[]}' 414 | 415 | # 将data解码为字符串 416 | data_str = data.decode('utf-8') 417 | 418 | # 将字符串转换为JSON对象 419 | json_obj = json.loads(data_str) 420 | 421 | json_obj['A29'] = int(time.time() - random.randint(100, 300)) 422 | json_obj['A2'] = int(time.time() * 1000.0000001) 423 | json_obj['A28'] = json_obj['A2'] + random.randint(280, 300) 424 | json_obj['A40'] = int(time.time() * 1000 - random.randint(4000, 5000)) 425 | a = random.randint(12345678911, 98765432101) 426 | b = random.randint(123456789102, 987654321012) 427 | json_obj['A46'] = f'{a}@{b}' 428 | json_obj['A50'] = self.uuid 429 | # json_obj['A36']['latitude'] = round(random.uniform(29.6067111, 29.6067999), 7) 430 | # json_obj['A36']['longitude'] = round(random.uniform(94.3670111, 94.3670999), 7) 431 | updated_data = json.dumps(json_obj).replace(", ", ",").replace(": ", ":").replace("=", "\\u003d").encode( 432 | 'utf-8') 433 | padder = padding.PKCS7(64).padder() 434 | padded_data = padder.update(updated_data) + padder.finalize() 435 | cipher = Cipher(algorithms.TripleDES(key), modes.CBC(iv), backend=default_backend()) 436 | encryptor = cipher.encryptor() 437 | encrypted_data = encryptor.update(padded_data) + encryptor.finalize() 438 | encoded_data = base64.b64encode(encrypted_data).decode('utf-8') 439 | lines = [encoded_data[i:i + 76] for i in range(0, len(encoded_data), 76)] 440 | formatted_data = '\n'.join(lines) 441 | if len(lines[-1]) < 76: 442 | formatted_data += '\n' 443 | # formatted_data = formatted_data.replace('\n', '\\n') 444 | return formatted_data 445 | 446 | def act(self): 447 | try_count = 5 448 | while try_count > 0: 449 | try: 450 | url = 'https://game.meituan.com/mgc/gamecenter/front/api/v1/login?yodaReady=h5&csecplatform=4&csecversion=2.3.1' 451 | h = { 452 | 'accessToken': '', 453 | 'Accept': 'application/json, text/plain, */*', 454 | 'Content-Length': '307', 455 | 'x-requested-with': 'XMLHttpRequest', 456 | 'User-Agent': self.ua, 457 | 'Content-Type': 'application/json;charset=UTF-8', 458 | 'Cookie': f'token={self.ck}' 459 | } 460 | sing = ''.join(random.choices(string.ascii_letters + string.digits, k=16)) 461 | data = { 462 | "mtToken": self.ck, 463 | "deviceUUID": self.uuid, 464 | "mtUserId": self.usid, 465 | "idempotentString": sing 466 | } 467 | # body = json.dumps(data) 468 | # r = self.Getmtgsig_data(url, h, body) 469 | if isdl: 470 | r = requests.post(url, headers=h, json=data, timeout=10, verify=False) 471 | else: 472 | r = requests.post(url, headers=h, json=data, timeout=10, verify=False) 473 | if r.json()['data']['loginInfo']['accessToken'] is not None: 474 | self.actoken = r.json()['data']['loginInfo']['accessToken'] 475 | return True 476 | else: 477 | if isprint: 478 | self.startmsg += f'🆔账号{self.num}-{self.name} 获取actoken异常:还有{try_count - 1}次重试机会\n' 479 | try_count -= 1 480 | time.sleep(random.randint(2, 5)) 481 | continue 482 | except: 483 | if isprint: 484 | self.startmsg += f'🆔账号{self.num}-{self.name} 获取actoken异常:还有{try_count - 1}次重试机会\n' 485 | try_count -= 1 486 | time.sleep(random.randint(2, 5)) 487 | continue 488 | 489 | def get_mtgsig(self, urls, body): 490 | try_count = 5 491 | while try_count > 0: 492 | try: 493 | encoded_data = base64.b64encode(body.encode('utf-8')) 494 | bodybase64 = encoded_data.decode('utf-8') 495 | data = { 496 | 'km': km, 497 | 'usid': self.usid, 498 | 'method': 'POST', 499 | 'url': urls, 500 | 'ua': self.ua, 501 | 'bbody': bodybase64 502 | } 503 | r = requests.post('http://bedee.top:12333/mtgsig', json=data) 504 | if '成功' in r.text and r.json()['usid'] == self.usid: 505 | if isprint: 506 | print(f'🆔账号{self.num}-{self.name} {r.json()["msg"]}') 507 | return r.json()['mtgsig'] 508 | elif '卡密次数不足' in r.text or '失败' in r.text: 509 | print(r.json()['msg']) 510 | return False 511 | elif r.json()['usid'] != self.usid: 512 | print(f'🆔账号{self.num}-{self.name} 请求异常,返回的参数不对!\n') 513 | try_count -= 1 514 | time.sleep(random.randint(3, 8)) 515 | continue 516 | else: 517 | try_count -= 1 518 | time.sleep(random.randint(3, 8)) 519 | continue 520 | except Exception as e: 521 | try_count -= 1 522 | if isprint: 523 | self.endmsg += f'🆔账号{self.num}-{self.name} 请求异常,还有{try_count}次重试机会\n' 524 | time.sleep(random.randint(3, 8)) 525 | if try_count == 0: 526 | print(f'🆔账号{self.num}-{self.name} 结束运行~') 527 | return False 528 | 529 | def get_ids(self): 530 | try_count = 5 531 | while try_count > 0: 532 | try: 533 | url = f'https://game.meituan.com/mgc/gamecenter/front/api/v1/mgcUser/task/queryMgcTaskInfo?yodaReady=h5&csecplatform=4&csecversion=2.3.1' 534 | data = { 535 | 'externalStr': '', 536 | 'riskParams': { 537 | 'uuid': self.uuid, 538 | "platform": self.platform, 539 | "fingerprint": self.zw, 540 | "version": "12.19.209", 541 | "app": 0, 542 | "cityid": "351" 543 | }, 544 | 'gameType': 10102 545 | } 546 | body = json.dumps(data, separators=(',', ':')) # 压缩数据去空格 547 | mtgsig = self.get_mtgsig(url, body) 548 | h = { 549 | "Host": "game.meituan.com", 550 | "Connection": "keep-alive", 551 | "Content-Length": "2401", 552 | 'accessToken': '', 553 | "mtgsig": mtgsig, 554 | "User-Agent": self.ua, 555 | "Content-Type": "application/json;charset=UTF-8", 556 | "Accept": "application/json, text/plain, */*", 557 | "x-requested-with": "XMLHttpRequest", 558 | "actoken": self.actoken, 559 | 'mtoken': self.ck, 560 | "Origin": "https://mgc.meituan.com", 561 | "Sec-Fetch-Site": "same-site", 562 | "Sec-Fetch-Mode": "cors", 563 | "Sec-Fetch-Dest": "empty", 564 | # "Referer": f"https://mgc.meituan.com/h5/gamehallv2.html?inner_source=10102_ch290&f=android&token=AgFXIxdLTEtVLswl3aJH_Vh80Q79nmM7UFeewkfVFXBL4Qwx9ZaXjnd5zLh_CUJkm--dHQ-0l9jH1QAAAAC1HgAAcdk87pFda7nvWTIk0vcHu81tNStEfzIUvuJzRYLp_goE4K6L2zIuCPaPfJ5TUhfS&userid=4208094795&utm_source=xiaomi&utm_medium=android&utm_term=1200190207&version_name=12.19.207&utm_content=38a5cc27b89946099157f5d8488f40f9a171003093481337514&utm_campaign=AgroupBgroupC0D300E0Gmine&ci=351&msid=38a5cc27b89946099157f5d8488f40f9a1710030934813375141710654811064&uuid=000000000000016066FDF138B43928771EF787713DCF1A171003093481310199&p_appid=10", 565 | "Accept-Encoding": "gzip, deflate", 566 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", 567 | "Cookie": f"token={self.ck};mt_c_token={self.ck};uuid={self.uuid}" 568 | } 569 | if isdl: 570 | r = requests.post(url, headers=h, data=body, timeout=10, verify=False,proxies=proxy) 571 | else: 572 | r = requests.post(url, headers=h, data=body, timeout=10, verify=False) 573 | rj = r.json() 574 | if rj['msg'] == 'ok' and rj['data']['taskList'] != []: 575 | self.data_list = rj['data']['taskList'] 576 | return True 577 | elif not rj['data']['taskList']: 578 | return False 579 | else: 580 | if isprint: 581 | self.startmsg += f'🆔账号{self.num}-{self.name} 获取游戏任务异常:还有{try_count - 1}次重试机会\n' 582 | try_count -= 1 583 | time.sleep(random.randint(2, 5)) 584 | continue 585 | except Exception as e: 586 | if isprint: 587 | self.startmsg += f'🆔账号{self.num}-{self.name} 获取游戏任务异常:还有{try_count - 1}次重试机会\n' 588 | try_count -= 1 589 | time.sleep(random.randint(2, 5)) 590 | continue 591 | 592 | def startcxtb(self): 593 | try_count = 5 594 | while try_count > 0: 595 | try: 596 | url = 'https://game.meituan.com/mgc/gamecenter/skuExchange/resource/counts?sceneId=3&gameId=10102' 597 | self.t_h = { 598 | 'User-Agent': self.ua, 599 | 'actoken': self.actoken, 600 | 'mtoken': self.ck, 601 | 'Cookie': f'token={self.ck}' 602 | } 603 | if isdl: 604 | r = requests.get(url, headers=self.t_h, timeout=10, verify=False) 605 | 606 | else: 607 | r = requests.get(url, headers=self.t_h, timeout=10, verify=False) 608 | rj = r.json() 609 | if rj['msg'] == 'ok': 610 | data = rj['data'] 611 | for d in data: 612 | self.xtb = d['count'] 613 | self.startmsg += f'🎁运行前小团币: {int(self.xtb)}({int(self.xtb) / 1000}元)\n' 614 | return True 615 | else: 616 | if isprint: 617 | self.startmsg += f'🆔账号{self.num}-{self.name} 查询运行前团币失败:还有{try_count - 1}次重试机会\n' 618 | try_count -= 1 619 | time.sleep(random.randint(3, 8)) 620 | continue 621 | except: 622 | if isprint: 623 | self.startmsg += f'🆔账号{self.num}-{self.name} 查询运行前团币异常:还有{try_count - 1}次重试机会\n' 624 | try_count -= 1 625 | time.sleep(random.randint(3, 8)) 626 | continue 627 | 628 | def endcxtb(self): 629 | try_count = 5 630 | while try_count > 0: 631 | try: 632 | url = 'https://game.meituan.com/mgc/gamecenter/skuExchange/resource/counts?sceneId=3&gameId=10102' 633 | # self.t_h = { 634 | # 'User-Agent': self.ua, 635 | # 'actoken': self.actoken, 636 | # 'mtoken': self.ck, 637 | # 'cookie': f'token={self.ck}' 638 | # } 639 | self.t_h = { 640 | 'Accept': 'application/json, text/plain, */*', 641 | 'x-requested-with': 'XMLHttpRequest', 642 | 'User-Agent': self.ua, 643 | 'Content-Type': 'application/json;charset=UTF-8', 644 | 'actoken': self.actoken, 645 | 'mtoken': self.ck, 646 | 'Cookie': f'token={self.ck}' 647 | } 648 | if isdl: 649 | r = requests.get(url, headers=self.t_h, timeout=10, verify=False) 650 | else: 651 | r = requests.get(url, headers=self.t_h, timeout=10, verify=False) 652 | rj = r.json() 653 | if rj['msg'] == 'ok': 654 | data = rj['data'] 655 | for d in data: 656 | self.wcxtb = d['count'] 657 | self.endmsg += f'🎁运行后小团币: {int(self.wcxtb)}({int(self.wcxtb) / 1000}元)\n' 658 | return True 659 | else: 660 | if isprint: 661 | self.endmsg += f'🆔账号{self.num}-{self.name} 查询运行后团币失败:还有{try_count - 1}次重试机会\n' 662 | try_count -= 1 663 | time.sleep(random.randint(3, 8)) 664 | continue 665 | except: 666 | if isprint: 667 | self.endmsg += f'🆔账号{self.num}-{self.name} 查询运行后团币异常:还有{try_count - 1}次重试机会\n' 668 | try_count -= 1 669 | time.sleep(random.randint(3, 8)) 670 | continue 671 | 672 | def b64(self): 673 | y_bytes = base64.b64encode(self.tid.encode('utf-8')) 674 | y_bytes = y_bytes.decode('utf-8') 675 | return y_bytes 676 | 677 | def get_game(self): 678 | try_count = 5 679 | while try_count > 0: 680 | try: 681 | self.tid = f'mgc-gamecenter{self.id}' 682 | self.tid = self.b64() 683 | url = f'https://game.meituan.com/mgc/gamecenter/common/mtUser/mgcUser/task/finishV2' 684 | params = { 685 | 'taskId': self.tid, 686 | } 687 | if isdl: 688 | r = requests.get(url, headers=self.t_h, params=params, timeout=10, verify=False) 689 | else: 690 | r = requests.get(url, headers=self.t_h, params=params, timeout=10, verify=False) 691 | if isprint: 692 | print(f'🆔账号{self.num}-{self.name}({self.usid}) 领取{self.id} {r.json()}') 693 | if r.status_code == 200: 694 | if r.json()['msg'] == 'ok': 695 | time.sleep(random.randint(1, 3)) 696 | return True 697 | elif '完成过' in r.text: 698 | time.sleep(random.randint(1, 3)) 699 | return False 700 | else: 701 | if isprint: 702 | print(f'🆔账号{self.num}-{self.name}({self.usid}) 任务状态: {r.text}') 703 | return False 704 | else: 705 | if isprint: 706 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.id}领取任务失败:还有{try_count - 1}次重试机会\n' 707 | try_count -= 1 708 | time.sleep(random.randint(3, 8)) 709 | continue 710 | except: 711 | if isprint: 712 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.id}领取任务异常:还有{try_count - 1}次重试机会\n' 713 | try_count -= 1 714 | time.sleep(random.randint(3, 8)) 715 | continue 716 | 717 | def post_id(self): 718 | try_count = 5 719 | while try_count > 0: 720 | try: 721 | headers = { 722 | 'Host': 'game.meituan.com', 723 | 'Connection': 'keep-alive', 724 | # 'Content-Length': '2725', 725 | 'Accept': 'application/json, text/plain, */*', 726 | 'x-requested-with': 'XMLHttpRequest', 727 | 'actoken': self.actoken, 728 | 'mtoken': self.ck, 729 | 'User-Agent': self.ua, 730 | 'Content-Type': 'application/json;charset=UTF-8', 731 | 'Origin': 'https://mgc.meituan.com', 732 | 'Sec-Fetch-Site': 'same-site', 733 | 'Sec-Fetch-Mode': 'cors', 734 | 'Sec-Fetch-Dest': 'empty', 735 | 'Referer': 'https://mgc.meituan.com/', 736 | # 'Accept-Encoding': 'gzip, deflate', 737 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 738 | 'Cookie': f'token={self.ck}' 739 | } 740 | data = { 741 | "taskId": self.id, 742 | "externalStr": "", 743 | "riskParams": { 744 | "uuid": self.uuid, 745 | "platform": 4, 746 | "fingerprint": self.zw, 747 | "version": "12.19.209", 748 | "app": 0, 749 | "cityid": "351" 750 | }, 751 | "gameType": 10102 752 | } 753 | body = json.dumps(data) 754 | r = self.Getmtgsig_data( 755 | 'https://game.meituan.com/mgc/gamecenter/front/api/v1/mgcUser/task/receiveMgcTaskReward?yodaReady=h5&csecplatform=4&csecversion=2.3.1', 756 | headers, body) 757 | if isprint: 758 | print(f'🆔账号{self.num}-{self.name}({self.usid}) 完成{self.id} {r.json()}') 759 | if r.status_code == 200: 760 | if r.json()['msg'] == 'ok': 761 | time.sleep(random.randint(1, 3)) 762 | return True 763 | elif '异常' in r.text: 764 | time.sleep(random.randint(1, 3)) 765 | return False 766 | else: 767 | print(f'🆔账号{self.num}-{self.name} {self.id},{r.text}\n') 768 | time.sleep(random.randint(1, 3)) 769 | return False 770 | else: 771 | if isprint: 772 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.id}完成任务异常:还有{try_count - 1}次重试机会\n' 773 | try_count -= 1 774 | time.sleep(random.randint(3, 8)) 775 | 776 | continue 777 | except: 778 | if isprint: 779 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.id}完成任务异常:还有{try_count - 1}次重试机会\n' 780 | try_count -= 1 781 | time.sleep(random.randint(3, 8)) 782 | continue 783 | 784 | def coin_login(self): 785 | """获取签到浏览的actoken""" 786 | try_count = 5 787 | while try_count > 0: 788 | try: 789 | headers = { 790 | 'Origin': 'https://awp.meituan.com', 791 | 'Cookie': f'token={self.ck}', 792 | 'Accept': '*/*', 793 | 'User-Agent': self.ua, 794 | 'Content-Type': 'application/json', 795 | 'Host': 'game.meituan.com', 796 | 'Connection': 'Keep-Alive', 797 | } 798 | sjc = int(time.time() * 1000.0000001) 799 | params = { 800 | 'mtUserId': self.usid, 801 | 'mtDeviceId': self.uuid, 802 | 'mtToken': self.ck, 803 | 'nonceStr': 'tq0wppcrgrc0nk26', 804 | 'gameType': 10273, 805 | 'externalStr': {"cityId": "351"}, 806 | 'shark': 1, 807 | 'yodaReady': 'h5', 808 | 'csecplatform': '4', 809 | 'csecversion': '2.3.1', 810 | # 'mtgsig': get_xsmtg(), 811 | } 812 | if isdl: 813 | r = requests.get('https://game.meituan.com/coin-marketing/login/loginMgc', headers=headers, 814 | params=params, timeout=10, verify=False) 815 | else: 816 | r = requests.get('https://game.meituan.com/coin-marketing/login/loginMgc', headers=headers, 817 | params=params, timeout=10, verify=False) 818 | self.qdactoken = r.json().get('accessToken', None) 819 | if self.qdactoken is not None: 820 | return True 821 | else: 822 | if isprint: 823 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取qdactoken异常,还有{try_count - 1}次重试机会\n' 824 | try_count -= 1 825 | time.sleep(random.randint(3, 8)) 826 | continue 827 | except: 828 | if isprint: 829 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取qdactoken异常:还有{try_count - 1}次重试机会\n' 830 | try_count -= 1 831 | time.sleep(random.randint(3, 8)) 832 | continue 833 | 834 | def qd(self): 835 | """签到和浏览任务""" 836 | try_count = 5 837 | while try_count > 0: 838 | try: 839 | headers = { 840 | 'Host': 'game.meituan.com', 841 | 'Connection': 'keep-alive', 842 | 'x-requested-with': 'XMLHttpRequest', 843 | 'appName': 'meituan', 844 | 'User-Agent': self.ua, 845 | 'Content-Type': 'application/json', 846 | 'Accept': '*/*', 847 | 'Origin': 'https://awp.meituan.com', 848 | 'Sec-Fetch-Site': 'same-site', 849 | 'Sec-Fetch-Mode': 'cors', 850 | 'Sec-Fetch-Dest': 'empty', 851 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 852 | } 853 | sjc = int(time.time() * 1000.0000001) 854 | params = { 855 | 'yodaReady': 'h5', 856 | 'csecplatform': '4', 857 | 'csecversion': '2.3.1', 858 | # 'mtgsig': get_xsmtg(), 859 | } 860 | data = { 861 | "protocolId": self.qdid, 862 | "data": {}, 863 | "riskParams": { 864 | "ip": "", 865 | "uuid": self.uuid, 866 | "platform": self.platform, 867 | "version": "12.19.209", 868 | "app": 0, 869 | "fingerprint": self.zw, 870 | "cityId": "351" 871 | }, 872 | "acToken": self.qdactoken 873 | } 874 | if self.qdid == 10024: 875 | while True: 876 | if isdl: 877 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 878 | json=data, params=params, timeout=10, verify=False) 879 | else: 880 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 881 | json=data, params=params, timeout=10, verify=False) 882 | if isprint: 883 | print(f'🆔账号{self.num}-{self.name}({self.usid}) {self.qdid}: {r.json()}') 884 | if 'interval' in r.text: 885 | xxsj = r.json()['data']['timedReward']['interval'] 886 | time.sleep(xxsj / 1000) 887 | time.sleep(random.randint(1, 3)) 888 | continue 889 | else: 890 | time.sleep(random.randint(1, 3)) 891 | break 892 | return True 893 | elif self.qdid == 10041: 894 | while True: 895 | if isdl: 896 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 897 | json=data, 898 | params=params, timeout=10, verify=False) 899 | else: 900 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 901 | json=data, 902 | params=params, timeout=10, verify=False) 903 | if isprint: 904 | print(f'🆔账号{self.num}-{self.name}({self.usid}) {self.qdid}: {r.json()}') 905 | if 'rewardAmount' in r.text: 906 | time.sleep(random.randint(1, 3)) 907 | continue 908 | else: 909 | time.sleep(random.randint(1, 3)) 910 | break 911 | return True 912 | else: 913 | if isdl: 914 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 915 | json=data, 916 | params=params, timeout=10, verify=False) 917 | else: 918 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 919 | json=data, 920 | params=params, timeout=10, verify=False) 921 | if isprint: 922 | print(f'🆔账号{self.num}-{self.name}({self.usid}) {self.qdid}: {r.json()}') 923 | time.sleep(random.randint(1, 3)) 924 | return True 925 | except: 926 | if isprint: 927 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.qdid}签到任务异常:还有{try_count - 1}次重试机会\n' 928 | try_count -= 1 929 | time.sleep(random.randint(3, 8)) 930 | continue 931 | 932 | def get_llids(self): 933 | try_count = 5 934 | while try_count > 0: 935 | try: 936 | headers = { 937 | 'Host': 'game.meituan.com', 938 | 'Connection': 'keep-alive', 939 | 'x-requested-with': 'XMLHttpRequest', 940 | 'appName': self.mtbb, 941 | 'User-Agent': self.ua, 942 | 'Accept': '*/*', 943 | 'Origin': 'https://awp.meituan.com', 944 | 'Sec-Fetch-Site': 'same-site', 945 | 'Sec-Fetch-Mode': 'cors', 946 | 'Sec-Fetch-Dest': 'empty', 947 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 948 | } 949 | sjc = int(time.time() * 1000.0000001) 950 | params = { 951 | 'yodaReady': 'h5', 952 | 'csecplatform': '4', 953 | 'csecversion': '2.3.1', 954 | # 'mtgsig': get_xsmtg(), 955 | } 956 | # "protocolId": 10002, # 签到 957 | # "protocolId": 10024, # 1 3 5 要等待时间 958 | # "protocolId": 10041, # 下滑浏览 959 | # "protocolId": 10008, # 获取id 960 | # "protocolId": 10014, # 抽奖 961 | # "protocolId": 10015, # 抽奖前运行 962 | data = { 963 | "protocolId": 10008, 964 | "data": {}, 965 | "riskParams": { 966 | "ip": "", 967 | "uuid": self.uuid, 968 | "platform": 4, 969 | "version": "12.19.209", 970 | "app": 0, 971 | "fingerprint": self.zw, 972 | "cityId": "351" 973 | }, 974 | "acToken": self.qdactoken, 975 | } 976 | if isdl: 977 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 978 | json=data, 979 | params=params, timeout=10, verify=False) 980 | else: 981 | r = requests.post('https://game.meituan.com/coin-marketing/msg/post', headers=headers, 982 | json=data, 983 | params=params, timeout=10, verify=False) 984 | time.sleep(random.randint(1, 3)) 985 | self.lisss = r.json()['data']['taskInfoList'] 986 | return True 987 | except: 988 | if isprint: 989 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.qdid}签到任务异常:还有{try_count - 1}次重试机会\n' 990 | try_count -= 1 991 | time.sleep(random.randint(3, 8)) 992 | continue 993 | 994 | def get_ll(self): 995 | try_count = 5 996 | while try_count > 0: 997 | try: 998 | headers = { 999 | 'Host': 'game.meituan.com', 1000 | 'Connection': 'keep-alive', 1001 | 'x-requested-with': 'XMLHttpRequest', 1002 | 'appName': self.mtbb, 1003 | 'User-Agent': self.ua, 1004 | 'Content-Type': 'application/json', 1005 | 'Accept': '*/*', 1006 | 'Origin': 'https://awp.meituan.com', 1007 | 'Sec-Fetch-Site': 'same-site', 1008 | 'Sec-Fetch-Mode': 'cors', 1009 | 'Sec-Fetch-Dest': 'empty', 1010 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 1011 | } 1012 | sjc = int(time.time() * 1000.0000001) 1013 | params = { 1014 | 'yodaReady': 'h5', 1015 | 'csecplatform': '4', 1016 | 'csecversion': '2.3.1', 1017 | # 'mtgsig': get_xsmtg(), 1018 | } 1019 | 1020 | get_data = { 1021 | "protocolId": 10010, # 先运行获取任务 1022 | "data": { 1023 | "externalStr": {"cityId": "351"}, 1024 | "taskId": self.llid, # 任务id 1025 | "taskEntranceType": "normal" 1026 | }, 1027 | "riskParams": { 1028 | "ip": "", 1029 | "uuid": self.uuid, 1030 | "platform": 4, 1031 | "version": "12.19.209", 1032 | "app": 0, 1033 | "fingerprint": self.zw, 1034 | "cityId": "351" 1035 | }, 1036 | "acToken": self.qdactoken, 1037 | "mtToken": self.ck 1038 | } 1039 | if isdl: 1040 | r = requests.post( 1041 | 'https://game.meituan.com/coin-marketing/msg/post', headers=headers, 1042 | json=get_data, 1043 | params=params, timeout=10, verify=False 1044 | ) 1045 | else: 1046 | r = requests.post( 1047 | 'https://game.meituan.com/coin-marketing/msg/post', headers=headers, 1048 | json=get_data, 1049 | params=params, timeout=10, verify=False 1050 | ) 1051 | if isprint: 1052 | print(f'🆔账号{self.num}-{self.name}({self.usid}) {self.llid} 领取任务 {r.json()}') 1053 | if r.json()['data'] is None: 1054 | time.sleep(random.randint(1, 3)) 1055 | return False 1056 | else: 1057 | time.sleep(random.randint(1, 3)) 1058 | return True 1059 | except: 1060 | if isprint: 1061 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.llid}获取浏览任务异常:还有{try_count - 1}次重试机会\n' 1062 | try_count -= 1 1063 | time.sleep(random.randint(3, 8)) 1064 | continue 1065 | 1066 | def post_ll(self): 1067 | try_count = 5 1068 | while try_count > 0: 1069 | try: 1070 | headers = { 1071 | "Host": "game.meituan.com", 1072 | "Connection": "keep-alive", 1073 | "Content-Length": "747", 1074 | "x-requested-with": "XMLHttpRequest", 1075 | "appName": self.mtbb, 1076 | "innerSource": "10273_yxdt", 1077 | "User-Agent": self.ua, 1078 | "Content-Type": "application/json", 1079 | "Accept": "*/*", 1080 | "Origin": "https://mgc.meituan.com", 1081 | "Sec-Fetch-Site": "same-site", 1082 | "Sec-Fetch-Mode": "cors", 1083 | "Sec-Fetch-Dest": "empty", 1084 | "Accept-Encoding": "gzip, deflate", 1085 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" 1086 | } 1087 | sjc = int(time.time() * 1000.0000001) 1088 | params = { 1089 | 'yodaReady': 'h5', 1090 | 'csecplatform': '4', 1091 | 'csecversion': '2.3.1', 1092 | # 'mtgsig': get_xsmtg(), 1093 | } 1094 | 1095 | post_data = { 1096 | "protocolId": 10009, 1097 | "data": { 1098 | "externalStr": "{\"cityId\":\"351\"}", 1099 | "taskId": f'{self.llid}', 1100 | "taskEntranceType": "normal" 1101 | }, 1102 | "riskParams": { 1103 | "ip": "", 1104 | "uuid": self.uuid, 1105 | "platform": 4, 1106 | "version": "12.19.209", 1107 | "app": 0, 1108 | "fingerprint": self.zw, 1109 | "cityId": "351" 1110 | }, 1111 | "acToken": self.qdactoken, 1112 | "mtToken": self.ck 1113 | } 1114 | if isdl: 1115 | r = requests.post( 1116 | 'https://game.meituan.com/coin-marketing/msg/post', headers=headers, 1117 | json=post_data, 1118 | params=params, timeout=10, verify=False, 1119 | proxies=proxy 1120 | ) 1121 | else: 1122 | r = requests.post( 1123 | 'https://game.meituan.com/coin-marketing/msg/post', headers=headers, 1124 | json=post_data, 1125 | params=params, timeout=10, verify=False 1126 | ) 1127 | if isprint: 1128 | print(f'🆔账号{self.num}-{self.name}({self.usid}) {self.llid} 完成任务 {r.json()}\n') 1129 | if r.json()['data'] is None: 1130 | time.sleep(random.randint(1, 3)) 1131 | return False 1132 | else: 1133 | time.sleep(random.randint(1, 3)) 1134 | return True 1135 | except: 1136 | if isprint: 1137 | self.endmsg += f'🆔账号{self.num}-{self.name} {self.llid}完成浏览任务异常:还有{try_count - 1}次重试机会\n' 1138 | try_count -= 1 1139 | time.sleep(random.randint(3, 8)) 1140 | continue 1141 | 1142 | def runq_jrtb(self): 1143 | try_count = 5 1144 | while try_count > 0: 1145 | try: 1146 | url = "https://game.meituan.com/mgc/gamecenter/skuExchange/resources/change/logs?changeType=1&limit=50&sceneId=2&gameId=10139&mtToken=&acToken=&shark=1&yodaReady=h5&csecplatform=4&csecversion=2.3.1" 1147 | headers = { 1148 | "Host": "game.meituan.com", 1149 | "Connection": "keep-alive", 1150 | "x-requested-with": "XMLHttpRequest", 1151 | "actoken": self.qdactoken, 1152 | "mtoken": self.ck, 1153 | "User-Agent": "Mozilla/5.0 (Linux; Android 13; V2055A Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.74 Mobile Safari/537.36 TitansX/11.38.10 KNB/1.2.0 android/13 mt/com.meituan.turbo/2.0.202 App/10120/2.0.202 MeituanTurbo/2.0.202", 1154 | "Content-Type": "application/json", 1155 | "Accept": "*/*", 1156 | "Origin": "https://awp.meituan.com", 1157 | "Sec-Fetch-Site": "same-site", 1158 | "Sec-Fetch-Mode": "cors", 1159 | "Sec-Fetch-Dest": "empty", 1160 | "Referer": "https://awp.meituan.com/", 1161 | "Accept-Encoding": "gzip, deflate", 1162 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" 1163 | } 1164 | if isdl: 1165 | r = requests.get(url, headers=headers, timeout=10, verify=False) 1166 | else: 1167 | r = requests.get(url, headers=headers, timeout=10, verify=False) 1168 | if r.json()['msg'] == 'ok': 1169 | datalist = r.json()['data'] 1170 | coins = 0 1171 | for data in datalist: 1172 | coin = data['changeCount'] 1173 | gmtCreated = data['gmtCreated'] 1174 | if gmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1175 | coins += coin 1176 | else: 1177 | break 1178 | self.lastGmtCreated = datalist[-1]['gmtCreated'] 1179 | while True: 1180 | if self.lastGmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1181 | url1 = f"https://game.meituan.com/mgc/gamecenter/skuExchange/resources/change/logs?changeType=1&limit=50&sceneId=2&lastGmtCreated={self.lastGmtCreated}&gameId=10139&mtToken=&acToken=&shark=1&yodaReady=h5&csecplatform=4&csecversion=2.3.1" 1182 | if isdl: 1183 | r = requests.get(url1, headers=headers, timeout=10, verify=False) 1184 | else: 1185 | r = requests.get(url1, headers=headers, timeout=10, verify=False) 1186 | # if isprint: 1187 | # print(r.json()) 1188 | # print() 1189 | if 'ok' in r.text and r.json()['data'] != []: 1190 | datalist = r.json()['data'] 1191 | for data in datalist: 1192 | coin = data['changeCount'] 1193 | gmtCreated = data['gmtCreated'] 1194 | if gmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1195 | coins += coin 1196 | else: 1197 | break 1198 | self.lastGmtCreated = datalist[-1]['gmtCreated'] 1199 | if self.lastGmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1200 | time.sleep(random.randint(1, 3)) 1201 | continue 1202 | else: 1203 | self.coins = coins 1204 | self.startmsg += f'💰今日团币: {coins}\n' 1205 | return True 1206 | elif 'ok' in r.text and r.json()['data'] == []: 1207 | self.coins = coins 1208 | self.endmsg += f'💰今日团币: {coins}\n' 1209 | return True 1210 | else: 1211 | if isprint: 1212 | self.startmsg += f'🆔账号{self.num}-{self.name} 获取今日团币异常:还有{try_count - 1}次重试机会\n' 1213 | try_count -= 1 1214 | time.sleep(random.randint(2, 5)) 1215 | continue 1216 | else: 1217 | self.coins = coins 1218 | self.startmsg += f'💰今日团币: {coins}\n' 1219 | return True 1220 | break 1221 | else: 1222 | if isprint: 1223 | self.startmsg += f'🆔账号{self.num}-{self.name} 获取今日团币异常:还有{try_count - 1}次重试机会\n' 1224 | try_count -= 1 1225 | time.sleep(random.randint(2, 5)) 1226 | continue 1227 | except: 1228 | if isprint: 1229 | self.startmsg += f'🆔账号{self.num}-{self.name} 获取今日团币异常:还有{try_count - 1}次重试机会\n' 1230 | try_count -= 1 1231 | time.sleep(random.randint(2, 5)) 1232 | continue 1233 | 1234 | def tj_bchd(self): 1235 | try_count = 5 1236 | while try_count > 0: 1237 | try: 1238 | bchd = int(self.wcxtb) - int(self.xtb) 1239 | url = "https://game.meituan.com/mgc/gamecenter/skuExchange/resources/change/logs?changeType=1&limit=50&sceneId=2&gameId=10139&mtToken=&acToken=&shark=1&yodaReady=h5&csecplatform=4&csecversion=2.3.1" 1240 | headers = { 1241 | "Host": "game.meituan.com", 1242 | "Connection": "keep-alive", 1243 | "x-requested-with": "XMLHttpRequest", 1244 | "actoken": self.qdactoken, 1245 | "mtoken": self.ck, 1246 | "User-Agent": "Mozilla/5.0 (Linux; Android 13; V2055A Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.74 Mobile Safari/537.36 TitansX/11.38.10 KNB/1.2.0 android/13 mt/com.meituan.turbo/2.0.202 App/10120/2.0.202 MeituanTurbo/2.0.202", 1247 | "Content-Type": "application/json", 1248 | "Accept": "*/*", 1249 | "Origin": "https://awp.meituan.com", 1250 | "Sec-Fetch-Site": "same-site", 1251 | "Sec-Fetch-Mode": "cors", 1252 | "Sec-Fetch-Dest": "empty", 1253 | "Referer": "https://awp.meituan.com/", 1254 | "Accept-Encoding": "gzip, deflate", 1255 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" 1256 | 1257 | } 1258 | if isdl: 1259 | r = requests.get(url, headers=headers, timeout=10, verify=False) 1260 | else: 1261 | r = requests.get(url, headers=headers, timeout=10, verify=False) 1262 | if r.json()['msg'] == 'ok': 1263 | datalist = r.json()['data'] 1264 | coins = 0 1265 | for data in datalist: 1266 | coin = data['changeCount'] 1267 | gmtCreated = data['gmtCreated'] 1268 | if gmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1269 | coins += coin 1270 | else: 1271 | break 1272 | self.lastGmtCreated = datalist[-1]['gmtCreated'] 1273 | while True: 1274 | if self.lastGmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1275 | url1 = f"https://game.meituan.com/mgc/gamecenter/skuExchange/resources/change/logs?changeType=1&limit=50&sceneId=2&lastGmtCreated={self.lastGmtCreated}&gameId=10139&mtToken=&acToken=&shark=1&yodaReady=h5&csecplatform=4&csecversion=2.3.1" 1276 | if isdl: 1277 | r = requests.get(url1, headers=headers, timeout=10, verify=False) 1278 | else: 1279 | r = requests.get(url1, headers=headers, timeout=10, verify=False) 1280 | # if isprint: 1281 | # print(r.json()) 1282 | # print() 1283 | if 'ok' in r.text and r.json()['data'] != []: 1284 | datalist = r.json()['data'] 1285 | for data in datalist: 1286 | coin = data['changeCount'] 1287 | gmtCreated = data['gmtCreated'] 1288 | if gmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1289 | coins += coin 1290 | else: 1291 | break 1292 | self.lastGmtCreated = datalist[-1]['gmtCreated'] 1293 | if self.lastGmtCreated >= f"{datetime.now().strftime('%Y-%m-%d')} 00:00:00": 1294 | time.sleep(random.randint(1, 3)) 1295 | continue 1296 | else: 1297 | self.coins = coins 1298 | self.endmsg += f'🔥本次获得小团币: {bchd}\n💰今日团币: {coins}\n' 1299 | return True 1300 | elif 'ok' in r.text and r.json()['data'] == []: 1301 | self.coins = coins 1302 | self.endmsg += f'🔥本次获得小团币: {bchd}\n💰今日团币: {coins}\n' 1303 | return True 1304 | else: 1305 | if isprint: 1306 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取今日团币异常:还有{try_count - 1}次重试机会\n' 1307 | try_count -= 1 1308 | time.sleep(random.randint(2, 5)) 1309 | continue 1310 | else: 1311 | self.coins = coins 1312 | self.endmsg += f'🔥本次获得小团币: {bchd}\n💰今日团币: {coins}\n' 1313 | return True 1314 | break 1315 | else: 1316 | if isprint: 1317 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取今日团币异常:还有{try_count - 1}次重试机会\n' 1318 | try_count -= 1 1319 | time.sleep(random.randint(2, 5)) 1320 | continue 1321 | except: 1322 | if isprint: 1323 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取今日团币异常:还有{try_count - 1}次重试机会\n' 1324 | try_count -= 1 1325 | time.sleep(random.randint(2, 5)) 1326 | continue 1327 | 1328 | def run_game2(self): 1329 | i_num = 0 1330 | for i in self.ids: 1331 | zong = len(self.ids) 1332 | self.id = i 1333 | if self.id in self.noids: 1334 | pass 1335 | else: 1336 | if self.id in [386, 510, 511, 332]: 1337 | i_num += 1 1338 | a = 0 1339 | while a < 5: 1340 | a += 1 1341 | if isprint: 1342 | print( 1343 | f'\n🆔账号{self.num}-{self.name}({self.usid}) 任务{i_num}/{zong} id: {self.id} 第{a}次') 1344 | if self.get_game(): 1345 | self.post_id() 1346 | continue 1347 | else: 1348 | break 1349 | continue 1350 | else: 1351 | i_num += 1 1352 | if isprint: 1353 | print( 1354 | f'\n🆔账号{self.num}-{self.name}({self.usid}) 任务{i_num}/{zong} id: {self.id}') 1355 | if self.get_game(): 1356 | self.post_id() 1357 | continue 1358 | 1359 | def get_new_llids(self): 1360 | if self.get_llids(): 1361 | self.llids = [] 1362 | for i in self.lisss: 1363 | taskTitles = json.loads(i['mgcTaskBaseInfo']['viewExtraJson']) 1364 | buttonName = taskTitles.get('common', None).get('buttonName', '去完成') 1365 | zt = i['status'] 1366 | if zt == 2 and buttonName in ['去完成', '去浏览', '去阅读', '去领取']: 1367 | self.llids.append(i['id']) 1368 | elif zt == 3 and buttonName in ['去完成', '去浏览', '去阅读', '去领取']: 1369 | self.llids.append(i['id']) 1370 | else: 1371 | pass 1372 | if isprint: 1373 | print(f'🆔账号{self.num}-{self.name}({self.usid}) 获取到{len(self.llids)}个浏览任务!\n{self.llids}') 1374 | if self.llids: 1375 | return True 1376 | else: 1377 | return False 1378 | else: 1379 | return False 1380 | 1381 | def run_tbzx(self): 1382 | for i in self.lisss: 1383 | zt = i['status'] 1384 | self.llid = i['id'] 1385 | taskTitles = json.loads(i['mgcTaskBaseInfo']['viewExtraJson']) 1386 | taskTitle = taskTitles['common']['taskTitle'] 1387 | taskDesc = taskTitles['common']['taskDesc'] 1388 | buttonName = taskTitles.get('common', None).get('buttonName', '去完成') 1389 | if zt in [2, 3] and self.llid == 15181: 1390 | if isprint: 1391 | print( 1392 | f'🆔账号{self.num}-{self.name}({self.usid}) {self.llid}: 状态:{zt} {taskTitle}({taskDesc}) {buttonName}') 1393 | while True: 1394 | if self.get_ll(): 1395 | if self.post_ll(): 1396 | continue 1397 | else: 1398 | break 1399 | else: 1400 | break 1401 | elif zt == 2 and buttonName in ['去完成', '去浏览', '去阅读', '去领取']: 1402 | if isprint: 1403 | print( 1404 | f'🆔账号{self.num}-{self.name}({self.usid}) {self.llid}: 状态:{zt} {taskTitle}({taskDesc}) {buttonName}') 1405 | if self.get_ll(): 1406 | self.post_ll() 1407 | elif zt == 3 and buttonName in ['去完成', '去浏览', '去阅读', '去领取']: 1408 | if isprint: 1409 | print( 1410 | f'🆔账号{self.num}-{self.name}({self.usid}) {self.llid}: 状态:{zt} {taskTitle}({taskDesc}) {buttonName}') 1411 | self.post_ll() 1412 | else: 1413 | continue 1414 | 1415 | def run_tbrw(self): 1416 | self.read_sign() 1417 | if self.get_new_llids(): 1418 | self.run_tbzx() 1419 | self.mtbb = 'meituanturbo' 1420 | if self.get_new_llids(): 1421 | self.run_tbzx() 1422 | # self.llid = 17622 1423 | # if self.get_ll(): 1424 | # self.post_ll() 1425 | # self.qdid = 10014 1426 | # self.qd() 1427 | for i in self.qdrwids: 1428 | self.qdid = i 1429 | self.qd() 1430 | else: 1431 | pass 1432 | 1433 | def read_sign(self): 1434 | try_count = 5 1435 | while try_count > 0: 1436 | try: 1437 | url = 'https://web.meituan.com/novel/marketing/sign/signV2' 1438 | headers = { 1439 | 'Host': 'web.meituan.com', 1440 | 'appType': 'group', 1441 | 'token': self.ck, 1442 | 'content-type': 'application/json', 1443 | 'User-Agent': self.ua, 1444 | 'Referer': 'https://servicewechat.com/wxde8ac0a21135c07d/1248/page-frame.html', 1445 | } 1446 | 1447 | params = { 1448 | 'yodaReady': 'wx', 1449 | 'csecappid': 'wxde8ac0a21135c07d', 1450 | 'csecplatform': '3', 1451 | 'csecversionname': '7.49.4', 1452 | 'csecversion': '1.4.0', 1453 | } 1454 | json_data = { 1455 | 'fingerprint': '', 1456 | } 1457 | r = requests.post(url=url, params=params, headers=headers, json=json_data) 1458 | if '成功' in r.text: 1459 | response = r.json() 1460 | times = response['data']['times'] 1461 | sign_list = response['data']['signList'] 1462 | award_amount_list = [item['awardAmount'] for item in sign_list if item['signed']] 1463 | if isprint: 1464 | print( 1465 | f"🆔账号{self.num}-{self.name} 第{times}天阅读签到成功📕,今日已获得{award_amount_list[-1]}团币") 1466 | time.sleep(random.randint(1, 3)) 1467 | return True 1468 | else: 1469 | if isprint: 1470 | self.endmsg += f'🆔账号{self.num}-{self.name} 小说签到异常:还有{try_count - 1}次重试机会\n' 1471 | try_count -= 1 1472 | time.sleep(random.randint(2, 5)) 1473 | continue 1474 | 1475 | except: 1476 | if isprint: 1477 | self.endmsg += f'🆔账号{self.num}-{self.name} 小说签到异常:还有{try_count - 1}次重试机会\n' 1478 | try_count -= 1 1479 | time.sleep(random.randint(2, 5)) 1480 | continue 1481 | 1482 | def game_gift(self): 1483 | url = "https://game.meituan.com/mgc/gamecenter/front/api/v1/mgcUser/gift/xtb/exchangeWeekCard?yodaReady=h5&csecplatform=4&csecversion=2.3.1&mtgsig={}" 1484 | h = { 1485 | 'Accept': 'application/json, text/plain, */*', 1486 | 'x-requested-with': 'XMLHttpRequest', 1487 | 'User-Agent': self.ua, 1488 | 'Content-Type': 'application/json;charset=UTF-8', 1489 | 'actoken': self.actoken, 1490 | 'mtoken': self.ck, 1491 | 'Cookie': f'token={self.ck}' 1492 | } 1493 | if isdl: 1494 | r = requests.get(url, headers=h, timeout=10, verify=False) 1495 | time.sleep(random.randint(1, 3)) 1496 | else: 1497 | r = requests.get(url, headers=h, timeout=10, verify=False) 1498 | time.sleep(random.randint(1, 3)) 1499 | if isprint: 1500 | print(r.text) 1501 | 1502 | def get_gglactoken(self): 1503 | try_count = 5 1504 | while try_count > 0: 1505 | try: 1506 | headers = { 1507 | 'Host': 'guoyuan.meituan.com', 1508 | 'Connection': 'keep-alive', 1509 | 'Content-Length': '119', 1510 | 'Accept': 'application/json, text/plain, */*', 1511 | 'x-requested-with': 'XMLHttpRequest', 1512 | 'mtoken': self.ck, 1513 | 'User-Agent': self.ua, 1514 | 'Content-Type': 'application/json;charset=UTF-8', 1515 | 'Origin': 'https://guoyuan.meituan.com', 1516 | 'Sec-Fetch-Site': 'same-origin', 1517 | 'Sec-Fetch-Mode': 'cors', 1518 | 'Sec-Fetch-Dest': 'empty', 1519 | 'Accept-Encoding': 'gzip, deflate', 1520 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 1521 | 'Cookie': f'token={self.ck}' 1522 | } 1523 | sjc = int(time.time() * 1000.0000001) 1524 | params = { 1525 | 'yodaReady': 'h5', 1526 | 'csecplatform': '4', 1527 | 'csecversion': '2.3.1', 1528 | # 'mtgsig': get_xsmtg(), 1529 | } 1530 | data = { 1531 | 'uuid': self.uuid, 1532 | 'scratchSource': 1, 1533 | 'idempotent': 'pr2l4wrcn7' 1534 | } 1535 | r = requests.post('https://guoyuan.meituan.com/scratch/index', params=params, headers=headers, 1536 | json=data) 1537 | self.gglactoken = r.json().get('data').get('acToken', None) 1538 | if self.gglactoken is not None: 1539 | time.sleep(random.randint(1, 3)) 1540 | return True 1541 | else: 1542 | if isprint: 1543 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取刮刮乐actoken异常:还有{try_count - 1}次重试机会\n' 1544 | try_count -= 1 1545 | time.sleep(random.randint(3, 8)) 1546 | continue 1547 | except: 1548 | if isprint: 1549 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取刮刮乐actoken异常:还有{try_count - 1}次重试机会\n' 1550 | try_count -= 1 1551 | time.sleep(random.randint(3, 8)) 1552 | continue 1553 | 1554 | def get_ggllist(self): 1555 | try_count = 5 1556 | while try_count > 0: 1557 | try: 1558 | headers = { 1559 | 'Host': 'guoyuan.meituan.com', 1560 | 'Connection': 'keep-alive', 1561 | 'Accept': 'application/json, text/plain, */*', 1562 | 'x-requested-with': 'XMLHttpRequest', 1563 | 'acToken': self.gglactoken, 1564 | 'mtoken': self.ck, 1565 | 'User-Agent': self.ua, 1566 | 'Sec-Fetch-Site': 'same-origin', 1567 | 'Sec-Fetch-Mode': 'cors', 1568 | 'Sec-Fetch-Dest': 'empty', 1569 | 'Accept-Encoding': 'gzip, deflate', 1570 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 1571 | 'Cookie': f'token={self.ck}' 1572 | } 1573 | sjc = int(time.time() * 1000.0000001) 1574 | params = { 1575 | 'scratchSource': '1', 1576 | 'yodaReady': 'h5', 1577 | 'csecplatform': '4', 1578 | 'csecversion': '2.3.1', 1579 | # 'mtgsig': get_xsmtg(), 1580 | } 1581 | r = requests.get('https://guoyuan.meituan.com/scratch/mgcUser/taskList', params=params, 1582 | headers=headers) 1583 | self.ggl_list = r.json().get('data').get('taskList', None) 1584 | if self.ggl_list: 1585 | time.sleep(random.randint(1, 3)) 1586 | return True 1587 | else: 1588 | if isprint: 1589 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取刮刮乐任务列表异常:还有{try_count - 1}次重试机会\n' 1590 | try_count -= 1 1591 | time.sleep(random.randint(3, 8)) 1592 | continue 1593 | except: 1594 | if isprint: 1595 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取刮刮乐任务列表异常:还有{try_count - 1}次重试机会\n' 1596 | try_count -= 1 1597 | time.sleep(random.randint(3, 8)) 1598 | continue 1599 | 1600 | def get_ggl(self): 1601 | try_count = 5 1602 | while try_count > 0: 1603 | try: 1604 | headers = { 1605 | 'Host': 'guoyuan.meituan.com', 1606 | 'Connection': 'keep-alive', 1607 | 'Content-Length': '34', 1608 | 'Accept': 'application/json, text/plain, */*', 1609 | 'x-requested-with': 'XMLHttpRequest', 1610 | 'acToken': self.gglactoken, 1611 | 'mtoken': self.ck, 1612 | 'User-Agent': self.ua, 1613 | 'Origin': 'https://guoyuan.meituan.com', 1614 | 'Sec-Fetch-Site': 'same-origin', 1615 | 'Sec-Fetch-Mode': 'cors', 1616 | 'Sec-Fetch-Dest': 'empty', 1617 | 'Accept-Encoding': 'gzip, deflate', 1618 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 1619 | 'Cookie': f'token={self.ck}' 1620 | } 1621 | sjc = int(time.time() * 1000.0000001) 1622 | params = { 1623 | 'yodaReady': 'h5', 1624 | 'csecplatform': '4', 1625 | 'csecversion': '2.3.1', 1626 | # 'mtgsig': get_xsmtg(), 1627 | } 1628 | data = { 1629 | 'taskId': self.gglid, 1630 | 'scratchSource': 1 1631 | } 1632 | r = requests.post( 1633 | 'https://guoyuan.meituan.com/scratch/mgcUser/finishTask', 1634 | params=params, 1635 | headers=headers, 1636 | json=data, 1637 | ) 1638 | codes = r.json().get('code', None) 1639 | if isprint: 1640 | print(f'🆔账号{self.num}-{self.name}({self.usid}) {self.gglid} 领取刮刮乐任务 {r.json()}') 1641 | if codes == 0 or codes == 1101: 1642 | time.sleep(random.randint(1, 3)) 1643 | return True 1644 | else: 1645 | if isprint: 1646 | self.endmsg += f'🆔账号{self.num}-{self.name} 领取刮刮乐任务异常:还有{try_count - 1}次重试机会\n' 1647 | try_count -= 1 1648 | time.sleep(random.randint(3, 8)) 1649 | continue 1650 | except: 1651 | if isprint: 1652 | self.endmsg += f'🆔账号{self.num}-{self.name} 领取刮刮乐任务异常:还有{try_count - 1}次重试机会\n' 1653 | try_count -= 1 1654 | time.sleep(random.randint(3, 8)) 1655 | continue 1656 | 1657 | def post_ggl(self): 1658 | try_count = 5 1659 | while try_count > 0: 1660 | try: 1661 | headers = { 1662 | 'Host': 'guoyuan.meituan.com', 1663 | 'Connection': 'keep-alive', 1664 | 'Content-Length': '34', 1665 | 'Accept': 'application/json, text/plain, */*', 1666 | 'x-requested-with': 'XMLHttpRequest', 1667 | 'acToken': self.gglactoken, 1668 | 'mtoken': self.ck, 1669 | 'User-Agent': self.ua, 1670 | 'Content-Type': 'application/json;charset=UTF-8', 1671 | 'Origin': 'https://guoyuan.meituan.com', 1672 | 'Sec-Fetch-Site': 'same-origin', 1673 | 'Sec-Fetch-Mode': 'cors', 1674 | 'Sec-Fetch-Dest': 'empty', 1675 | 'Accept-Encoding': 'gzip, deflate', 1676 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 1677 | 'Cookie': f'token={self.ck}' 1678 | } 1679 | sjc = int(time.time() * 1000.0000001) 1680 | params = { 1681 | 'yodaReady': 'h5', 1682 | 'csecplatform': '4', 1683 | 'csecversion': '2.3.1', 1684 | # 'mtgsig': get_xsmtg(), 1685 | } 1686 | data = { 1687 | 'taskId': self.gglid, 1688 | 'scratchSource': 1 1689 | } 1690 | r = requests.post( 1691 | 'https://guoyuan.meituan.com/scratch/mgcUser/receiveTaskReward', 1692 | params=params, 1693 | headers=headers, 1694 | json=data, 1695 | ) 1696 | codes = r.json().get('code', None) 1697 | restCard = r.json().get('data', None).get('restCard', None) 1698 | if isprint: 1699 | print( 1700 | f'🆔账号{self.num}-{self.name}({self.usid}) {self.gglid} 完成刮刮乐任务,次数{restCard}。{r.json()}') 1701 | if codes == 0: 1702 | time.sleep(random.randint(1, 3)) 1703 | return True 1704 | else: 1705 | if isprint: 1706 | self.endmsg += f'🆔账号{self.num}-{self.name} 完成刮刮乐任务异常:还有{try_count - 1}次重试机会\n' 1707 | try_count -= 1 1708 | time.sleep(random.randint(3, 8)) 1709 | continue 1710 | 1711 | except: 1712 | if isprint: 1713 | self.endmsg += f'🆔账号{self.num}-{self.name} 完成刮刮乐任务异常:还有{try_count - 1}次重试机会\n' 1714 | try_count -= 1 1715 | time.sleep(random.randint(3, 8)) 1716 | continue 1717 | 1718 | def get_gglcard(self): 1719 | try_count = 5 1720 | while try_count > 0: 1721 | try: 1722 | headers = { 1723 | 'Host': 'guoyuan.meituan.com', 1724 | 'Connection': 'keep-alive', 1725 | 'Content-Length': '19', 1726 | 'Accept': 'application/json, text/plain, */*', 1727 | 'x-requested-with': 'XMLHttpRequest', 1728 | 'acToken': self.gglactoken, 1729 | 'mtoken': self.ck, 1730 | 'User-Agent': self.ua, 1731 | 'Content-Type': 'application/json;charset=UTF-8', 1732 | 'Origin': 'https://guoyuan.meituan.com', 1733 | 'Sec-Fetch-Site': 'same-origin', 1734 | 'Sec-Fetch-Mode': 'cors', 1735 | 'Sec-Fetch-Dest': 'empty', 1736 | 'Accept-Encoding': 'gzip, deflate', 1737 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 1738 | 'Cookie': f'token={self.ck}' 1739 | } 1740 | sjc = int(time.time() * 1000.0000001) 1741 | params = { 1742 | 'yodaReady': 'h5', 1743 | 'csecplatform': '4', 1744 | 'csecversion': '2.3.1', 1745 | # 'mtgsig': get_xsmtg(), 1746 | } 1747 | data = { 1748 | 'scratchSource': 1 1749 | } 1750 | r = requests.post( 1751 | 'https://guoyuan.meituan.com/scratch/mgcUser/useCard', 1752 | params=params, 1753 | headers=headers, 1754 | json=data, 1755 | ) 1756 | codes = r.json()['code'] 1757 | if '没有刮刮卡' in r.text: 1758 | return False 1759 | elif '正在刮的卡' in r.text: 1760 | return False 1761 | elif codes == 0: 1762 | self.cardId = r.json()['data']['scratchInProgress']['cardId'] 1763 | if isprint: 1764 | print(f'🆔账号{self.num}-{self.name} 获取刮刮乐id成功: {self.cardId}') 1765 | time.sleep(random.randint(1, 3)) 1766 | return True 1767 | else: 1768 | if isprint: 1769 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取刮刮乐id异常:还有{try_count - 1}次重试机会\n' 1770 | try_count -= 1 1771 | time.sleep(random.randint(3, 8)) 1772 | continue 1773 | except Exception as e: 1774 | print(e) 1775 | if isprint: 1776 | self.endmsg += f'🆔账号{self.num}-{self.name} 获取刮刮乐id异常:还有{try_count - 1}次重试机会\n' 1777 | try_count -= 1 1778 | time.sleep(random.randint(3, 8)) 1779 | continue 1780 | 1781 | def gk_ggl(self): 1782 | try_count = 5 1783 | while try_count > 0: 1784 | try: 1785 | headers = { 1786 | 'Host': 'guoyuan.meituan.com', 1787 | 'Connection': 'keep-alive', 1788 | 'Content-Length': '87', 1789 | 'Accept': 'application/json, text/plain, */*', 1790 | 'x-requested-with': 'XMLHttpRequest', 1791 | 'acToken': self.gglactoken, 1792 | 'mtoken': self.ck, 1793 | 'User-Agent': self.ua, 1794 | 'Content-Type': 'application/json;charset=UTF-8', 1795 | 'Origin': 'https://guoyuan.meituan.com', 1796 | 'Sec-Fetch-Site': 'same-origin', 1797 | 'Sec-Fetch-Mode': 'cors', 1798 | 'Sec-Fetch-Dest': 'empty', 1799 | 'Accept-Encoding': 'gzip, deflate', 1800 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', 1801 | 'Cookie': f'token={self.ck}' 1802 | } 1803 | params = { 1804 | 'yodaReady': 'h5', 1805 | 'csecplatform': '4', 1806 | 'csecversion': '2.3.1', 1807 | # 'mtgsig': get_xsmtg(), 1808 | } 1809 | data = { 1810 | 'cardId': self.cardId, 1811 | 'scratchedUnits': [1, 1, 1, 1, 1, 1, 1, 1, 1], 1812 | 'scratchSource': 1 1813 | } 1814 | r = requests.post( 1815 | 'https://guoyuan.meituan.com/scratch/mgcUser/progress', 1816 | params=params, 1817 | headers=headers, 1818 | json=data, 1819 | ) 1820 | codes = r.json().get('code', None) 1821 | if codes == 0: 1822 | prizeList = r.json()['data']['prizeList'] 1823 | for i in prizeList: 1824 | if isprint: 1825 | print(f'🆔账号{self.num}-{self.name} 刮刮乐获得{i["prizeName"]}') 1826 | time.sleep(random.randint(1, 3)) 1827 | return True 1828 | else: 1829 | if isprint: 1830 | self.endmsg += f'🆔账号{self.num}-{self.name} 刮刮乐刮卡异常:还有{try_count - 1}次重试机会\n' 1831 | try_count -= 1 1832 | time.sleep(random.randint(3, 8)) 1833 | continue 1834 | except: 1835 | if isprint: 1836 | self.endmsg += f'🆔账号{self.num}-{self.name} 刮刮乐刮卡异常:还有{try_count - 1}次重试机会\n' 1837 | try_count -= 1 1838 | time.sleep(random.randint(3, 8)) 1839 | continue 1840 | 1841 | def run_ggl(self): 1842 | if self.get_gglactoken(): 1843 | if self.get_ggllist(): 1844 | for i in self.ggl_list: 1845 | zt = i['status'] 1846 | self.gglid = i['id'] 1847 | viewTitle = i['viewTitle'] 1848 | dailyFinishTimes = i['dailyFinishTimes'] 1849 | maxLimit = i['maxLimit'] 1850 | if dailyFinishTimes < maxLimit and '下单' not in viewTitle and '美团首页' not in viewTitle and zt == 2: 1851 | if isprint: 1852 | print( 1853 | f'🆔账号{self.num}-{self.name}({self.usid}) {self.gglid}: 状态:{zt} {viewTitle}({dailyFinishTimes}/{maxLimit}) 未完成') 1854 | for i in range(maxLimit - dailyFinishTimes): 1855 | if self.get_ggl(): 1856 | self.post_ggl() 1857 | elif dailyFinishTimes <= maxLimit and '下单' not in viewTitle and '美团首页' not in viewTitle and zt == 3: 1858 | if isprint: 1859 | print( 1860 | f'🆔账号{self.num}-{self.name}({self.usid}) {self.gglid}: 状态:{zt} {viewTitle}({dailyFinishTimes}/{maxLimit}) 未领取') 1861 | self.post_ggl() 1862 | else: 1863 | if isprint: 1864 | print( 1865 | f'🆔账号{self.num}-{self.name}({self.usid}) {self.gglid}: 状态:{zt} {viewTitle}({dailyFinishTimes}/{maxLimit}) 已完成或者跳过不做') 1866 | while True: 1867 | if self.get_gglcard(): 1868 | self.gk_ggl() 1869 | continue 1870 | else: 1871 | break 1872 | 1873 | def get_new_gameid(self): 1874 | if self.get_ids(): 1875 | self.ids = [] 1876 | zt_3 = [] 1877 | for i in self.data_list: 1878 | if i['status'] == 2 and i['id'] not in self.noids: 1879 | self.ids.append(i['id']) 1880 | if i['status'] == 3 and i['id'] not in self.noids: 1881 | self.ids.append(i['id']) 1882 | zt_3.append(i['id']) 1883 | else: 1884 | pass 1885 | if isprint: 1886 | print(f'🆔账号{self.num}-{self.name}({self.usid}) 获取到{len(self.ids)}个游戏任务!\n{self.ids}') 1887 | if self.ids != [] and len(zt_3) < max_zt3: 1888 | return True 1889 | elif not self.ids: 1890 | return True 1891 | else: 1892 | self.startmsg += f'🆔账号{self.num}-{self.name}({self.usid}) ⛔️跑不动,{len(zt_3)}个任务未提交成功!尝试修改max_zt3参数为100!!!\n' 1893 | return False 1894 | else: 1895 | return False 1896 | 1897 | def run_game(self): 1898 | random.shuffle(self.data_list) 1899 | i_num = 0 1900 | for i in self.data_list: 1901 | zong = len(self.ids) 1902 | self.id = i['id'] 1903 | zt = i['status'] 1904 | if self.id in self.noids: 1905 | pass 1906 | else: 1907 | if zt == 2 and self.id in [386, 510, 511, 332]: 1908 | i_num += 1 1909 | a = 0 1910 | while a < 5: 1911 | a += 1 1912 | if isprint: 1913 | print( 1914 | f'\n🆔账号{self.num}-{self.name}({self.usid}) 任务{i_num}/{zong} id: {self.id} 状态: {zt} 第{a}次') 1915 | if self.get_game(): 1916 | self.post_id() 1917 | continue 1918 | else: 1919 | break 1920 | continue 1921 | elif zt == 3 and self.id in [386, 510, 511, 332]: 1922 | i_num += 1 1923 | a = 1 1924 | if isprint: 1925 | print( 1926 | f'\n🆔账号{self.num}-{self.name}({self.usid}) 任务{i_num}/{zong} id: {self.id} 状态: {zt} 第{a}次') 1927 | self.post_id() 1928 | while a < 5: 1929 | a += 1 1930 | if isprint: 1931 | print( 1932 | f'\n🆔账号{self.num}-{self.name}({self.usid}) 任务{i_num}/{zong} id: {self.id} 状态: {zt} 第{a}次') 1933 | if self.get_game(): 1934 | self.post_id() 1935 | continue 1936 | else: 1937 | break 1938 | continue 1939 | elif zt == 2: 1940 | i_num += 1 1941 | if isprint: 1942 | print( 1943 | f'\n🆔账号{self.num}-{self.name}({self.usid}) 任务{i_num}/{zong} id: {self.id} 状态: {zt}') 1944 | if self.get_game(): 1945 | self.post_id() 1946 | continue 1947 | elif zt == 3: 1948 | i_num += 1 1949 | if isprint: 1950 | print(f'\n🆔账号{self.num}-{self.name}({self.usid}) 任务{i_num}/{zong} id: {self.id} 状态: {zt}') 1951 | self.post_id() 1952 | continue 1953 | else: 1954 | continue 1955 | 1956 | def main(self): 1957 | if self.login(): 1958 | if self.act(): 1959 | if self.startcxtb(): 1960 | if self.coin_login(): 1961 | self.runq_jrtb() 1962 | if self.coins > jrtb_nums: 1963 | self.startmsg += f'🚀今日团币已经达到{jrtb_nums}不再运行!\n' 1964 | self.endmsg += f'🆔账号{self.num}-{self.name}({self.usid}) 🎁今天已经跑过啦\n' 1965 | if self.endcxtb(): 1966 | if self.tj_bchd(): 1967 | if self.uid is not None: 1968 | self.wxpusher() 1969 | ts = {'序号': self.num, '用户': self.name, '今日团币': self.coins, 1970 | '总共团币': f'{int(self.wcxtb)}({int(self.wcxtb) / 1000}元)'} 1971 | ts_all.append(ts) 1972 | print(f'{self.startmsg}{self.endmsg}') 1973 | else: 1974 | ts = {'序号': self.num, '用户': self.name, '今日团币': self.coins, 1975 | '总共团币': f'{int(self.wcxtb)}({int(self.wcxtb) / 1000}元)'} 1976 | ts_all.append(ts) 1977 | print(f'{self.startmsg}{self.endmsg}') 1978 | else: 1979 | isgame = self.get_new_gameid() 1980 | if isgame and self.ids != []: 1981 | # if 717 not in self.ids: 1982 | # self.game_gift() 1983 | self.startmsg += f'✅游戏中心获取任务成功!🚀即将运行所有任务\n' 1984 | print(self.startmsg) 1985 | a = 0 1986 | while True: 1987 | a += 1 1988 | if a > max_gamexh: 1989 | break 1990 | self.run_game() 1991 | isgame = self.get_new_gameid() 1992 | if isgame and len(self.ids) != 0: 1993 | continue 1994 | elif isgame and len(self.ids) == 0: 1995 | break 1996 | else: 1997 | self.endmsg += f'⛔️第{a}循环发现问题,停止游戏中心任务运行!' 1998 | break 1999 | elif isgame and self.ids == []: 2000 | self.startmsg += f'✅游戏中心已经全部完成!🚀即将运行小说和团币中心任务\n' 2001 | print(self.startmsg) 2002 | else: 2003 | if nzidrun: 2004 | self.ids = [15610, 15224, 15293, 15604, 15813, 15177, 15601, 15605, 15326, 15837, 2005 | 15458, 2006 | 15457, 2007 | 15603, 15606, 15324, 15810, 15607, 15618, 16656, 15608, 16498, 15169, 2008 | 15609, 2009 | 15302, 2010 | 15171, 15172, 15282, 15287, 15173, 323, 330, 507, 509, 672, 768] 2011 | self.startmsg += f'⛔️游戏中心获取任务失败,使用内置id!🚀即将运行游戏中心任务和团币中心任务\n' 2012 | print(self.startmsg) 2013 | self.run_game2() 2014 | else: 2015 | self.startmsg += f'⛔️游戏中心获取任务失败,未开启内置id运行!🚀即将运行团币中心任务\n' 2016 | print(self.startmsg) 2017 | if self.get_xslist(): 2018 | self.run_xsrw() 2019 | if self.coin_login(): 2020 | self.run_tbrw() 2021 | if run_ggl: 2022 | self.run_ggl() 2023 | self.endmsg += f'🆔账号{self.num}-{self.name}({self.usid}) 🎉运行完成\n' 2024 | if self.endcxtb(): 2025 | if self.tj_bchd(): 2026 | if self.uid is not None: 2027 | self.wxpusher() 2028 | ts = {'序号': self.num, '用户': self.name, '今日团币': self.coins, 2029 | '总共团币': f'{int(self.wcxtb)}({int(self.wcxtb) / 1000}元)'} 2030 | ts_all.append(ts) 2031 | print(self.endmsg) 2032 | else: 2033 | ts = {'序号': self.num, '用户': self.name, '今日团币': self.coins, 2034 | '总共团币': f'{int(self.wcxtb)}({int(self.wcxtb) / 1000}元)'} 2035 | ts_all.append(ts) 2036 | print(self.endmsg) 2037 | else: 2038 | self.endmsg += '🆔账号{self.num}-{self.name}({self.usid})⛔️获取今日团币失败\n' 2039 | print(self.endmsg) 2040 | else: 2041 | self.endmsg += '🆔账号{self.num}-{self.name}({self.usid})⛔️获取运行后团币失败\n' 2042 | print(self.endmsg) 2043 | else: 2044 | self.endmsg += '🆔账号{self.num}-{self.name}({self.usid})⛔️获取qdtoken失败\n' 2045 | print(self.endmsg) 2046 | else: 2047 | self.startmsg += '⛔️获取运行前团币失败\n' 2048 | print(self.startmsg) 2049 | else: 2050 | self.startmsg += '⛔️获取act失败\n' 2051 | print(self.startmsg) 2052 | else: 2053 | self.startmsg += '⛔️️登录失败️\n' 2054 | print(self.startmsg) 2055 | 2056 | def get_xslist(self): 2057 | self.xs_headers = { 2058 | # "retrofit_exec_time": self.timestamp_milliseconds(), 2059 | "Referer": "https://msc.meituan.com/73a62054aadc4526/6227/service", 2060 | "User-Agent": self.ua, 2061 | "M-SHARK-TRACEID": "101000000000000038E9FFD887F741C5BCE0A6A3F9D849C2A16592906xdrw3528218cdd781702178856961163393", 2062 | "Accept-Encoding": "gzip", 2063 | "clientVersion": "1.2.0", 2064 | "uuid": self.uuid, 2065 | "platform": "4", 2066 | "yodaVersion": "1.18.0.179", 2067 | "appVersion": "12.19.209", 2068 | "token": self.ck, 2069 | "clientType": "android", 2070 | "yodaReady": "native", 2071 | "appType": "group", 2072 | "novelScene": "0199", 2073 | "adBookId": "2611385", 2074 | "Content-Type": "application/json", 2075 | "Host": "web.meituan.com", 2076 | "Connection": "Keep-Alive", 2077 | } 2078 | r = requests.get('https://web.meituan.com/novel/marketing/task/listV2?clientAppVersion=6', 2079 | headers=self.xs_headers) 2080 | # r = requests.get('https://web.meituan.com/novel/marketing/task/listV2', 2081 | # headers=self.xs_headers) 2082 | if '操作成功' in r.text: 2083 | if isprint: 2084 | print( 2085 | f'🆔账号{self.num}-{self.name}({self.usid}) 获取小说任务成功!') 2086 | self.xslist = r.json().get('data', None) 2087 | time.sleep(random.randint(1, 3)) 2088 | return True 2089 | else: 2090 | if isprint: 2091 | print( 2092 | f'🆔账号{self.num}-{self.name}({self.usid}) ⛔️获取小说任务失败!') 2093 | time.sleep(random.randint(1, 3)) 2094 | return False 2095 | 2096 | def get_xsid(self): 2097 | headers = { 2098 | # "retrofit_exec_time": self.timestamp_milliseconds(), 2099 | "Referer": "https://msc.meituan.com/73a62054aadc4526/6227/service", 2100 | "User-Agent": self.ua, 2101 | "M-SHARK-TRACEID": "101000000000000038E9FFD887F741C5BCE0A6A3F9D849C2A16592906xdrw3528218cdd781702178856961163393", 2102 | "Accept-Encoding": "gzip", 2103 | "clientVersion": "1.2.0", 2104 | "uuid": self.uuid, 2105 | "platform": "4", 2106 | "yodaVersion": "1.18.0.179", 2107 | "appVersion": "12.19.204", 2108 | "token": self.ck, 2109 | "clientType": "android", 2110 | "yodaReady": "native", 2111 | "appType": "group", 2112 | "novelScene": "0199", 2113 | "adBookId": "2611385", 2114 | "Content-Type": "application/json", 2115 | "Host": "web.meituan.com", 2116 | # "mtgsig": "{'a1': '1.1', 'a2': 1705210566109, 'a3': '1705207770058CCSCKCCe67dcc3e61b3db1bf3f9e3b1c7aaaa883129', 'a5': 'p/q6y/VVJya//sJFOQVZjbVFgnuAD+P4', 'a6': 'hs1.4cc8P/oEcPnEVSLCbPATiLpS/SEx2PtOn9gl+fy5ugnXN+jI26oGzQDexAB7AKBL9MLQa+3hdYp5R8FyGDs76Fv/+b3RfNGzp7WOMiJ5fH+ELoJEuxPK7r5F/RZ6ZuFZIYoBAe2hzCchU/UuxEUHIpHgO6MyqfhNJScPSO8BBhZRQXRwFJ+SqvkC2oiYtSpTCS+KojN+3plAj5fjDq8yPGj8pcC2Vv2m6Ri0Ujwa3VxhF1b5vS7KTnhmLX6kwDn8BF2OHCXcEd6j33djG3D8PoYgU/TwPq1rHNKkbX0GM3TrYc3edu3k4a0S0jbyQLr+4bhZ0SkiV5Ie03wu/lMksW7ECNwnxNJtJPIs7pJprLrc=', 'x0': 4, 'd1': '693c48f536c46dd0da9991745ff82524'}", 2117 | "Connection": "Keep-Alive", 2118 | } 2119 | data = { 2120 | 'jobId': self.jobId, 2121 | 'property': self.property, 2122 | 'fingerprint': self.zw, 2123 | } 2124 | # r = requests.post('https://web.meituan.com/novel/marketing/task', headers=headers, json=data) 2125 | data = json.dumps(data) 2126 | r = self.Getmtgsig_data('https://web.meituan.com/novel/marketing/task', headers, data) 2127 | 2128 | if '操作成功' in r.text: 2129 | self.xsid = r.json()['data']['taskId'] 2130 | if isprint: 2131 | print( 2132 | f'🆔账号{self.num}-{self.name}({self.usid}) 获取小说id✅成功{self.jobId}({self.xsid}) {r.json()}') 2133 | time.sleep(random.randint(1, 3)) 2134 | return True 2135 | else: 2136 | if isprint: 2137 | print( 2138 | f'🆔账号{self.num}-{self.name}({self.usid}) ⛔️获取小说id失败{self.jobId} {r.json()}') 2139 | time.sleep(random.randint(1, 3)) 2140 | return False 2141 | 2142 | def get_xsrw(self): 2143 | self.xs_headers = { 2144 | # "retrofit_exec_time": self.timestamp_milliseconds(), 2145 | "Referer": "https://msc.meituan.com/73a62054aadc4526/6227/service", 2146 | "User-Agent": self.ua, 2147 | "M-SHARK-TRACEID": "101000000000000038E9FFD887F741C5BCE0A6A3F9D849C2A16592906xdrw3528218cdd781702178856961163393", 2148 | "Accept-Encoding": "gzip", 2149 | "clientVersion": "1.2.0", 2150 | "uuid": self.uuid, 2151 | "platform": "4", 2152 | "yodaVersion": "1.18.0.179", 2153 | "appVersion": "12.19.209", 2154 | "token": self.ck, 2155 | "clientType": "android", 2156 | "yodaReady": "native", 2157 | "appType": "group", 2158 | "novelScene": "0199", 2159 | "adBookId": "2611385", 2160 | "Content-Type": "application/json", 2161 | "Host": "web.meituan.com", 2162 | "Connection": "Keep-Alive", 2163 | } 2164 | if self.title == '听书赚美团币': 2165 | url = 'https://web.meituan.com/novel/marketing/task/audio/process' 2166 | data = { 2167 | 'process': self.condition, 2168 | 'fingerprint': self.zw, 2169 | 'audioPartnerType': 1, 2170 | 'taskProperty': 4 2171 | } 2172 | else: 2173 | url = 'https://web.meituan.com/novel/marketing/task/process' 2174 | data = { 2175 | 'taskId': f"{self.xsid}", 2176 | 'process': self.condition, 2177 | 'fingerprint': self.zw, 2178 | } 2179 | # r = requests.post('https://web.meituan.com/novel/marketing/task/process', headers=self.xs_headers, json=data) 2180 | 2181 | data = json.dumps(data) 2182 | r = self.Getmtgsig_data(url, self.xs_headers, data) 2183 | 2184 | if '操作成功' in r.text: 2185 | if isprint: 2186 | print( 2187 | f'🆔账号{self.num}-{self.name}({self.usid}) ✅领取{self.xsid}成功 {r.json()}') 2188 | time.sleep(random.randint(1, 3)) 2189 | return True 2190 | else: 2191 | if isprint: 2192 | print( 2193 | f'🆔账号{self.num}-{self.name}({self.usid}) ⛔️领取{self.xsid}失败 {r.json()}') 2194 | time.sleep(random.randint(1, 3)) 2195 | return False 2196 | 2197 | def post_xsrw(self): 2198 | data = { 2199 | 'taskId': f"{self.xsid}", 2200 | 'fingerprint': self.zw, 2201 | } 2202 | # r = requests.post('https://web.meituan.com/novel/marketing/task/coin', headers=self.xs_headers, json=data) 2203 | data = json.dumps(data) 2204 | r = self.Getmtgsig_data('https://web.meituan.com/novel/marketing/task/coin', self.xs_headers, data) 2205 | if '操作成功' in r.text: 2206 | if isprint: 2207 | print( 2208 | f'🆔账号{self.num}-{self.name}({self.usid}) ✅完成{self.xsid}成功 {r.json()}') 2209 | time.sleep(random.randint(1, 3)) 2210 | return True 2211 | else: 2212 | if isprint: 2213 | print( 2214 | f'🆔账号{self.num}-{self.name}({self.usid}) ⛔️完成{self.xsid}失败 {r.json()}') 2215 | time.sleep(random.randint(1, 3)) 2216 | return False 2217 | 2218 | def run_xsrw(self): 2219 | for data in self.xslist: 2220 | zt = data['status'] 2221 | self.title = data['title'] 2222 | self.xsid = data.get('taskId', None) 2223 | self.jobId = data['jobId'] 2224 | self.property = data['property'] 2225 | self.condition = data['award']['steps'][-1]['condition'] 2226 | if isprint: 2227 | print( 2228 | f"{self.title} 状态: {zt} taskid:{self.xsid} jobId: {self.jobId} property: {self.property} condition: {self.condition}") 2229 | if zt == 1 or zt == 0: 2230 | if self.get_xsid(): 2231 | time.sleep(random.randint(10, 60)) 2232 | if self.get_xsrw(): 2233 | time.sleep(random.randint(3, 8)) 2234 | self.post_xsrw() 2235 | time.sleep(random.randint(3, 8)) 2236 | pass 2237 | elif zt == 2: 2238 | if self.get_xsid(): 2239 | time.sleep(random.randint(10, 60)) 2240 | self.post_xsrw() 2241 | time.sleep(random.randint(3, 8)) 2242 | else: 2243 | pass 2244 | 2245 | 2246 | if __name__ == '__main__': 2247 | requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) 2248 | print = partial(print, flush=True) 2249 | msg = """ 2250 | 🔔当前版本V4.19自备接口版 2251 | """ 2252 | print(msg) 2253 | 2254 | token = os.environ.get(blname) 2255 | 2256 | if token is None: 2257 | print(f'⛔️未获取到ck变量:请检查变量是否填写') 2258 | exit(0) 2259 | if zdyfg in token: 2260 | tokens = token.split(zdyfg) 2261 | else: 2262 | tokens = [token] 2263 | 2264 | print(f'✅获取到{len(tokens)}个账号') 2265 | 2266 | bf = os.environ.get("bd_xtbbf") 2267 | if bf is None: 2268 | print(f'⛔️为设置并发变量,默认1') 2269 | bf = 1 2270 | else: 2271 | bf = int(bf) 2272 | print(f'✅设置最大并发数: {bf}') 2273 | 2274 | if isprint: 2275 | print(f'✅开启详细日志') 2276 | else: 2277 | print(f'⛔️未开启详细日志') 2278 | 2279 | if isdl: 2280 | if proxy_api_url != '': 2281 | print(f'✅开启代理api运行') 2282 | start_dlapi() 2283 | elif proxy_url != '': 2284 | print(f'✅开启代理池运行') 2285 | else: 2286 | print(f'⛔️未填入代理') 2287 | exit(0) 2288 | else: 2289 | print(f'⛔️未开启代理运行') 2290 | 2291 | ts_all = [] 2292 | with concurrent.futures.ThreadPoolExecutor(max_workers=int(bf)) as executor: 2293 | print(f'======================================') 2294 | for num in range(len(tokens)): 2295 | runzh = num + 1 2296 | if len(tokens[num].split("#")) == 2 and "UID" in tokens[num]: 2297 | print(f'🆔账号{runzh} 好像没加uuid,请添加后再运行!\n') 2298 | elif len(tokens[num].split("#")) == 2 and "UID" not in tokens[num]: 2299 | run = Mttb(runzh, tokens[num]) 2300 | executor.submit(run.main) 2301 | elif len(tokens[num].split("#")) == 3: 2302 | run = Mttb(runzh, tokens[num]) 2303 | executor.submit(run.main) 2304 | elif len(tokens[num].split("#")) == 1: 2305 | print(f'🆔账号{runzh} 好像没加uuid,请添加后再运行!\n') 2306 | time.sleep(random.randint(2, 5)) 2307 | 2308 | if wxpusher_alluid == '': 2309 | stop_event.set() 2310 | pass 2311 | else: 2312 | stop_event.set() 2313 | ts_qb(ts_all) 2314 | -------------------------------------------------------------------------------- /bd_yl.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | time:2023.10.31 4 | cron: 1 1 1 1 1 5 | new Env('安装依赖(运行脚本前运行)'); 6 | 一键安装库里面脚本需要的依赖! 7 | 8 | """ 9 | 10 | import importlib.util 11 | import os 12 | 13 | yl = ['cryptograph', 'user_agent', ] 14 | for i in yl: 15 | spec = importlib.util.find_spec(i) 16 | if spec is None: 17 | os.system("pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple") 18 | os.system(f"pip install -i https://pypi.tuna.tsinghua.edu.cn/simple {i}") 19 | print(f"{i}安装完成") 20 | else: 21 | print(f"{i}已经安装") 22 | --------------------------------------------------------------------------------