Files
qinglong/脚本库/web版/账密/apply_link.split'id='-1}/2026-03-27_3dmgame_2262c9f7.py
2026-05-23 18:48:48 +00:00

353 lines
17 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Source: https://github.com/lksky8/sign-ql/blob/main/3dmgame.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/3dmgame.py
# Repo: lksky8/sign-ql
# Path: 3dmgame.py
# UploadedAt: 2026-03-27T20:17:30Z
# SHA256: 2262c9f7c2d40c8ef9822325fadd2e8ed3c43ba0f609c072a27c49b02edc2eaa
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
作者https://github.com/lksky8/sign-ql/
日期2026-3-28
网站3dmgame论坛签到
功能:签到、抽奖,金币可换现金买游戏
食用方法登录论坛后浏览器F12打开抓包https://bbs.3dmgame.com/home.php?mod=spacecp&ac=credit&showcredit=1抓这个url请求头的cookie包
变量bbs3dmck='cookie' 多个账号用换行分割
定时一天三次
青龙需要安装lxml模块
cron: 0 9 */8 * * *
"""
import time
import requests
from lxml import etree
import re
import random
import os
send_msg = ''
one_msg = ''
def Log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'{cont}\n'
send_msg += f'{cont}\n'
# 发送通知消息
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
print('发送通知消息失败!' + str(e))
class ThreeDMGame:
def __init__(self, cookies):
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://bbs.3dmgame.com',
'Pragma': 'no-cache',
'Sec-Fetch-Dest': 'iframe',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36',
'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Google Chrome";v="146"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'Cookie': cookies,
}
self.session = requests.Session()
self.session.headers.update(headers)
def user_info(self):
try:
response = self.session.get('https://bbs.3dmgame.com/home.php?mod=spacecp&ac=credit&showcredit=1')
html = etree.HTML(response.text)
user_id = html.xpath('//*[@id="hd"]/div/div[1]/p/strong/a/text()')[0]
points = html.xpath('//*[@id="extcreditmenu"]/text()')[0]
gold = html.xpath('//*[@id="ct"]/div[1]/div/ul[2]/li[1]/text()')[0]
print(f'用户ID[{user_id}] {points} 金元:{gold}')
Log(f'\n用户ID[{user_id}] {points} 金元:{gold}')
except Exception as e:
print('3dmgame论坛用户信息获取失败', e)
Log(f'\n3dmgame论坛用户信息获取失败')
def task_view(self, t_id):
try:
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=view&id={t_id}')
html = etree.HTML(response.text)
task_name = html.xpath('//h1[contains(@class, "xs2") and contains(@class, "ptm") and contains(@class, "pbm")]/text()')[0].strip()
if 'do=apply' in response.text:
print(f'任务:《{task_name}》 可申请')
elif '后可以再次申请' in response.text:
print(f'任务:《{task_name}》 未到申请时间')
elif '您所在的用户组无法申请此任务' in response.text:
print(f'任务:《{task_name}》 您所在的用户组无法申请此任务')
elif 'static/image/task/reward.gif' in response.text:
print(f'任务:《{task_name}》 任务已完成,待领取奖励')
else:
print(f'任务:《{task_name}》 未知状态')
except Exception as e:
print(f'查看任务信息失败:{t_id} {e}')
def check_task(self):
try:
response = self.session.get('https://bbs.3dmgame.com/home.php?mod=task')
# print(response.text)
html = etree.HTML(response.text)
task_rows = html.xpath('//div[@class="ptm"]//table//tr')
# for row in task_rows:
# # 提取任务名称
# task_name = row.xpath('.//td[2]//h3/a/text()')[0] if row.xpath('.//td[2]//h3/a/text()') else ""
#
# # 提取任务描述
# description = row.xpath('.//td[2]/p/text()')[0] if row.xpath('.//td[2]/p/text()') else ""
#
# # 提取任务奖励
# reward = row.xpath('.//td[3]/text()')[0].strip() if row.xpath('.//td[3]/text()') else ""
#
# # 提取任务状态(可申请/不可申请)
# is_available = len(row.xpath('.//td[4]//img[@alt="apply"]')) > 0
#
# apply_link = row.xpath('.//td[4]/a[contains(@href, "do=apply")]/@href')[0] if row.xpath('.//td[4]/a[contains(@href, "do=apply")]/@href') else "无可用申请链接"
#
# print(f"任务名称: {task_name}")
# print(f"申请链接: {apply_link}")
# print(f"描述: {description}")
# print(f"奖励: {reward}")
# print(f"是否可申请: {'是' if is_available else '否'}")
# print("---")
task_list = {}
for row in task_rows:
task_name = row.xpath('.//td[2]//h3/a/text()')[0] if row.xpath('.//td[2]//h3/a/text()') else ""
description = row.xpath('.//td[2]/p/text()')[0] if row.xpath('.//td[2]/p/text()') else ""
reward = row.xpath('.//td[3]/text()')[0].strip() if row.xpath('.//td[3]/text()') else ""
apply_links = row.xpath('.//td[4]/a[contains(@href, "do=apply")]/@href')
# 只处理有可用申请链接的任务
if apply_links:
apply_link = apply_links[0]
print(f"任务名称: {task_name}")
print(f"描述: {description}")
print(f"奖励: {reward}")
# print(f"任务id: {apply_link.split('id=')[-1]}")
print("-" * 50)
task_list.update({task_name: apply_link.split('id=')[-1]})
if len(task_list) > 0:
print(f'获取到{len(task_list)}个可接任务')
for name, link_id in task_list.items():
print('*' * 30)
print(f'尝试领取任务:{name}')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=apply&id={link_id}')
if 'do=draw' in response.text:
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={link_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:{name} 直接完成')
else:
print(f'任务:{name} 失败' + response.text)
elif '申请此任务需要先完成另一个任务' in response.text:
html_message = etree.HTML(response.text)
qianzhi_task = html_message.xpath('//div[@id="messagetext"]//p[@class="alert_btnleft"]/a/@href')[0].split("id=")[-1]
print(f'任务:{name} 领取失败 | 原因是前置任务未完成跳转前置任务id{qianzhi_task}')
self.task_view(qianzhi_task)
elif '任务申请成功' in response.text:
print(f'任务:{name} 领取成功')
elif '不是进行中的任务' in response.text:
print(f'任务:{name} 无法直接完成')
else:
print(f'任务:{name} 领取失败')
print(response.text)
time.sleep(1)
print('-' * 50)
else:
print('没有可接任务')
# Log(f'\n没有可接任务')
print('-' * 50)
except Exception as e:
print(f'检查任务信息失败:{e}')
def check_task_doing(self):
try:
response = self.session.get('https://bbs.3dmgame.com/home.php?mod=task&item=doing')
# print(response.text)
html = etree.HTML(response.text)
task_rows = html.xpath('//div[@class="ptm"]//table//tr')
task_list = []
for row in task_rows:
# 提取任务名称
task_name = row.xpath('.//td[2]//h3/a/text()')[0] if row.xpath('.//td[2]//h3/a/text()') else ""
# 提取任务ID
task_id = row.xpath('.//td[2]//h3/a/@href')[0].split('id=')[-1] if row.xpath('.//td[2]//h3/a/@href') else ""
# 提取do=view链接任务详情链接
# view_link = row.xpath('.//td[2]//h3/a[contains(@href, "do=view")]/@href')[0] if row.xpath('.//td[2]//h3/a[contains(@href, "do=view")]/@href') else ""
# 提取领取链接(do=draw类型)
# draw_links = row.xpath('.//td[4]/p/a[contains(@href, "do=draw")]/@href')[0] if row.xpath('.//td[4]/p/a/@href') else ""
print(f"进行中的任务: 《{task_name}")
task_list.append({task_name: task_id})
print('-' * 30)
if len(task_list) > 0:
return task_list
else:
print('没有进行中的任务')
# Log(f'\n没有进行中的任务')
return []
except Exception as e:
print(f'检查任务进行中失败:{e}')
def do_task(self, tk_list):
print(f'获取到{len(tk_list)}个待完成任务')
for task_name, task_id in tk_list.items():
print(f'尝试完成任务:《{task_name}')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=view&id={task_id}')
if 'static/image/task/reward.gif' in response.text:
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={task_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:《{task_name}》 完成')
else:
print(f'任务:《{task_name}》 失败')
print(response.text)
elif '完成此任务所需条件' in response.text:
print(f'任务:《{task_name}》 无完成条件')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={task_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:《{task_name}》 完成')
else:
print(f'任务:《{task_name}》 失败')
print(response.text)
else:
print(f'任务:《{task_name}》 有完成条件')
tree = etree.HTML(response.text)
tables = tree.xpath("//table[@class='tfm']//td[@class='bbda']/a/@href")[0]
# print(tables)
reply_td = tree.xpath("//table[@class='tfm']//td[@class='bbda'][contains(., '')]/text()[normalize-space()]")[1]
reply_td = reply_td.replace(' ', '')
# print(reply_td)
reply_count = re.search(r'(\d+)次', reply_td).group(1) if re.search(r'(\d+)次', reply_td) else "未知"
if 'thread' in tables:
response = self.session.get(f'https://bbs.3dmgame.com/{tables}')
formhash = re.search(r'name="formhash" value="(\w+)"', response.text).group(1)
fid_match = re.search(r"fid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
tid_match = re.search(r"tid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
print('回复次数:' + reply_count)
if int(reply_count) > 5:
print('回复次数大于5次任务跳过')
else:
for _ in range(int(reply_count)):
for i in range(3):
result = self.reply(tid_match, fid_match, formhash)
if result:
break
time.sleep(10)
time.sleep(35)
print(f'已完成任务 《{task_name}》 回复指定文章要求')
else:
response = self.session.get(f'https://bbs.3dmgame.com/{tables}')
result = re.findall(r'mod=redirect&tid=(\d+)&goto', response.text)
if len(result) > 0:
response = self.session.get(f'https://bbs.3dmgame.com/thread-{random.choice(result)}-1-1.html')
formhash = re.search(r'name="formhash" value="(\w+)"', response.text).group(1)
fid_match = re.search(r"fid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
tid_match = re.search(r"tid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
for _ in range(int(reply_count)):
for i in range(3):
result = self.reply(tid_match, fid_match, formhash)
if result:
break
time.sleep(10)
time.sleep(35)
print(f'已完成任务 《{task_name}》 回复指定主题要求')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={task_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:《{task_name}》 完成')
elif '您已完成该任务的' in response.text:
html = etree.HTML(response.text)
b = html.xpath('//div[@id="messagetext"]/p/text()')[0]
print(f'任务:《{task_name}》 失败:' + b.strip())
elif '您还没有开始执行任务,赶快哦' in response.text:
print(f'任务:《{task_name}》 失败:因任务特殊跳过该任务')
elif '您还没有开始执行任务' in response.text:
print(f'任务:《{task_name}》 失败:因任务特殊跳过该任务')
else:
print(f'任务:《{task_name}》 失败')
print(response.text)
time.sleep(3)
def reply(self, tid, fid, formhash):
response = requests.get("https://www.mxnzp.com/api/jokes/list?page=1&app_id=vqohyieoq7qklmgp&app_secret=FCc9Uf0h1c0LNkqeLRolebStTGfds3Fx")
response_json = response.json()
if response_json['code'] == 1 :
message = response_json['data']['list'][0]['content']
else:
message = '我是新玩家,搞不懂' + random.choice(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'])
data = {
'file': '',
'message': message,
'posttime': str(int(time.time())),
'formhash': formhash,
'usesig': '1',
'subject': ' ',
}
response = self.session.post(f'https://bbs.3dmgame.com/forum.php?mod=post&action=reply&fid={fid}&tid={tid}&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1', data=data)
if '回复发布成功' in response.text:
print('回帖成功,等待35秒后回复下个帖子')
return True
else:
print('回复失败,未知原因')
return False
def main(self):
self.user_info()
print('-' * 50)
print('开始做论坛任务-->>>>>>>>')
self.check_task()
task_list = self.check_task_doing()
if task_list:
for task in task_list:
self.do_task(task)
print('等待30秒进行下一个账号')
self.session.close()
print('*' * 50)
time.sleep(30)
Log('-' * 30)
if __name__ == '__main__':
try:
if 'bbs3dmck' in os.environ:
bbs3dmck = re.split("@|&", os.environ.get("bbs3dmck"))
print(f'查找到{len(bbs3dmck)}个账号\n')
else:
bbs3dmck = None
print('无bbs3dmck变量')
Log(f'\n未填入bbs3dmck变量')
if bbs3dmck:
z = 1
for ck in bbs3dmck:
print(f'登录第{z}个账号')
threeDM = ThreeDMGame(ck)
threeDM.main()
z+= 1
except Exception as e:
print(e)
try:
send_notification_message(title='3dmgame论坛签到') # 发送通知
except Exception as e:
print(e)