当前位置: 首页 > news >正文

浏览器书签脚本(书签小程序)学习

背景:刷课时发现视频无法自动连播,需要手动调整,很麻烦

发现对于 URL 包含序号参数(如https://xxx.cn/study/0/381/24770992)的视频页面,实现自动连播的核心是识别参数规律并在视频结束时自动跳转

我的课程是最后一段数字是视频 ID,每次 + 1。

浏览器书签脚本(简单快捷)

  1. 外观: 它看起来和普通书签一样,在你的书签栏上有一个标题和一个图标。

  2. 本质: 它的网址(URL)不是以 http:// 或 http:// 开头,而是以 javascript: 开头。后面跟着一段可执行的JavaScript代码。

  3. 工作原理: 当你点击这个书签时,浏览器不会跳转到新页面,而是会把你当前正在浏览的网页作为“沙盒”,在这片“沙盒”里运行那段JavaScript代码。

书签脚本的主要用途

书签脚本的用途非常广泛,以下是一些常见的例子:

  • 网页调试与开发:

    • 显示所有元素的边框,方便查看布局。

    • 一键清除页面上的所有Cookie和本地存储。

    • 将页面切换到响应式设计预览模式。

  • 内容提取与处理:

    • 一键去除页面广告和浮动元素,获得干净的阅读视图。

    • 提取页面上的所有链接、图片或电子邮件地址。

    • 将文章内容发送到Kindle或稍后读应用(如Pocket)。

  • 界面增强:

    • 为没有暗色模式的网站强制启用暗色主题。

    • 调整页面的字体和行距,使其更易于阅读。

    • 自动展开被折叠的评论区或“”内容。

  • 实用工具:

    • 生成当前页面的二维码,方便在手机上浏览。

    • 将选中的文本直接翻译成其他语言。

    • 快速进行搜索引擎切换(如在Google和百度之间切换当前搜索关键词)。

如何创建和使用?

  1. 在浏览器中打开书签管理器。(通常是按 Ctrl+Shift+O 或 Cmd+Shift+O

  2. 添加一个新书签。

  3. 在“名称”字段中,填写一个你容易识别的名字,例如“视频自动连播”。

     4.在“网址”或“URL”字段中,粘贴完整的以 javascript: 开头的代码。

​
javascript:(function(){// 解析当前URL,提取最后一段数字(视频ID)const parts = window.location.href.split('/');const lastPart = parts[parts.length - 1];const currentId = parseInt(lastPart);if (!isNaN(currentId)) {// 计算下一个视频ID(根据实际规律调整,这里假设+1)const nextId = currentId + 1;// 替换URL中的ID并跳转parts[parts.length - 1] = nextId;const nextUrl = parts.join('/');// 延迟3秒跳转(预留视频结束缓冲时间,可调整)setTimeout(() => window.location.href = nextUrl, 3000);} else {alert('未识别到视频序号参数');}
})();​

问题:

原因:浏览器对书签中 JavaScript 代码的格式要求比较严格,需要确保代码是一个完整、紧凑的 JavaScript 语句,不能有多余的注释、换行等影响格式的内容。

把之前的代码进行压缩,去除不必要的注释和换行,确保代码是连续的。比如将代码修改为:

javascript:(function(){const parts=window.location.href.split('/');const lastPart=parts[parts.length-1];const currentId=parseInt(lastPart);if(!isNaN(currentId)){const nextId=currentId+1;parts[parts.length-1]=nextId;const nextUrl=parts.join('/');setTimeout(()=>window.location.href=nextUrl,3000);}else{alert('未识别到视频序号参数');}})();

        5.保存,然后将这个新书签拖到书签栏上方便点击的位置。

bug:

一运行代码就从24770992 跳到本页面第一个视频24770884 

问题分析与解决方案

为什么从 24770992 跳到了 24770884?

根本原因在于你的代码逻辑的一个关键假设是错误的

假设:代码假设视频ID是连续递增的,即下一个视频的ID严格等于当前视频ID + 1。
现实:在你使用的这个网站上,视频ID并不是连续排列的

从 24770992 到 24770884,ID实际上是减小了,而且跳跃幅度很大。这说明视频ID的生成可能依赖于数据库的自增主键、时间戳或其他复杂逻辑,它们在线性顺序上是不连续的

因此,当你试图访问一个不存在的 24770993 页面时,网站服务器可能没有返回404错误,而是执行了某种默认的重定向逻辑,比如:

  • 跳转到课程的第一个视频(24770884)。

  • 跳转到课程的介绍页面。

  • 跳转到404页面。

方案:如果网站有播放列表API(进阶)

如果是比较规范的网站,可能会通过API加载播放列表。你可以尝试在开发者工具的 Network(网络)面板中查找包含播放列表的请求,然后编写代码来解析它,找到当前视频在列表中的位置,然后获取下一个视频的URL。这种方法更复杂,但也更强大和精确。

    • 网络请求列表中,寻找包含以下关键词的请求:

      • list

      • course

      • chapter

      • playlist

      • curriculum

      • menu

    • 重点关注类型为 XHR 或 Fetch 的请求。

    • 点击这些请求,在 Preview 或 Response 标签页中查看返回的数据,确认是否包含视频列表。

  1. 分析API响应

    • 找到包含视频数组的API,数据结构通常如下:

    json

    {"data": {"sections": [{"lessons": [{"id": 24770884, "title": "第一章", "url": "/course/0/381/24770884"},{"id": 24770992, "title": "第二章", "url": "/course/0/381/24770992"},{"id": 24771015, "title": "第三章", "url": "/course/0/381/24771015"}]}]}

第二步:获取API详细信息

当你找到正确的API后:

  1. 复制API地址

    • 在 Headers 标签页中,找到 Request URL,这就是API端点。

  2. 查看请求方法

    • 通常是 GET 或 POST

  3. 查看必要的请求头

    • 有些API需要认证,检查 Headers 中的 AuthorizationCookie 等。

第三步:编写智能连播脚本

基于找到的API信息,这里是一个通用模板:

javascript: (function() {// 配置区:根据你找到的API信息修改这里const API_URL = 'https://api.example.com/course/381/lessons'; // 替换为实际的API URLconst REQUEST_METHOD = 'GET'; // 或 'POST'const NEED_AUTH = true; // 如果API需要认证就设为true// 获取当前页面URL用于匹配const currentUrl = window.location.href;// 显示加载状态const loadingMsg = document.createElement('div');loadingMsg.style.cssText = 'position:fixed; top:20px; right:20px; background:#000; color:#fff; padding:10px; z-index:9999;';loadingMsg.textContent = '📡 获取播放列表中...';document.body.appendChild(loadingMsg);// 准备请求配置const requestConfig = {method: REQUEST_METHOD,headers: {'Content-Type': 'application/json'}};// 如果需要认证,添加认证头if (NEED_AUTH) {// 这里会自动使用当前登录状态的cookie}// 调用API获取播放列表fetch(API_URL, requestConfig).then(response => {if (!response.ok) {throw new Error(`API请求失败: ${response.status}`);}return response.json();}).then(data => {loadingMsg.textContent = '✅ 列表获取成功,解析中...';// 解析函数 - 需要根据实际的API响应结构进行调整function parseVideoList(data) {// 示例1:扁平化结构if (data.data && Array.isArray(data.data.lessons)) {return data.data.lessons;}// 示例2:嵌套章节结构if (data.data && Array.isArray(data.data.sections)) {const allLessons = [];data.data.sections.forEach(section => {if (section.lessons && Array.isArray(section.lessons)) {allLessons.push(...section.lessons);}});return allLessons;}// 示例3:直接数组if (Array.isArray(data.lessons)) {return data.lessons;}throw new Error('无法解析播放列表结构');}const videoList = parseVideoList(data);// 在当前列表中查找当前视频const findCurrentVideo = () => {// 方法1:通过URL匹配for (let i = 0; i < videoList.length; i++) {if (videoList[i].url && currentUrl.includes(videoList[i].url)) {return i;}}// 方法2:通过ID匹配(需要从当前URL提取ID)const currentId = currentUrl.split('/').pop();for (let i = 0; i < videoList.length; i++) {if (videoList[i].id == currentId || (videoList[i].url && videoList[i].url.includes(currentId))) {return i;}}return -1;};const currentIndex = findCurrentVideo();if (currentIndex === -1) {loadingMsg.textContent = '❌ 未在当前课程中找到本视频';setTimeout(() => loadingMsg.remove(), 3000);return;}// 检查是否有下一个视频if (currentIndex < videoList.length - 1) {const nextVideo = videoList[currentIndex + 1];loadingMsg.textContent = `⏭️ 3秒后跳转到: ${nextVideo.title || '下一节'}`;// 3秒后跳转setTimeout(() => {let nextUrl = nextVideo.url || nextVideo.link;// 确保URL是完整的if (nextUrl && !nextUrl.startsWith('http')) {const baseUrl = window.location.origin;nextUrl = baseUrl + (nextUrl.startsWith('/') ? '' : '/') + nextUrl;}if (nextUrl) {window.location.href = nextUrl;} else {loadingMsg.textContent = '❌ 无法获取下一视频链接';setTimeout(() => loadingMsg.remove(), 3000);}}, 3000);} else {loadingMsg.textContent = '🎉 已经是最后一节课程了!';setTimeout(() => loadingMsg.remove(), 3000);}}).catch(error => {console.error('错误:', error);loadingMsg.textContent = `❌ 错误: ${error.message}`;setTimeout(() => loadingMsg.remove(), 5000);});
})();

配置说明

  1. 修改API_URL:替换成你找到的实际API地址

  2. 调整parseVideoList函数:根据API实际返回的数据结构修改解析逻辑

  3. 设置NEED_AUTH:如果API需要登录,设为true

  4. 调整findCurrentVideo逻辑:确保能准确匹配当前视频

最后:智能探测方案部分视频成功

大部分失败  放弃了

http://www.dtcms.com/a/487268.html

相关文章:

  • 网站营销单页怎么设计方案怎样做视频网站
  • ComfyUI部署以及节点扩展
  • CentOS部署Docker容器
  • centOS防火墙操作
  • 个人网站建设规划app展示网站模板
  • 做网站意义和目的阿里云服务器做电影网站
  • 建设网站公司有哪些小程序推广联盟
  • 百度做网站哪里可以学动态小网站
  • android 限定符屏幕适配 根据屏幕尺寸适配不同layout文件夹
  • 【华为OD机试】投篮大赛 100分
  • 厦门网站建设人才浙江省住房和城乡建设厅成绩查询
  • 产品展示型网站有哪些公司网站注意事项
  • python物理模拟:描述波动、振动和旋转系统
  • osg项目运行时关于gl.h错误的问题及解决方法
  • 购物网站首页模板下载做模板下载网站挣钱吗
  • 免费源码网站好用的免费网站源码网站有哪些
  • 小朋友做安全教育的网站开发一款app的公司
  • LeetCode 面试经典 150_区间_用最少数量的箭引爆气球(51_452_C++_中等)(求交集)(sort() 以第二个进行排序)
  • 老干局网站建设方案手机网站图片自适应
  • 云南省建设厅网站舉報软件开发赚钱吗
  • 增强现实:制造业的变革力量
  • 网站虚拟主机建设找人做个网站多少钱
  • 树突状细胞(DC)和巨噬细胞 gvl
  • 【系统分析师】写作框架:信息系统开发方法论
  • 如何仿做网站万网老板是谁
  • SpringCloud系列(52)--SpringCloud Sleuth简介
  • 2025年10月15日第一批一战复旦
  • Xshell效率实战:SSH管理秘籍
  • (一) Dotnet使用MCP的Csharp SDK
  • 网银网站模板网站开发实训报告总结