Computer Science,  tools

刷课程序支持工具

页面元素检测扩展工具

  • 程序功能

程序主要基于自动化检测脚本里的有效按钮检测逻辑进行单独扩展,主要是方便用户单独扫描当前页面里符合匹配字段的所有页面元素,并一一进行功能验证,在用户无法直接得到页面元素时可以进行自动检测(如果可以单独获取页面元素,建议使用元素测试脚本,精准度实用性更强)。因此此程序主要功能是获取自动化与非自动刷课脚本里的相关页面元素(视频播放,播放下一个视频等按钮元素),便于配置相关参数,配合刷课脚本完美使用。

  • 程序流程
  1. 用户输入:程序启动时,要求用户输入课程的 URL 和检测次数。
  2. 浏览器初始化与页面加载:程序初始化一个 Chrome 浏览器实例,并打开指定的课程页面。
  3. 模拟视频观看:程序会获取视频的当前状态信息(如视频时长、当前播放时间等),并持续检查视频状态。如果视频暂停,程序会模拟点击播放按钮。程序还会尝试跳转视频进度到最后,模拟快进操作。
  4. 播放和切换到下一个视频:程序会查找并点击播放按钮,确保视频播放。如果视频播放完毕,程序会查找“下一集”按钮并模拟点击,自动播放下一集视频。
  5. 检测次数:用户可以设置检测次数,程序会根据用户的需求反复执行检测操作。
  6. 退出与总结:完成检测后,程序退出浏览器,输出检测完成信息。
  • 程序重点

通过此程序,可以自动检测获取页面所有可能的功能元素,并进行匹配测试,如果符合要求则会输出结果,其结果可以用于改进自动化刷客脚本的检测逻辑,便于排查错误,最主要的是可以通过输出的参数来配置config.json文件,使得半自动脚本支持当前页面。集体参数可以参考config.json的格式内容。

页面元素测试扩展工具

  • 程序功能

程序主要基于上述自动页面元素检测工具进行单独提取,主要用于模拟用户在网页中点击特定按钮或元素,帮助用户检测页面上的可点击元素是否能够正常工作。此程序取消了上述自动程序进行页面全搜索全匹配的笼统方法,反而依靠用户对元素进行精准定位。用户使用此脚本可以将浏览器页面开发者选项里检查道德元素class字段置于此脚本中进行检测,执行相关点击操作,最后用户自主判断是否生效,通过用户端使能将有效字段筛选出来,配合刷课脚本完美使用,主要是更新config.json文件,增强半自动刷客程序的扩展能力。

  • 程序流程
  1. 浏览器初始化:程序启动时,用户输入课程页面的 URL,程序初始化浏览器并加载该页面。
  2. 登录处理:程序等待用户登录(如果需要),确保在操作前能够正常访问页面。
  3. 查找按钮:用户输入一个元素的 class 参数,程序会在页面上查找包含该参数的所有按钮。如果找到按钮,程序会等待 2 秒后开始模拟点击。
  4. 按钮点击与反馈:对于找到的按钮,程序尝试点击并等待用户确认是否成功。如果按钮生效,程序会结束当前操作并继续检测下一个按钮;如果按钮点击失败,则输出失败信息。
  5. 重复检测:用户可以继续输入不同的参数进行检测,直到输入为空为止。
  6. 退出:检测完成后,程序退出浏览器并结束。
  • 程序重点

此程序是一个简单的自动化按钮点击检测工具,主要用于验证网页上的元素(按钮)是否能正常工作。用户可以通过输入 class 参数来检测指定类型的元素是否可点击,程序会模拟用户点击并反馈操作是否成功。此工具适用于自动化网页测试和元素交互验证,尤其在需要确认网页按钮功能时非常实用。可根据config.json里面相关字段进行验证,协助完成config.json里面配置项。

程序代码

  • 页面元素检测扩展工具:button_scan.py
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
import time


# 设置 Selenium 浏览器
def setup_browser(course_url):
    print(f"初始化浏览器")
    options = webdriver.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    # options.add_argument('--headless')  # 无头模式(可选,不显示浏览器界面)
    options.add_argument("--start-maximized")
    options.add_argument('--disable-gpu')  # 禁用GPU加速(可选)
    options.add_argument("--no-sandbox")
    options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")#替换自己的浏览器代理
    driver = webdriver.Chrome(options=options)

    # 打开登录页面
    driver.get(course_url)
    time.sleep(1)  # 等待页面加载
    print("初始化完毕")
    return driver

