Files
qinglong/脚本库/web版/账密/嘤嘤怪之家/2025-08-27_嘤嘤怪之家_9e2e2ee0.py
2026-05-24 05:33:05 +00:00

431 lines
17 KiB
Python
Raw 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/LinYuanovo/AutoTaskScripts/blob/main/web/%E5%98%A4%E5%98%A4%E6%80%AA%E4%B9%8B%E5%AE%B6.py
# Raw: https://raw.githubusercontent.com/LinYuanovo/AutoTaskScripts/main/web/%E5%98%A4%E5%98%A4%E6%80%AA%E4%B9%8B%E5%AE%B6.py
# Repo: LinYuanovo/AutoTaskScripts
# Path: web/嘤嘤怪之家.py
# UploadedAt: 2025-08-27T15:31:08+08:00
# SHA256: 9e2e2ee0614b254534faf4e169de569e3d9bbc058a01ef97defe9b330fc9dd90
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
作者: 临渊
日期: 2025/6/8
name: 嘤嘤怪之家
入口: 网站 (https://yyg.app/)
功能: 登录、签到、评论每日上限30积分
变量: yyg='账号&密码' 多个账号用换行分割
DDDD_OCR_URL (dddd_ocr地址)
定时: 一天两次
cron: 10 9,10 * * *
------------更新日志------------
2025/6/8 V1.0 初始化,完成签到功能
2025/6/10 V1.1 添加评论功能
2025/6/11 V1.2 优化代码结构使用session管理cookie添加查询积分功能不一定成功
2025/7/23 V1.3 更新域名
2025/7/28 V1.4 修改头部注释,以便拉库
2025/8/27 V1.5 增加尝试获取最新域名
"""
import requests
import os
import re
import urllib.parse
import time
import random
import logging
import traceback
from datetime import datetime
from bs4 import BeautifulSoup
DDDD_OCR_URL = os.getenv("DDDD_OCR_URL") or "" # dddd_ocr地址
DEFAULT_GUIDE_URL = "https://yyg.autos/" # 默认发布地址
DEFAULT_HOST = "yyg.app" # 默认域名
class AutoTask:
def __init__(self, site_name):
"""
初始化自动任务类
:param site_name: 站点名称,用于日志显示
"""
self.site_name = site_name
self.setup_logging()
def setup_logging(self):
"""
配置日志系统
"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s\t- %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[
# logging.FileHandler(f'{self.site_name}_{datetime.now().strftime("%Y%m%d")}.log', encoding='utf-8'), # 保存日志
logging.StreamHandler()
]
)
def check_cookie(self):
"""
检查cookie
:return: 用户名和密码
"""
try:
# 从环境变量获取cookie
cookie = os.getenv(f"yyg")
if not cookie:
logging.error(f"[检查cookie]没有找到环境变量yyg")
return
# 多个账号用换行分割
cookies = cookie.split('\n')
for cookie in cookies:
# 解析cookie字符串提取用户名和密码
username, password = cookie.split('&')
yield username, password
except Exception as e:
logging.error(f"[检查cookie]发生错误: {str(e)}\n{traceback.format_exc()}")
raise
def get_host(self):
"""
获取最新域名
:return: 域名
"""
try:
url = DEFAULT_GUIDE_URL
response = requests.get(url)
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'html.parser')
links = soup.find_all('a')
for link in links:
link_text = link.get_text(strip=True)
if re.search(r'访问最新域名', link_text):
href_value = link.get('href')
if href_value.startswith("http"):
host = href_value.split("//")[1]
logging.info(f"[获取最新域名]最新域名: {host}")
return host
else:
return href_value
return DEFAULT_HOST
except Exception as e:
logging.error(f"[获取最新域名]发生错误: {str(e)}\n{traceback.format_exc()}")
return DEFAULT_HOST
def get_captcha_img(self, host, session, type):
"""
获取验证码图片
:param host: 域名
:param session: 会话对象
:param type: 验证码类型
:return: 验证码base64
"""
max_retries = 3 # 最大重试次数
retry_count = 0
while retry_count < max_retries:
try:
url = f"https://{host}/wp-content/themes/zibll/action/captcha.php?type=image&id={type}"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
}
response = session.get(url, headers=headers).json()
if 'img' in response:
return response['img']
else:
retry_count += 1
logging.warning(f"[获取验证码]第{retry_count}次获取失败,正在重试...")
continue
except Exception as e:
retry_count += 1
if retry_count >= max_retries:
logging.error(f"[获取验证码]重试次数已达上限")
return None
continue
return None
def get_captcha_text(self, img):
"""
获取验证码文字
:param img: 验证码图片base64
:return: 验证码
"""
try:
url = DDDD_OCR_URL
payload = {
'image': img
}
response = requests.post(url, data=payload).json()
if response['code'] == 200:
return response['data']
else:
logging.error(f"[获取验证码]发生错误: {response['message']}")
return None
except Exception as e:
logging.error(f"[获取验证码]发生错误: {str(e)}\n{traceback.format_exc()}")
return None
def login_in(self, host, username, password, text, session):
"""
登录
:param host: 域名
:param username: 用户名
:param password: 密码
:param text: 验证码
:param session: 会话对象
:return: 是否成功
"""
max_retries = 3 # 最大重试次数
retry_count = 0
while retry_count < max_retries:
try:
url = f"https://{host}/wp-admin/admin-ajax.php"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
payload = f"username={username}&password={password}&canvas_yz={text}&remember=forever&action=user_signin"
response = session.post(url, headers=headers, data=payload)
response_json = response.json()
if response_json['error'] == 0:
logging.info(f"[登录]成功")
return True
else:
logging.error(f"[登录]失败: {response_json['msg']}")
if "重新获取" in response_json['msg'] or "请输入图形验证码" in response_json['msg']:
retry_count += 1
if retry_count >= max_retries:
logging.error(f"[登录]验证码重试次数已达上限")
return False
img = self.get_captcha_img(host, session, "img_yz_signin")
while not img:
img = self.get_captcha_img(host, session, "img_yz_signin")
text = self.get_captcha_text(img)
if not text:
logging.error(f"[登录]获取验证码文字失败")
return False
continue
return False
except requests.RequestException as e:
logging.error(f"[登录]发生网络错误: {str(e)}\n{traceback.format_exc()}")
return False
except Exception as e:
logging.error(f"[登录]发生未知错误: {str(e)}\n{traceback.format_exc()}")
return False
return False
def sign_in(self, host, session):
"""
执行签到
:param host: 域名
:param session: 会话对象
:return: 是否签到成功
"""
try:
url = f"https://{host}/wp-admin/admin-ajax.php"
headers = {
'Host': host,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
}
payload = "action=user_checkin"
response = session.post(url, headers=headers, data=payload)
response_json = response.json()
# 处理响应
logging.info(f"[签到]{response_json['msg']}")
return response_json['msg']
except requests.RequestException as e:
logging.error(f"[签到]发生网络错误: {str(e)}\n{traceback.format_exc()}")
return False
except Exception as e:
logging.error(f"[签到]发生未知错误: {str(e)}\n{traceback.format_exc()}")
return False
def get_post_id(self, host, session, retry_count=0):
"""
获取帖子id
:param host: 域名
:param session: 会话对象
:param retry_count: 重试次数
:return: 帖子id列表
"""
try:
url = f"https://{host}/category/pcgame?orderby=modified" # 最新排列
headers = {
'Host': host,
'Referer': f"https://{host}/category/pcgame",
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
}
response = session.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
post_ids = []
for i in range(3,7):
# 找到所有posts元素
links = soup.select(f'body > main > div > div > div:nth-child(2) > posts:nth-child({i}) > div.item-body.flex.xx.flex1.jsb > h2 > a')
if links: # 如果找到了链接
link = links[0] # 获取第一个链接
# 提取帖子ID
if link.get('href'):
# 从URL中提取ID (例如从 https://yyg.boats/14819.html 提取 14819)
post_id = link['href'].split('/')[-1].replace('.html', '')
post_ids.append(post_id)
# 如果没有获取到帖子ID且重试次数小于3次则重试
if not post_ids and retry_count < 3:
logging.info(f"[获取帖子ID]未获取到帖子ID{retry_count + 1}次重试")
time.sleep(random.randint(5, 10))
return self.get_post_id(host, session, retry_count + 1)
elif not post_ids and retry_count >= 3:
post_ids = ['14818', '14817', '14816', '14815']
logging.warning(f"[获取帖子ID]三次未获取到帖子ID使用默认帖子ID: {post_ids}")
logging.info(f"[获取帖子ID]成功获取到 {len(post_ids)} 个帖子ID: {post_ids}")
return post_ids
except requests.RequestException as e:
logging.error(f"[获取帖子ID]发生网络错误: {str(e)}\n{traceback.format_exc()}")
return []
except Exception as e:
logging.error(f"[获取帖子ID]发生未知错误: {str(e)}\n{traceback.format_exc()}")
return []
def submit_comment(self, host, session, captcha, post_id, retry_count=0):
"""
提交评论
:param host: 域名
:param session: 会话对象
:param captcha: 验证码
:param post_id: 帖子ID
:param retry_count: 重试次数
"""
try:
url = f"https://{host}/wp-admin/admin-ajax.php"
headers = {
'Host': host,
'Referer': f"https://{host}/{post_id}.html",
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
}
payload = f"comment=%E6%84%9F%E8%B0%A2%E5%88%86%E4%BA%AB&canvas_yz={captcha}&comment_post_ID={post_id}&comment_parent=0&action=submit_comment"
response = session.post(url, headers=headers, data=payload)
response_json = response.json()
logging.info(f"[评论帖子{post_id}]{response_json['msg']}")
if "图形验证码错误" in response_json['msg']:
if retry_count >= 3:
logging.warning(f"[评论{post_id}]验证码错误重试次数已达上限,跳过此评论")
return False
logging.info(f"[评论帖子{post_id}]验证码错误,第{retry_count + 1}次重试")
submit_comment_captcha = self.get_captcha_img(host, session, "submit_comment")
while not submit_comment_captcha:
submit_comment_captcha = self.get_captcha_img(host, session, "submit_comment")
submit_comment_text = self.get_captcha_text(submit_comment_captcha)
if not submit_comment_text:
logging.error(f"[评论帖子{post_id}]获取验证码文字失败")
return False
return self.submit_comment(host, session, submit_comment_text, post_id, retry_count + 1)
return response_json['msg']
except Exception as e:
logging.error(f"[评论帖子{post_id}]发生未知错误: {str(e)}\n{traceback.format_exc()}")
return False
def get_user_balance(self, host, session):
"""
获取用户积分
:param host: 域名
:param session: 会话对象
:return: 用户积分
"""
try:
url = f"https://{host}/user/balance"
headers = {
'Host': host,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
}
response = session.get(url, headers=headers)
# 正则匹配积分记录里第一个,即 积分: xxx
balance = re.search(r'积分: (\d+)', response.text)
if balance:
return balance.group(1)
else:
logging.error(f"[获取用户积分]未找到积分记录")
return 0
except Exception as e:
logging.error(f"[获取用户积分]发生未知错误: {str(e)}\n{traceback.format_exc()}")
return 0
def do_task(self, host, session):
"""
执行任务
:param host: 域名
:param session: 会话对象
"""
# 执行签到
self.sign_in(host, session)
# 获取帖子id
post_ids = self.get_post_id(host, session)
# 获取评论验证码图片(四次)
for post_id in post_ids:
captcha = self.get_captcha_img(host, session, "submit_comment")
while not captcha:
captcha = self.get_captcha_img(host, session, "submit_comment")
text = self.get_captcha_text(captcha)
if not text:
logging.error(f"[评论{post_id}]获取验证码文字失败")
continue
# 提交评论
self.submit_comment(host, session, text, post_id)
time.sleep(random.randint(16, 30))
# 获取用户积分
balance = self.get_user_balance(host, session)
logging.info(f"[账号]当前积分: {balance}")
def run(self):
"""
运行任务
"""
try:
logging.info(f"{self.site_name}】开始执行任务")
host = self.get_host()
for index, (username, password) in enumerate(self.check_cookie(), 1):
logging.info("")
logging.info(f"------【账号{index}】开始执行任务------")
# 创建会话
session = requests.Session()
# 获取登录验证码图片
login_in_img = self.get_captcha_img(host, session, "img_yz_signin")
while not login_in_img:
login_in_img = self.get_captcha_img(host, session, "img_yz_signin")
# 获取登录验证码文字
login_in_text = self.get_captcha_text(login_in_img)
if not login_in_text:
logging.error(f"[{self.site_name}]获取登录验证码文字失败")
continue
# 登录
if self.login_in(host, username, password, login_in_text, session):
# 执行任务
self.do_task(host, session)
logging.info(f"------【账号{index}】执行任务完成------")
logging.info("")
except Exception as e:
logging.error(f"{self.site_name}】执行过程中发生错误: {str(e)}\n{traceback.format_exc()}")
if __name__ == "__main__":
auto_task = AutoTask("嘤嘤怪之家")
auto_task.run()