This commit is contained in:
Ytong
2025-10-04 04:49:27 +08:00
parent 7ab5c22d9d
commit 16270eb6b9

807
猫猫阅读4.0最新版.py Normal file
View File

@@ -0,0 +1,807 @@
# 当前脚本来自于http://script.345yun.cn脚本库下载
#
#
# 阅读入口https://file.52bin.cn/img/ID9/202509/68c63a96f101e.jpeg 微信扫码打开
# 配置说明:
# 1. 环境变量 mmyd_ck: 配置cookie账号信息bbus值支持多账号分隔符换行符、@、& 例如eyxxxxxxxxx 不要前面的bbus=
# 2. 环境变量 mmyd_ua: 配置UA信息 https://useragent.todaynav.com/ 微信打开此网站即可 请使用你的微信的User-Agent
# 3. 环境变量 mmyd_url: 检测文章提交接口的URL可选如http://192.168.124.201:9900/check_read请使用自己的这个只是例子
# 4. 环境变量 mmyd_token: PushPlus推送加token可选
# 5. 环境变量 mmyd_tx: PushPlus推送加token可选
# 使用说明:
# - 首账号采用固定邀请码请wx点击阅读入口。
# - 支持多账号批量运行自动刷新Cookie
# - 自动检测文章并推送通知需配置mmyd_token
# - 自动提现功能满足5000金币自动提现
# - 如果配置了mmyd_url会先尝试自动过检失败则推送通知
#
# 本脚本仅供学习交流请在下载后的24小时内完全删除
# 请勿用于商业用途或非法目的,否则后果自负
# 固定注释内容
fixed_comments = """# 猫猫阅读脚本 4.0
#
# 阅读入口https://file.52bin.cn/img/ID9/202509/68c63a96f101e.jpeg 微信扫码打开
#
# 配置说明:
# 1. 环境变量 mmyd_ck: 配置cookie账号信息bbus值支持多账号分隔符换行符、@、&
# 2. 环境变量 mmyd_ua: 配置UA信息 https://useragent.todaynav.com/ 微信打开此网站即可 请使用你的微信的User-Agent
# 3. 环境变量 mmyd_url: 检测文章提交接口的URL可选如http://192.168.124.201:9900/check_read
# 4. 环境变量 mmyd_token: PushPlus推送加token可选
#
# 使用说明:
# - 首账号采用固定邀请码请wx点击阅读入口。
# - 支持多账号批量运行自动刷新Cookie
# - 自动检测文章并推送通知需配置mmyd_token
# - 自动提现功能满足5000金币自动提现
# - 如果配置了mmyd_url会先尝试自动过检失败则推送通知
#
# 本脚本仅供学习交流请在下载后的24小时内完全删除
# 请勿用于商业用途或非法目的,否则后果自负"""
import requests
import json
import os
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
import re
import time
import random
from requests.exceptions import RequestException
# 创建全局 session
session = requests.Session()
# API认证相关
API_URL = os.getenv("mmyd_url") # 检测文章提交接口URL
PUSH_TOKEN = os.getenv("mmyd_token") # PushPlus推送token
UA_USER_AGENT = os.getenv("mmyd_ua") # UA
PROXY_URL = os.getenv("mmyd_proxy") #代理
# 新增: PushPlus通知函数
def send_pushplus_notification(token, title, content):
"""使用PushPlus发送通知"""
try:
url_pushplus = "http://www.pushplus.plus/send"
data_pushplus = {
"token": token,
"title": title,
"content": content,
"template": "html"
}
response = requests.post(url_pushplus, data=data_pushplus, timeout=10)
response.raise_for_status()
result = response.json()
if result.get("code") == 200:
print(f"✅ PushPlus通知发送成功", flush=True)
else:
print(f"❗ PushPlus通知发送失败: {result.get('msg', '未知错误')}", flush=True)
except Exception as e:
print(f"❗ PushPlus通知请求异常: {str(e)}", flush=True)
def fetch_luodi_url():
url = "http://thr.zuoanai.cn/baobaocode.php"
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Connection": "keep-alive",
"Host": "thr.zuoanai.cn",
"Referer": "http://thr.zuoanai.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0",
"X-Requested-With": "XMLHttpRequest"
}
resp = session.get(url, headers=headers, timeout=15, proxies=proxies)
resp.raise_for_status()
data = resp.json()
luodi_url = data.get("data", {}).get("luodi")
print(f"获取到活动地址: {luodi_url}")
return luodi_url
def get_first_redirect(luodi_url):
parsed = urlparse(luodi_url)
host = parsed.hostname
path = parsed.path + (f"?{parsed.query}" if parsed.query else "")
headers = {
"Host": host,
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/tpg,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"X-Requested-With": "com.tencent.mm",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
}
url = f"http://{host}{path}"
resp = session.get(url, headers=headers, allow_redirects=False, timeout=15)
if resp.status_code == 302:
location = resp.headers.get('Location')
# print(f"302跳转地址: {location}")
parsed2 = urlparse(location)
new_host = parsed2.hostname
m = re.search(r'/haobaobao/([^/?]+)', parsed2.path)
cid = m.group(1) if m else None
# print(f"新域名: {new_host}, cid: {cid}")
return new_host, cid
else:
print(f"未返回302状态码: {resp.status_code}")
print(resp.text)
return None, None
def get_redirect_url(code, cid):
url = f"http://soicq.hzyunyan.cn/blank_ground.html?type=bao&cid={cid}&code={code}&state=1"
headers = {
"Host": "soicq.hzyunyan.cn",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"X-Requested-With": "com.tencent.mm",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
}
resp = session.get(url, headers=headers, allow_redirects=False, timeout=15)
if resp.status_code == 302:
location = resp.headers.get('Location')
# print(f"redirect接口302 Location: {location}")
return location
else:
print(f"redirect接口未返回302状态码: {resp.status_code}")
print(resp.text)
return None
def get_bbus_from_url(bbus_url):
# 处理q参数去掉v前缀
parsed = urlparse(bbus_url)
qs = parse_qs(parsed.query)
# 处理q参数
if 'q' in qs and qs['q']:
qval = qs['q'][0]
if qval.startswith('v') and len(qval) > 1:
qs['q'][0] = qval[1:]
# 处理v参数替换为当前时间戳减6小时2秒
if 'v' in qs and qs['v']:
now = int(time.time())
v_new = now - (6 * 3600)
qs['v'][0] = str(v_new)
new_query = urlencode(qs, doseq=True)
bbus_url = urlunparse(parsed._replace(query=new_query))
headers = {
"Host": parsed.hostname,
"Upgrade-Insecure-Requests": "1",
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive"
}
resp = session.get(bbus_url, headers=headers, timeout=15)
# print(resp.text)
print(f"请求: {bbus_url}")
print("--- 响应标头 ---")
for k, v in resp.headers.items():
print(f"{k}: {v}")
set_cookie = resp.headers.get('Set-Cookie', '')
m = re.search(r'bbus=([^;]+)', set_cookie)
bbus = m.group(1) if m else None
print(f"bbus: {bbus}")
return bbus
def get_location_domain(cid, bbus, new_host):
"""
1. GET /haobaobao/v{cid}?v=xxx带 bbus cookie获取 302 Location 域名
返回 (location_url, location_domain)
"""
v = int(time.time())
url = f"http://{new_host}/haobaobao/v{cid}?v={v}"
headers = {
"Host": new_host,
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/tpg,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"X-Requested-With": "com.tencent.mm",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": f"bbus={bbus}"
}
resp = session.get(url, headers=headers, allow_redirects=False, timeout=15)
location = resp.headers.get('Location')
if not location:
print(f"未获取到Location状态码: {resp.status_code}")
return None, None
# 提取域名
parsed = urlparse(location)
location_domain = parsed.hostname
# print(f"Location: {location}\nLocation域名: {location_domain}")
return location, location_domain
def post_mwtmpdomain(location_domain, bbus):
"""
2. POST /mwtmpdomain带 bbus cookie返回 domain/sk
"""
url = f"http://{location_domain}/mwtmpdomain"
headers = {
"Host": location_domain,
"Connection": "keep-alive",
"Content-Length": "0",
"User-Agent": UA_USER_AGENT,
"Accept": "application/json, text/javascript, */*; q=0.01",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{location_domain}",
"Referer": f"http://{location_domain}/haobaobao/home?v=1700447805",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": f"bbus={bbus}"
}
resp = session.post(url, headers=headers, timeout=15)
try:
data = resp.json()
domain_url = data['data']['domain']
from urllib.parse import urlparse, parse_qs
parsed = urlparse(domain_url)
qs = parse_qs(parsed.query)
sk = qs.get('sk', [None])[0]
# print(f"domain: {domain_url}\nsk: {sk}")
return domain_url, sk
except Exception as e:
print(f"解析domain/sk失败: {e}")
return None, None
def get_user_url(cid, bbus, new_host):
"""
综合流程:
1. 通过 get_location_domain 获取 Location 域名
2. 通过 post_mwtmpdomain 获取 domain/sk
返回 domain_url, sk
"""
location_url, location_domain = get_location_domain(cid, bbus, new_host)
if not location_domain:
return None, None
domain_url, sk = post_mwtmpdomain(location_domain, bbus)
return domain_url, sk
def get_article_link(host, sk):
"""
获取文章link
"""
now_ms = int(time.time() * 1000)
mysign = random.randint(100, 999)
vs = random.randint(100, 200)
rmemakdk_url = f"http://{host}/smkrdeas?time={now_ms}&mysign={mysign}&vs={vs}&sk={sk}"
headers = {
"Host": host,
"Connection": "keep-alive",
"User-Agent": UA_USER_AGENT,
"Accept": "application/json, text/javascript, */*; q=0.01",
"X-Requested-With": "XMLHttpRequest",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
}
# print(f"\n📖 请求文章任务: {rmemakdk_url}")
resp = session.get(rmemakdk_url, headers=headers, timeout=15)
return resp.json()
def visit_article_link(link):
"""
访问文章link模拟阅读
"""
article_headers = {
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Connection": "keep-alive"
}
print(f"📖 开始模拟阅读文章...")
resp = session.get(link, headers=article_headers, timeout=15)
return resp
def submit_read_result(host, sk, sleep_time):
"""
提交阅读完成
"""
psign = random.randint(200, 400)
jiajinbimao_url = f"http://{host}/jiajinbimao?time={sleep_time}&psign={psign}&sk={sk}"
headers = {
"Host": host,
"Connection": "keep-alive",
"User-Agent": UA_USER_AGENT,
"Accept": "application/json, text/javascript, */*; q=0.01",
"X-Requested-With": "XMLHttpRequest",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
}
# print(f"📖 提交阅读完成")
resp2 = session.get(jiajinbimao_url, headers=headers, timeout=15)
return resp2.json()
def read_article(domain_url, sk):
"""
1. GET /rmemakdk 获取文章link
2. 请求link等待20-30秒
3. GET /jiajinbimao 获取阅读结果
检测文章biz特殊处理如biz在检测列表等待120-130秒提示手动阅读
"""
check_biz_list = [
"MzkzMTYyMDU0OQ==", "Mzk0NDcxMTk2MQ==",
"MzkzNTYxOTgyMA==", "MzkzNDYxODY5OA==",
"MzkwNzYwNDYyMQ==", "MzkyNjY0MTExOA==",
"MzkwMTYwNzcwMw==", "Mzg4NTcwODE1NA==",
"MzkyMjYxNzQ2NA==", "Mzk4ODQzNjU1OQ==",
"MzkyMTc0MDU5Nw==", "Mzk4ODQzNzU3NA==",
"Mzk5MDc1MDQzOQ==",
]
parsed = urlparse(domain_url)
host = parsed.hostname
# 1. 获取文章link
try:
data = get_article_link(host, sk)
link = data.get('data', {}).get('link')
if not link:
if data.get('errcode') == 407:
print('⚠️ 60分钟后可继续阅读')
elif data.get('errcode') == 405:
print(f"{data.get('msg')}")
else:
print(f"❌ 未获取到文章link: {data}")
return False
# print(f"✅ 获取到文章: {link}")
# 提取biz
biz_match = parse_qs(urlparse(link).query).get('__biz', [None])[0]
print(f"文章标题: {biz_match}")
print(f"📖 开始阅读: {link}", flush=True)
# 检测文章特殊处理
auto_checked = False
if biz_match in check_biz_list or biz_match is None:
wait_time = random.randint(120, 130)
title = "⚠️ 猫猫检测文章请在120s内完成阅读"
content = f"""
⚠️ 请在120s内完成阅读
⚠️ 每次阅读不得少于8秒
文章链接:{link}
当前时间 {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
"""
# 自动过检逻辑
auto_checked = False
if API_URL:
print(f"送入自动过检...")
payload = {"url": link,"ck":bbus,"ua":UA_USER_AGENT,'version':'3.0'}
try:
resp = requests.post(API_URL, json=payload, timeout=60).json()
if resp['status'] == 'success':
time.sleep(25)
print(f"✅ 自动过检成功,跳过推送")
auto_checked = True
else:
print(f"❌ 自动过检失败", resp['message'])
except Exception as e:
print(f"自动过检请求异常: {e}")
if not auto_checked:
if PUSH_TOKEN:
print("开始推送文章...")
send_pushplus_notification(PUSH_TOKEN, title, content)
else:
print("未配置推送token尝试使用青龙配置文件推送")
print(QLAPI.notify(title, content))
print(f"⏳ 检测文章等待 {wait_time} 秒...")
time.sleep(wait_time)
# 检测文章不请求link但需要调用jiajinbimao接口
sleep_time = random.randint(9, 18)
else:
# 2. 请求 link等待20-30秒
try:
print(link)
visit_article_link(link)
sleep_time = random.randint(9, 18)
print(f"⏳ 等待 {sleep_time} 秒模拟阅读...")
time.sleep(sleep_time)
except Exception as e:
print(f"❌ 阅读文章请求失败: {e}")
return False
# 3. GET /jiajinbimao 获取阅读结果
max_retries = 3
for retry_count in range(max_retries):
try:
data2 = submit_read_result(host, sk, sleep_time)
if data2.get('errcode') == 0:
d = data2.get('data', {})
print(
f"✅ 阅读完成!本次金币: {d.get('gold')},今日已读: {d.get('day_read')},今日金币: {d.get('day_gold')},当前金币: {d.get('last_gold')},剩余可读: {d.get('remain_read')}")
return True
elif data2.get('errcode') == 405 and '未能获取到用户信息' in str(data2.get('msg')):
print(f"⚠️ 第 {retry_count + 1}/{max_retries} 次获取用户信息失败: {data2.get('msg')},正在重试...")
if retry_count == max_retries - 1:
print(f"❌ 连续 {max_retries} 次用户信息获取失败,退出运行")
return False
time.sleep(2)
continue
else:
print(f"❌ 阅读完成接口返回失败: {data2}")
return False
except requests.exceptions.ReadTimeout:
print(f"⏰ 第 {retry_count + 1}/{max_retries} 次请求超时,正在重试...")
if retry_count == max_retries - 1:
print(f"❌ 连续 {max_retries} 次请求超时,退出运行")
return False
time.sleep(2)
except Exception as e:
print(f"❌ 阅读完成接口请求失败: {e}")
return False
except Exception as e:
print(f"❌ 解析文章任务响应失败: {e}")
return False
def confirm_withdraw(domain_url, bbus, signid):
"""
确认提现
"""
from urllib.parse import urlparse
host = urlparse(domain_url).hostname
url = f"http://{host}/haobaobao/getwithdraw"
headers = {
"Host": host,
"Connection": "keep-alive",
"User-Agent": UA_USER_AGENT,
"Accept": "application/json, text/javascript, */*; q=0.01",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Origin": f"http://{host}",
"Referer": f"http://{host}/haobaobao/withdraw",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": f"bbus={bbus}",
"X-Requested-With": "XMLHttpRequest"
}
data = f"signid={signid}&ua=2&ptype=0&paccount=&pname="
# print(f"\n🔄 正在确认提现")
resp = session.post(url, headers=headers, data=data, timeout=15)
try:
res_json = resp.json()
if res_json.get('errcode') == 0:
print("✅ 确认提现成功")
else:
if res_json.get('errcode') == 405:
print(res_json.get('msg').replace("<br>", "\n"))
else:
print(f"❌ 确认提现失败: {res_json}")
except Exception as e:
print(f"❌ 确认提现响应解析失败: {e}")
def get_user_info_and_withdraw(domain_url, bbus):
"""
获取用户信息并自动提现
"""
from urllib.parse import urlparse
host = urlparse(domain_url).hostname
withdraw_url = f"http://{host}/haobaobao/withdraw"
headers = {
"Host": host,
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/tpg,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"X-Requested-With": "com.tencent.mm",
"Referer": f"http://{host}/haobaobao/home?v=1751942506",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": f"bbus={bbus}"
}
try:
resp = session.get(withdraw_url, headers=headers, timeout=30)
except requests.exceptions.ReadTimeout as e:
print(f"[超时] 获取用户信息/提现页面超时: {e}")
return None
except Exception as e:
print(f"[异常] 获取用户信息/提现页面失败: {e}")
return None
html = resp.text
# 提取参数
def extract_var(varname):
m = re.search(rf'var {varname} ?= ?["\']?([^;"\']+)["\']?;', html)
return m.group(1) if m else None
request_id = extract_var('request_id')
nickname = extract_var('nickname')
qrcode_num = extract_var('qrcode_num')
isallowtj = extract_var('isallowtj')
# 提取金币
m_gold = re.search(r'<p class="f_left" id="exchange_gold">(\d+)</p>', html)
exchange_gold = int(m_gold.group(1)) if m_gold else 0
print(f"用户ID: {nickname}")
print(f"邀请人ID: {qrcode_num}")
# print(f"是否可提现(isallowtj): {isallowtj}")
print(f"当前金币: {exchange_gold}")
# print(f"request_id: {request_id}")
# 自动提现
gold = (exchange_gold // 1000) * 1000
if gold == 0 or not request_id:
print("❌ 无法提现金币不足或request_id缺失")
return request_id
if gold < MIN_WITHDRAW_GOLD:
print(f"❌ 当前金币 {gold} 未达到提现门槛 {MIN_WITHDRAW_GOLD},跳过提现")
return request_id
post_url = f"http://{host}/haobaobao/getgold"
post_headers = headers.copy()
post_headers.update({
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Origin": f"http://{host}",
"Referer": f"http://{host}/haobaobao/withdraw",
"Accept": "application/json, text/javascript, */*; q=0.01"
})
data = f"request_id={request_id}&gold={gold}"
print(f"\n💸 正在发起提现,金币: {gold}")
resp2 = session.post(post_url, headers=post_headers, data=data, timeout=15)
try:
res_json = resp2.json()
if res_json.get('errcode') == 0:
money = res_json.get('data', {}).get('money')
print(f"✅ 提现成功,金额: {money}")
else:
if res_json.get('errcode') == 405:
print(res_json.get('msg').replace("<br>", "\n"))
else:
print(f"❌ 提现失败: {res_json}")
except Exception as e:
print(f"❌ 提现响应解析失败: {e}")
return request_id
def get_promotion_link(domain_url, bbus):
"""
获取推广链接输出qrcodes1和作者推广链接
"""
from urllib.parse import urlparse
host = urlparse(domain_url).hostname
url = f"http://{host}/tiyvaewmk?v=1"
headers = {
"Host": host,
"Connection": "keep-alive",
"User-Agent": UA_USER_AGENT,
"Accept": "application/json, text/javascript, */*; q=0.01",
"X-Requested-With": "XMLHttpRequest",
"Referer": f"http://{host}/haobaobao/showcode",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": f"bbus={bbus}"
}
try:
resp = session.get(url, headers=headers, timeout=15)
data = resp.json()
if data.get('errcode') == 0:
qrcodes1 = data.get('data', {}).get('qrcodes', {}).get('qrcodes1')
if qrcodes1:
# print(f"[🌟 推广链接] {qrcodes1}")
# 输出作者推广链接
# 替换kstief/后面的内容
author_link = re.sub(r'(kstief/)[^/?]+(\?tsd=\d+)?', lambda m: m.group(1) + author_code, qrcodes1)
print(f"[👨‍💻 作者推广链接] {author_link}")
else:
print("[❌ 推广链接] 未找到qrcodes1")
else:
print(f"[❌ 推广链接] 获取失败: {data}")
except Exception as e:
print(f"[❌ 推广链接] 请求异常: {e}")
def refresh_cookie(domain_url, bbus):
"""
刷新cookieGET /haobaobao/v1{author_code}?v=...响应302为成功
"""
from urllib.parse import urlparse
import time
host = urlparse(domain_url).hostname
v = int(time.time())
author_code = "1b69893ab98f0fd50e13e7d3e19d3c65" # 与全局变量保持一致
url = f"http://{host}/haobaobao/v1{author_code}?v={v}"
headers = {
"Host": host,
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"X-Requested-With": "com.tencent.mm",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": f"bbus={bbus}"
}
try:
resp = session.get(url, headers=headers, allow_redirects=False, timeout=10)
if resp.status_code == 302:
print(f"[Cookie刷新] 刷新成功")
return True
else:
print(f"[Cookie刷新] {host} 刷新失败,状态码: {resp.status_code}")
return False
except Exception as e:
print(f"[Cookie刷新] {host} 请求异常: {e}")
return False
def enter_home(domain_url, bbus):
"""
进入主页返回True表示成功False表示失败
"""
try:
import time
from urllib.parse import urlparse
host = urlparse(domain_url).hostname
v = int(time.time())
home_url = f"http://{host}/haobaobao/home?v={v}"
headers = {
"Host": host,
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"User-Agent": UA_USER_AGENT,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"X-Requested-With": "com.tencent.mm",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": f"bbus={bbus}"
}
resp = session.get(home_url, headers=headers, timeout=10)
if resp.status_code == 200:
# print(f"[主页] 进入主页成功")
return True
else:
print(f"[Cookie刷新] Cookie刷新失败状态码: {resp.status_code}")
return False
except Exception as e:
print(f"[Cookie刷新] Cookie刷新请求异常: {e}")
return False
# ===== 全局变量配置区 =====
MAX_RUNS = 30
author_code = "6c3a4d61c4b9467a869f21007fc8e4fc?tsd=971"
MIN_WITHDRAW_GOLD = 5000 # 新增:提现所需最小金币数
if __name__ == "__main__":
MULTI_ACCOUNT_SPLIT = ["\n", "@", "&"] # 分隔符列表
BBUS_LIST_OS = os.getenv(f"mmyd_ck")
if not BBUS_LIST_OS:
print("❌ 未配置cookie程序无法继续执行即将退出", flush=True)
exit(1)
BBUS_LIST = []
if BBUS_LIST_OS:
# 多分隔符分割
split_pattern = '|'.join(map(re.escape, MULTI_ACCOUNT_SPLIT))
bbus_items = [x for x in re.split(split_pattern, BBUS_LIST_OS) if x.strip()]
print(f"🔍 从环境变量获取cookie: {len(bbus_items)}")
BBUS_LIST.extend(bbus_items)
print(f"从环境变量中获取到了,共{len(BBUS_LIST)}个账号")
print(BBUS_LIST)
# 检查自动过检配置
if API_URL:
print(f"✅ 已配置自动过检接口: {API_URL}")
else:
print(" 未配置自动过检接口,检测文章将直接推送通知")
# 检查推送token配置
if PUSH_TOKEN:
print(f"✅ 已配置推送token: {PUSH_TOKEN}")
else:
print(" 未配置推送token检测文章将不会推送通知")
# 检查代理配置
if PROXY_URL:
print(f"✅ 已配置代理: {PROXY_URL}")
else:
print(" 未配置代理,采用本地请求")
# 最大运行次数默认30次
# MAX_RUNS = 30 # This line is removed as MAX_RUNS is now a global variable
print(f"检测到共{len(BBUS_LIST)}个账号")
for idx, bbus in enumerate(BBUS_LIST):
proxies = {}
if PROXY_URL:
try:
get_ip = requests.get(PROXY_URL).text
proxies = {
"http": f"http://{get_ip}",
"https": f"http://{get_ip}",
}
session.proxies = proxies
except Exception as e:
print('获取代理失败,使用本地网络执行')
print(f"\n{'=' * 10}🔰开始执行账号{idx + 1}🔰{'=' * 10}\n", flush=True)
try:
luodi_url = fetch_luodi_url()
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 获取活动地址失败: {e}")
continue
if not luodi_url:
continue
try:
new_host, cid = get_first_redirect(luodi_url)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 获取跳转地址失败: {e}")
continue
if not new_host or not cid:
continue
# 获取nLocation域名
try:
location_url, location_domain = get_location_domain(cid, bbus, new_host)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 获取nLocation域名失败: {e}")
continue
if not location_domain:
continue
# 用nLocation域名拼成domain_url
nlocation_domain_url = f"http://{location_domain}"
# 刷新cookie
try:
refresh_cookie(nlocation_domain_url, bbus)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 刷新cookie失败: {e}")
continue
# 刷新后进入主页
try:
enter_home(nlocation_domain_url, bbus)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 进入主页失败: {e}")
continue
# 后续流程依然用原有domain_url, sk
try:
domain_url, sk = post_mwtmpdomain(location_domain, bbus)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 获取domain_url/sk失败: {e}")
continue
# print(f"最终用户url: {domain_url}\nsk: {sk}")
for run_count in range(1, MAX_RUNS + 1):
print(f"\n🔄 第 {run_count}/{MAX_RUNS} 次运行")
print("-" * 50)
try:
success = read_article(domain_url, sk)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 阅读文章失败: {e}")
break
if not success:
print(f"❌ 第 {run_count} 次运行失败")
break
# print(f"✅ 第 {run_count} 次运行完成")
if run_count < MAX_RUNS:
wait_time = random.randint(2, 5)
print(f"⏳ 等待 {wait_time} 秒后继续下一次运行...")
time.sleep(wait_time)
print(f"\n🎉 账号运行完成!共运行 {run_count}")
try:
request_id = get_user_info_and_withdraw(nlocation_domain_url, bbus)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 获取用户信息/提现失败: {e}")
continue
# 新增:获取推广链接
try:
get_promotion_link(nlocation_domain_url, bbus)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 获取推广链接失败: {e}")
continue
time.sleep(random.randint(2, 3))
try:
confirm_withdraw(nlocation_domain_url, bbus, request_id)
except requests.exceptions.ConnectionError as e:
print(f"[连接错误] 确认提现失败: {e}")
continue
# 当前脚本来自于http://script.345yun.cn脚本库下载