您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
爬取课件url
当前为
// ==UserScript== // @name 小雅爬爬爬 // @match *://ccnu.ai-augmented.com/* // @grant none // @description 爬取课件url // @license MIT // @author Yi // @version 1.0.7 // @namespace https://greasyfork.org/users/1268039 // ==/UserScript== 'use strict'; let course_resources; // 附件下载实现细节 function parseContent() { console.oldLog("::parseContent"); var download_url = 'https://ccnu.ai-augmented.com/api/jx-oresource/cloud/file_url/'; var download_list = document.getElementById("download_list"); download_list.innerHTML = '<h3 style="color:#fcbb34">课程附件清单</h3>'; for (let i in course_resources) { let file_name = course_resources[i].name; if (course_resources[i].mimetype) { fetch(download_url + course_resources[i].quote_id).then(function(response) { return response.json(); }).then(function(data) { if (data.success) { let file_url = data.data.url; // 创建一个包含链接和勾选框的容器 var file_container = document.createElement('div'); file_container.style.display = 'flex'; file_container.style.alignItems = 'center'; // 创建勾选框 var checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.style.marginRight = '10px'; // 创建链接元素 var file_info = document.createElement('a'); file_info.innerHTML = file_name; file_info.href = file_url; file_info.target = "_blank"; file_info.addEventListener('mouseover', () => { file_info.style.color = '#000'; }); file_info.addEventListener('mouseout', function() { file_info.style.color = ''; }); // 将勾选框和链接添加到容器中 file_container.appendChild(checkbox); file_container.appendChild(file_info); console.oldLog('::parse', file_name, file_url); // 将包含勾选框和链接的容器添加到下载列表 download_list.append(file_container); } }).catch(function(e) { console.oldLog('!!error', e); }); } } } function courseDownload(file_url, file_name) { getBlob(file_url, function(blob) { saveAs(blob, file_name); }) } function getBlob(file_url,cb) { let xhr = new XMLHttpRequest(); xhr.open('GET', file_url, true); xhr.responseType = 'blob'; xhr.onload = function() { if (xhr.status === 200) { cb(xhr.response); } } xhr.send(); } function saveAs(blob, file_name) { if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, file_name); } else { let link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = file_name; link.click(); window.URL.revokeObjectURL(link.href); } } window.showList = function () { var download_list = document.getElementById("download_list"); // 检查是否已经存在搜索框 var existingSearchInput = document.getElementById("searchInput"); if (!existingSearchInput) { // 如果不存在,则创建搜索框 var searchInput = document.createElement("input"); searchInput.type = "text"; searchInput.placeholder = "搜索文件名"; searchInput.id = "searchInput"; // 设置唯一的ID searchInput.addEventListener("input", function () { filterList(this.value); }); download_list.prepend(searchInput); } if (download_list.style.display == "none") { download_list.style.display = "flex"; download_list.style.overflowY = "auto"; // 添加垂直滚动条 download_list.style.maxHeight = "300px"; // 设置最大高度,根据需要调整 } else { download_list.style.display = "none"; } // 检查是否已经创建了批量下载按钮 var existingbulkDownloadButton = document.getElementById("bulkDownloadButton"); if (!existingbulkDownloadButton) { // 添加批量下载按钮 window.bulkDownloadButton = document.createElement('button'); window.bulkDownloadButton.innerHTML = '批量下载'; window.bulkDownloadButton.id = "bulkDownloadButton"; window.bulkDownloadButton.style.position = 'fixed'; // 固定在右上角 window.bulkDownloadButton.style.top = '20px'; // 调整上方位置 window.bulkDownloadButton.style.right = '20px'; // 调整右侧位置 window.bulkDownloadButton.addEventListener('click', function() { // 获取所有勾选框 var checkboxes = document.querySelectorAll("#download_list input[type='checkbox']:checked"); // 获取选中链接的文件名和链接 var selected_files = []; checkboxes.forEach(function(checkbox) { var container = checkbox.parentElement; var link = container.querySelector('a'); var file_name = link.innerHTML; var file_url = link.href; selected_files.push({ name: file_name, url: file_url }); }); // 执行批量下载 selected_files.forEach(function(file) { courseDownload(file.url, file.name); }); }); // 将批量下载按钮添加到下载列表 download_list.appendChild(window.bulkDownloadButton); } } function filterList(keyword) { keyword = keyword.toLowerCase(); // 转换为小写,便于匹配 var files = document.querySelectorAll("#download_list a"); files.forEach(function(file) { var fileName = file.innerHTML.toLowerCase(); var checkbox = file.previousSibling; // Assuming the checkbox is before the link if (fileName.includes(keyword)) { file.style.display = "block"; // 匹配到的文件显示 checkbox.style.display = "inline-block"; // 显示勾选框 } else { file.style.display = "none"; // 不匹配的文件隐藏 checkbox.style.display = "none"; // 隐藏勾选框 } }); } function add_download_button() { // 全局变量用于保存批量下载按钮 window.bulkDownloadButton = null; var down_button = document.createElement('div'); down_button.innerHTML = '<svg ondblclick="showList()" t="1680053155014" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8308" width="60px" height="60px"><path d="M389.842311 369.275391c0 0-54.207599-52.138474-127.760802-9.55461-65.813938 40.649815-54.193273 115.050316-54.193273 115.050316S61.690526 503.173984 61.690526 652.223648c3.281743 148.84091 158.777213 150.336984 158.777213 150.336984l309.799812-0.467651L386.531915 672.168909l79.646991 0.864694 0.013303-157.420309 102.108562-0.694825 0.732687 157.684322 77.813227 1.106194L530.266527 802.560632l262.197654 0c0 0 144.715963 0.148379 165.04087-141.442406 9.680477-154.855904-139.875724-185.378058-139.875724-185.378058s17.017582-229.233891-193.000666-255.367085C444.611705 201.987341 389.842311 369.275391 389.842311 369.275391z" fill="#fcbb34" p-id="8309"></path></svg><div id="download_list" style="z-index:999;backdrop-filter: blur(10px);border: 2px solid #fcbb34;border-radius: 5px;display: none;padding: 20px;flex-direction: column;align-items: flex-start;"><h3 style="color:#fcbb34">课程附件清单</h3></div></div>'; // 您的按钮HTML代码 down_button.style.position = 'fixed'; down_button.style.left = '80px'; down_button.style.bottom = '50px'; down_button.style.zIndex = '9000'; down_button.setAttribute('draggable', 'true'); // 设置按钮可拖动 var isDragging = false; // 用于标记是否正在拖动按钮 down_button.onmousedown = function(event) { isDragging = true; // 当鼠标按下时开始拖动 var shiftX = event.clientX - down_button.getBoundingClientRect().left; var shiftY = event.clientY - down_button.getBoundingClientRect().top; down_button.style.position = 'absolute'; down_button.style.zIndex = 1000; function moveAt(pageX, pageY) { down_button.style.left = pageX - shiftX + 'px'; down_button.style.top = pageY - shiftY + 'px'; } function onMouseMove(event) { if (isDragging) { // 只有在拖动时才移动按钮 moveAt(event.pageX, event.pageY); } } document.addEventListener('mousemove', onMouseMove); down_button.addEventListener('mouseup', function() { isDragging = false; // 当鼠标松开时停止拖动 document.removeEventListener('mousemove', onMouseMove); }, {once: true}); // 使用 {once: true} 使事件监听器只触发一次,避免重复绑定事件 } document.body.appendChild(down_button); } window.onload = ()=> { console.oldLog = console.log; console.log = (...data) =>{ if (data[0] == 'nodesToData') { course_resources = data[1]; console.oldLog('::', course_resources); parseContent(); } }; // 创建一个 MutationObserver 实例 const observer = new MutationObserver(function(mutationsList, observer) { // 在每次发生 DOM 变化时触发这个回调函数 for(let mutation of mutationsList) { if (mutation.type === 'childList' && mutation.target.id === 'download_list') { // 如果发生了子节点的变化,并且变化的目标是下载列表 // 重新添加搜索框和批量下载按钮 window.showList(); break; // 处理完毕后退出循环 } } }); // 配置需要观察的目标节点和观察的类型 observer.observe(document.body, { childList: true, subtree: true }); // 添加下载按钮并延迟显示 setTimeout(() => { add_download_button(); }, 2000); }; // 定义要抓取的后缀名 var extensions = [".doc", ".pdf", ".docx", ".ppt", ".pptx", ".xls", ".xlsx"]; // 创建一个元素,用于显示抓取到的 URL var list = document.createElement("div"); initializeListStyles(list); // 监听 xhr 请求,检查响应的 URL 是否符合条件 var open = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url, async, user, pass) { this.addEventListener("load", function() { // 如果 URL 包含指定的后缀名之一 for (var i = 0; i < extensions.length; i++) { if (url.includes(extensions[i])) { // 发送一个新的 xhr 请求,获取真正的下载地址 handleXhrResponse(url); break; } } }); open.call(this, method, url, async, user, pass); }; // 初始化列表样式 function initializeListStyles(element) { element.style.position = "fixed"; element.style.top = "10px"; element.style.right = "0"; element.style.width = "300px"; element.style.height = "10%"; element.style.overflow = "auto"; element.style.zIndex = "9999"; element.style.padding = "10px"; // 添加闪烁动画样式 var style = document.createElement("style"); style.textContent = ` @keyframes blink { 25% { opacity: 0; } } .blink-animation { animation: blink 1s 3 alternate; /* 持续时间1秒,总共3次,alternate表示交替进行 */ } `; document.head.appendChild(style); // 为元素添加渐变背景色 element.style.background = "linear-gradient(to right bottom, #ffc700, #ffa500)"; // 为元素添加阴影效果 element.style.boxShadow = "0 4px 8px 0 rgba(0, 0, 0, 0.2)"; // 为元素添加圆角效果 element.style.borderRadius = "10px"; // 为元素添加动画效果,悬停时放大 element.style.transition = "transform 0.3s"; element.addEventListener("mouseover", function() { element.style.transform = "scale(1.1)"; }); element.addEventListener("mouseout", function() { element.style.transform = "scale(1)"; }); element.innerHTML = "<h3><span style=\"font-family: '微软雅黑', 'Microsoft YaHei', sans-serif; font-weight: bold; font-style: italic; font-size: 16px;\">抓取到的课件</span></h3>"; // 添加 draggable 属性,可拖动 element.setAttribute("draggable", "true"); // 添加 resize 属性,可调整大小 element.style.resize = "both"; // 添加拖动事件监听器 element.addEventListener("dragstart", function(e) { // 设置拖动元素的透明度 e.target.style.opacity = "0.5"; // 设置拖动元素的 id e.dataTransfer.setData("text/plain", e.target.id); // 记录拖动元素的初始位置和鼠标的初始位置 e.target.startX = e.clientX; e.target.startY = e.clientY; e.target.offsetX = e.target.offsetLeft; e.target.offsetY = e.target.offsetTop; }); element.addEventListener("drag", function(e) { // 如果鼠标的位置有效,根据鼠标的移动距离,更新拖动元素的位置 if (e.clientX > 0 && e.clientY > 0) { e.target.style.left = e.target.offsetX + e.clientX - e.target.startX + "px"; e.target.style.top = e.target.offsetY + e.clientY - e.target.startY + "px"; } }); element.addEventListener("dragend", function(e) { // 恢复拖动元素的透明度 e.target.style.opacity = "1"; }); document.body.appendChild(element); } // 全局变量,用于存储唯一的预览链接元素 var previewLink; // 全局变量,用于标志是否有异步操作正在进行中 var isDownloading = false; function handleXhrResponse(url) { if (isDownloading) { return; // 如果已经有下载在进行中,则跳过 } isDownloading = true; // 清除之前的预览链接元素 if (previewLink) { previewLink.parentNode.removeChild(previewLink); previewLink = null; } var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.onload = function () { // 如果响应的文本中包含一个以 http 或 https 开头的 URL,将其添加到列表中 // 在此之前,先将响应的文本中的 "}}" 和引号替换为空字符串,去掉多余的符号 var text = xhr.responseText.replace("}}", "").replace(/"/g, ""); var match = text.match(/(http|https):\/\/\S+/); var titleBannerElement = document.querySelector('.common_node_content_banner h5.title'); var content; if (titleBannerElement && titleBannerElement.getAttribute('title')) { content = titleBannerElement.getAttribute('title').trim(); } else { content = titleBannerElement.textContent.trim(); } if (match) { // 如果预览链接不存在,则创建 if (!previewLink) { previewLink = document.createElement("a"); previewLink.style.color = "#40a9ff"; previewLink.style.fontFamily = "'微软雅黑', 'Microsoft YaHei', sans-serif"; previewLink.style.fontStyle = "italic"; previewLink.style.fontWeight = "bold"; // 将预览链接添加到列表中 list.appendChild(previewLink); list.appendChild(document.createElement("br")); } // 更新预览链接的属性 previewLink.href = match[0]; previewLink.target = "_blank"; previewLink.textContent = content; // 添加闪烁动画效果 list.classList.add("blink-animation"); // 设置定时器,在3秒后清除动画 setTimeout(function() { list.classList.remove("blink-animation"); }, 3000); // 添加点击事件监听器,在点击时进行下载 previewLink.addEventListener("click", function (event) { event.preventDefault(); // 阻止默认的点击行为 // 异步获取 Blob 对象 getBlob(match[0], function(blob) { // 使用自定义文件名进行下载 saveAs(blob, content); }); }); } isDownloading = false; // 将新创建的元素插入到列表的最前面 var titleElement = list.querySelector("h3"); if (titleElement) { list.insertBefore(previewLink, titleElement.nextSibling); } else { list.appendChild(previewLink); } } xhr.send(); } // 异步获取 Blob 对象的函数 function get1Blob(url) { return new Promise(resolve => { const xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.responseType = "blob"; // 请求类型是 blob 类型 xhr.crossOrigin = "*"; // 解决跨域问题 xhr.onload = () => { if (xhr.status === 200) { resolve(xhr.response); } }; xhr.send(); }); } // 下载文件并重新命名的函数 function save1As(blob, content) { if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, content); } else { const link = document.createElement("a"); const body = document.querySelector("body"); link.href = window.URL.createObjectURL(blob); link.download = content; // 修改文件名 link.style.display = "none"; body.appendChild(link); link.click(); body.removeChild(link); window.URL.revokeObjectURL(link.href); } }