# 模拟观看视频
def simulate_video_watch(driver):
    video_info = get_video_info(driver)
    if video_info is not None:
        VIDEO_SRC = video_info['src']
        print(f"播放视频,视频时长:{video_info['duration']} 秒")
        while not video_info['ended'] and VIDEO_SRC == video_info['src']:
            if video_info['paused']:
                print("WARNING:检测到视频暂停")
                if not click_button(driver,BUTTON_PLAY):
                    print("视频重新播放失败")
                    return
            print("check:")
            print(f"      当前播放时间:{round(video_info['currentTime'], 2)}秒")
            print(f"      视频进度:{round((video_info['currentTime'] / video_info['duration']) * 100, 2)}%") if video_info['duration'] > 0 else print("      视频进度:0%")
            print("      尝试跳转至视频末尾")
            if driver.execute_script("""var video = document.querySelector('video');
                                        if (video) {
                                            video.currentTime = video.duration;
                                            return true;
                                        } else {
                                            return false;
                                        }
                                    """
                                     ):
                print("      尝试跳转完毕")
            else:
                print("      尝试跳转失败")
            time.sleep(10)  # 模拟观看视频,每10s检查视频状态
            video_info = get_video_info(driver)
        print(f"播放完毕")
        print(f"********************************")

#获取视频元素的信息
def get_video_info(driver):
    try:
    # 执行 JavaScript 获取视频元素的时长
        video_info = driver.execute_script("""
            var video = document.querySelector('video');  // 获取页面中的第一个 <video> 标签
            if (video) {
                return {
                    duration: video.duration,  // 视频时长(单位:秒)
                    currentTime: video.currentTime,  // 当前播放时间(单位:秒)
                    paused: video.paused,  // 是否暂停
                    ended: video.ended,  // 是否播放完毕
                    src: video.src    //视频地址
                };
            } else {
                return null;  // 如果没有找到视频元素,返回 null
            }
        """)

        if video_info:
            return video_info
        else:
            print("未能找到视频元素")
            return None
    except Exception as e:
        print(f"获取视频信息失败:{e}")
        return None

#查找播放按钮
def seach_video_button(driver, Type):
    print(f"查找")
    try:
        # 查找按钮
        if Type == 'play':
            play_buttons = WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located(
                (By.XPATH,
                    "//*[contains(translate(@class, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'PLAY')]"
                 )
                )
            )
        if Type == 'next':
            play_buttons = WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located(
                (By.XPATH,
                    "//button[contains(translate(text(), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'NEXT')] | "
                    "//button[contains(translate(@aria-label, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'NEXT')] | "
                    "//button[contains(translate(@data-action, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'NEXT')] | "
                    "//button[contains(translate(@class, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'NEXT')] | "
                    "//i[contains(translate(@class, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'NEXT')] | "
                    "//div[contains(translate(@class, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'NEXT')] | "
                    "//span[contains(translate(@class, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'NEXT')]"
                 )
                )
            )
            
        if not play_buttons:
            print("没有找到符合条件的按钮")
            return False
        else:
            # 输出所有找到的按钮
            print(f"共找到 {len(play_buttons)} 个按钮")
            return play_buttons
    except Exception as e:
        print(f"无法找到按钮")
        return False

#确认真正的播放按钮
def confirm_play_button(driver):
    video_info = get_video_info(driver)
    if video_info is None:
        print("无视频信息")
        return False
    buttons = seach_video_button(driver, 'play')
    if not buttons:
        return
    if video_info['ended']:
        print("视频结束")
        return
    VIDEO_STATUS = video_info['paused']
    index = 0
    while index < len(buttons):
        button = buttons[index]
        click_button(driver,button)
        video_info = get_video_info(driver)
        if VIDEO_STATUS != video_info['paused']:
            print(f"找到有效按钮!")
            time.sleep(2)
            VIDEO_STATUS = video_info['paused']
            if not video_info['paused']:
                print(f"已找到播放按钮")
                global BUTTON_PLAY
                BUTTON_PLAY = button
                #print(f"{button}")
                try:
                    attributes = ['id', 'class', 'name', 'href', 'src', 'value', 'alt', 'title']
                    for attr in attributes:
                        print(f"{attr}: {button.get_attribute(attr)}")
                    html_content = button.get_attribute("outerHTML")
                    print(f"完整 HTML: {html_content}")
                except Exception as e:
                    print(f"error:{e}")  
                return
        else:
            index += 1
        time.sleep(1)
    print(f"检索完毕")


