Continue seeded Qinglong script collection
This commit is contained in:
430
脚本库/web版/账密/嘤嘤怪之家/2025-08-27_嘤嘤怪之家_9e2e2ee0.py
Normal file
430
脚本库/web版/账密/嘤嘤怪之家/2025-08-27_嘤嘤怪之家_9e2e2ee0.py
Normal file
@@ -0,0 +1,430 @@
|
||||
# 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()
|
||||
Reference in New Issue
Block a user