下载地址:www.pan38.com/dow/share.p… 提取密码:3722
这个自动刷视频系统包含主程序、配置管理和GUI控制三大模块。主程序使用pyautogui实现自动滑动和鼠标移动,pynput监听热键控制。配置模块支持JSON格式的持久化设置。GUI提供直观的操作界面和参数调整功能。使用时需先安装依赖,可通过中键点击或GUI按钮启动/停止自动滑动。
import time import random import pyautogui from pynput import mouse, keyboard import threading import logging from datetime import datetime
class VideoAutoScroller: def init(self): self.is_running = False self.scroll_interval = 30 # 默认30秒滑动一次 self.logger = self.setup_logger() self.stop_event = threading.Event() self.mouse_listener = None self.keyboard_listener = None
def setup_logger(self):
logger = logging.getLogger('VideoAutoScroller')
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
# 文件日志
file_handler = logging.FileHandler('video_scroller.log')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# 控制台日志
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
return logger
def on_click(self, x, y, button, pressed):
if pressed and button == mouse.Button.middle:
self.toggle_scrolling()
return True
def on_press(self, key):
try:
if key.char == 'q':
self.stop_scrolling()
except AttributeError:
pass
return True
def start_listeners(self):
self.mouse_listener = mouse.Listener(on_click=self.on_click)
self.keyboard_listener = keyboard.Listener(on_press=self.on_press)
self.mouse_listener.start()
self.keyboard_listener.start()
def random_scroll(self):
scroll_amount = random.randint(500, 800)
pyautogui.scroll(-scroll_amount)
self.logger.info(f"向下滑动 {scroll_amount} 单位")
def random_mouse_movement(self):
x, y = pyautogui.position()
new_x = x + random.randint(-50, 50)
new_y = y + random.randint(-50, 50)
pyautogui.moveTo(new_x, new_y, duration=0.5)
def scrolling_loop(self):
while not self.stop_event.is_set():
try:
self.random_scroll()
if random.random() > 0.7: # 30%概率移动鼠标
self.random_mouse_movement()
# 随机间隔增加人性化
interval = self.scroll_interval + random.randint(-5, 5)
self.stop_event.wait(interval)
except Exception as e:
self.logger.error(f"滚动时发生错误: {str(e)}")
time.sleep(5)
def start_scrolling(self):
if not self.is_running:
self.is_running = True
self.stop_event.clear()
self.scroll_thread = threading.Thread(target=self.scrolling_loop)
self.scroll_thread.start()
self.logger.info("自动滑动已启动")
def stop_scrolling(self):
if self.is_running:
self.is_running = False
self.stop_event.set()
self.scroll_thread.join()
self.logger.info("自动滑动已停止")
def toggle_scrolling(self):
if self.is_running:
self.stop_scrolling()
else:
self.start_scrolling()
def run(self):
self.logger.info("视频自动滑动程序启动")
self.start_listeners()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
self.stop_scrolling()
if self.mouse_listener:
self.mouse_listener.stop()
if self.keyboard_listener:
self.keyboard_listener.stop()
self.logger.info("程序正常退出")
if name == "main": scroller = VideoAutoScroller() scroller.run()
json import os from pathlib import Path
class ConfigManager: DEFAULT_CONFIG = { "scroll_interval": 30, "min_scroll_amount": 500, "max_scroll_amount": 800, "mouse_movement_probability": 0.3, "random_interval_range": 5, "hotkeys": { "start_stop": "middle_mouse", "emergency_stop": "q" }, "log_settings": { "log_to_file": True, "log_to_console": True, "log_level": "INFO" } }
def __init__(self, config_file="config.json"):
self.config_file = Path(config_file)
self.config = None
self.load_config()
def load_config(self):
if self.config_file.exists():
try:
with open(self.config_file, 'r') as f:
self.config = json.load(f)
self.validate_config()
except (json.JSONDecodeError, IOError) as e:
print(f"加载配置文件失败: {e}, 使用默认配置")
self.config = self.DEFAULT_CONFIG.copy()
else:
self.config = self.DEFAULT_CONFIG.copy()
self.save_config()
def save_config(self):
try:
with open(self.config_file, 'w') as f:
json.dump(self.config, f, indent=4)
except IOError as e:
print(f"保存配置文件失败: {e}")
def validate_config(self):
# 验证所有必需的配置项都存在
for key in self.DEFAULT_CONFIG:
if key not in self.config:
self.config[key] = self.DEFAULT_CONFIG[key]
# 验证特定值的有效性
if not (10 <= self.config["scroll_interval"] <= 600):
self.config["scroll_interval"] = self.DEFAULT_CONFIG["scroll_interval"]
if not (100 <= self.config["min_scroll_amount"] <= self.config["max_scroll_amount"] <= 1200):
self.config["min_scroll_amount"] = self.DEFAULT_CONFIG["min_scroll_amount"]
self.config["max_scroll_amount"] = self.DEFAULT_CONFIG["max_scroll_amount"]
def get(self, key, default=None):
keys = key.split('.')
value = self.config
try:
for k in keys:
value = value[k]
return value
except (KeyError, TypeError):
return default
def set(self, key, value):
keys = key.split('.')
current = self.config
for k in keys[:-1]:
if k not in current:
current[k] = {}
current = current[k]
current[keys[-1]] = value
self.save_config()
tkinter as tk from tkinter import ttk, messagebox import threading from config_manager import ConfigManager
class UIController: def init(self, scroller): self.scroller = scroller self.config = ConfigManager() self.root = tk.Tk() self.setup_ui() self.update_ui_from_config()
def setup_ui(self):
self.root.title("视频自动滑动控制器")
self.root.geometry("400x300")
self.root.protocol("WM_DELETE_WINDOW", self.on_close)
# 主框架
main_frame = ttk.Frame(self.root, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)
# 控制按钮
self.control_frame = ttk.LabelFrame(main_frame, text="控制", padding="10")
self.control_frame.pack(fill=tk.X, pady=5)
self.start_button = ttk.Button(
self.control_frame,
text="开始",
command=self.toggle_scrolling
)
self.start_button.pack(side=tk.LEFT, padx=5)
self.stop_button = ttk.Button(
self.control_frame,
text="停止",
command=self.stop_scrolling,
state=tk.DISABLED
)
self.stop_button.pack(side=tk.LEFT, padx=5)
# 设置面板
self.settings_frame = ttk.LabelFrame(main_frame, text="设置", padding="10")
self.settings_frame.pack(fill=tk.BOTH, expand=True, pady=5)
# 滑动间隔设置
ttk.Label(self.settings_frame, text="滑动间隔(秒):").grid(row=0, column=0, sticky=tk.W)
self.interval_var = tk.IntVar()
self.interval_spin = ttk.Spinbox(
self.settings_frame,
from_=10,
to=600,
increment=5,
textvariable=self.interval_var,
width=5
)
self.interval_spin.grid(row=0, column=1, sticky=tk.W)
# 滑动幅度设置
ttk.Label(self.settings_frame, text="最小滑动幅度:").grid(row=1, column=0, sticky=tk.W)
self.min_scroll_var = tk.IntVar()
self.min_scroll_spin = ttk.Spinbox(
self.settings_frame,
from_=100,
to=1200,
increment=50,
textvariable=self.min_scroll_var,
width=5
)
self.min_scroll_spin.grid(row=1, column=1, sticky=tk.W)
ttk.Label(self.settings_frame, text="最大滑动幅度:").grid(row=2, column=0, sticky=tk.W)
self.max_scroll_var = tk.IntVar()
self.max_scroll_spin = ttk.Spinbox(
self.settings_frame,
from_=100,
to=1200,
increment=50,
textvariable=self.max_scroll_var,
width=5
)
self.max_scroll_spin.grid(row=2, column=1, sticky=tk.W)
# 保存按钮
self.save_button = ttk.Button(
self.settings_frame,
text="保存设置",
command=self.save_settings
)
self.save_button.grid(row=3, column=0, columnspan=2, pady=10)
# 状态栏
self.status_var = tk.StringVar()
self.status_var.set("就绪")
self.status_bar = ttk.Label(
self.root,
textvariable=self.status_var,
relief=tk.SUNKEN,
anchor=tk.W
)
self.status_bar.pack(fill=tk.X)
def update_ui_from_config(self):
self.interval_var.set(self.config.get("scroll_interval"))
self.min_scroll_var.set(self.config.get("min_scroll_amount"))
self.max_scroll_var.set(self.config.get("max_scroll_amount"))
def save_settings(self):
try:
self.config.set("scroll_interval", self.interval_var.get())
self.config.set("min_scroll_amount", self.min_scroll_var.get())
self.config.set("max_scroll_amount", self.max_scroll_var.get())
messagebox.showinfo("成功", "设置已保存")
except Exception as e:
messagebox.showerror("错误", f"保存设置失败: {str(e)}")
def toggle_scrolling(self):
if not self.scroller.is_running:
self.start_scrolling()
else:
self.stop_scrolling()
def start_scrolling(self):
self.scroller.scroll_interval = self.interval_var.get()
self.scroller.start_scrolling()
self.start_button.config(state=tk.DISABLED)
self.stop_button.config(state=tk.NORMAL)
self.status_var.set("自动滑动运行中...")
def stop_scrolling(self):
self.scroller.stop_scrolling()
self.start_button.config(state=tk.NORMAL)
self.stop_button.config(state=tk.DISABLED)
self.status_var.set("已停止")
def on_close(self):
if self.scroller.is_running:
if messagebox.askokcancel("退出", "自动滑动仍在运行,确定要退出吗?"):
self.scroller.stop_scrolling()
self.root.destroy()
else:
self.root.destroy()
def run(self):
self.root.mainloop()