#确认真正的下一个按钮
def confirm_next_button(driver):
    video_info = get_video_info(driver)
    if video_info is None:
        print("无视频信息")
        return False
    VIDEO_SRC = video_info['src']
    simulate_video_watch(driver)
    buttons = seach_video_button(driver, 'next')
    if not buttons:
        print("无有效button")
        return False
    attributes = ['id', 'class', 'name', 'href', 'src', 'value', 'alt', 'title']
    data = ""
    for button in buttons:
        try:
            for attr in attributes:
                data += f"{attr}: {button.get_attribute(attr)}\n"
            html_content = button.get_attribute("outerHTML")
        except Exception as e:
            print(f"error:{e}")  
        click_button(driver,button)
        time.sleep(1)
        video_info = get_video_info(driver)
        if VIDEO_SRC != video_info['src']:
            print(f"找到有效按钮!")
            BUTTON_NEXT = button
            print(f"{data}")
            print(f"完整 HTML: {html_content}")
            #print(f"{button}")
            return True
        else:
            data = ""
    print(f"检索完毕")
    return False

#点击按钮
def click_button(driver,button):
    try:
        driver.execute_script("arguments[0].click();", button)
        #print(f"成功点击{button.text}按钮")
        return True
    except Exception as e:
        print("error:无法点击按钮")
        return False

# 主程序
def main():
    course_url= input("请输入课程地址链接: \n")
    count = input("请输入检测次数:\n")
    for i in range(int(count)):
        print(f"第{i+1}次检测:")
        driver = setup_browser(course_url)
        input("若需要登陆,请登陆后按回车键继续,若不需要登录请直接按回车键继续!")
        print("开始检索播放按钮:")
        confirm_play_button(driver)
        print("开始检索切换下一个按钮:")
        confirm_next_button(driver)
        driver.quit()
        # 完成操作后退出
    print("===============================")
    print("检测结束")

# 执行主程序
if __name__ == "__main__":
    main()
  • 页面元素测试扩展工具:button_test.py
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
import time

# 设置 Selenium 浏览器
def setup_browser(course_url):
    print(f"初始化浏览器")
    options = webdriver.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    # options.add_argument('--headless')  # 无头模式(可选,不显示浏览器界面)
    options.add_argument("--start-maximized")
    options.add_argument('--disable-gpu')  # 禁用GPU加速(可选)
    options.add_argument("--no-sandbox")
    options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")#替换自己的浏览器代理
    driver = webdriver.Chrome(options=options)

    # 打开登录页面
    driver.get(course_url)
    time.sleep(1)  # 等待页面加载
    print("初始化完毕")
    return driver

#点击按钮
def click_button(driver,buttons):
    if buttons is None:
        return False
    for index,button in enumerate(buttons):
        print(f"2s后开始测试第{index + 1}个元素可行性,注意")
        time.sleep(2)
        try:
            #driver.execute_script("arguments[0].click();", button)
            button.click()
            #print(f"成功点击{button.text}按钮")
            if not input("若未生效回车继续,若生效输入任意键回车完成") == "":
                print(f"{button.get_attribute('outerHTML')}")
                return True
        except Exception as e:
            print("error:无法点击按钮")
            return False
    print("全部检索完毕")
    return False

#根据配置参数寻找页面按钮
def find_button_by_parm(driver,parm):
    if parm is None:
        return None
    try:
        buttons = WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located(
                (By.XPATH,
                 f"//*[contains(@class, '{parm}')]"
                 )
                )
            )
        print(f"共找到 {len(buttons)} 个按钮")
        print(f"按钮元素:{buttons}")
        if len(buttons) > 0:
            return buttons
        else:
            return None
    except Exception as e:
        print(f"{parm}参数按钮查找出错: {e}")
        return None

# 主程序
def main():
    course_url= input("请输入课程地址链接: \n")
    if course_url == "":
        print("链接为空,退出")
        return
    driver = setup_browser(course_url)
    input("若需要登陆,请登陆后按回车键继续,若不需要登录请直接按回车键继续!")
    while True:
        parm = input("输入要检查的元素参数:")
        if not parm:
            break
        print("2s后开始测试元素可行性,注意")
        time.sleep(2)
        if click_button(driver,find_button_by_parm(driver,parm)):
            print("检测完毕")
        else:
            print("点击失败")
    
    # 完成操作后退出
    driver.quit()
    print("===============================")
    print("检测结束")

# 执行主程序
if __name__ == "__main__":
    main()

一条评论

留言

您的邮箱地址不会被公开。 必填项已用 * 标注