您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
抖音作者页面提效
// ==UserScript== // @name 抖音作者页面复制按钮 // @namespace http://tampermonkey.net/ // @version 1.7 // @description 抖音作者页面提效 // @author You // @match https://www.douyin.com/user/* // @icon https://www.google.com/s2/favicons?sz=64&domain=douyin.com // @grant none // @license MIT // ==/UserScript== // 拦截请求 window.aggrx_collectionIDObject = {}; function aggrx_requestInterception() { // 保存原始的 open 和 send 方法 const originalOpen = XMLHttpRequest.prototype.open; const originalSend = XMLHttpRequest.prototype.send; // 重写 open 方法,记录请求信息 XMLHttpRequest.prototype.open = function (method, url, async, user, password) { this._requestInfo = { method, url }; // 保存请求的 URL 和方法 return originalOpen.apply(this, arguments); }; // 重写 send 方法,拦截响应数据 XMLHttpRequest.prototype.send = function (body) { const xhr = this; // 保存请求体数据 this._requestInfo.body = body; // 保存原始的 onreadystatechange const originalOnReadyStateChange = xhr.onreadystatechange; // 重写 onreadystatechange xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE) { const { url } = xhr._requestInfo; // 判断是否是特定接口 if (url.includes('/aweme/v1/web/aweme/post/') || url.includes('/aweme/v1/web/locate/post/')) { console.log(`Request to: ${url}`); try { const parsedResponse = JSON.parse(xhr.responseText); parsedResponse.aweme_list.forEach(item => { console.log(item); window.aggrx_collectionIDObject[`${item.desc}`] = { authorName: item.author.nickname, authorUID: item.author.uid, videoID: item.aweme_id, desc: item.desc, tag: item.text_extra }; }); } catch (e) { console.error('Error parsing response:', e); } } } // 调用原始的回调函数 if (originalOnReadyStateChange) { originalOnReadyStateChange.apply(xhr, arguments); } }; return originalSend.apply(this, arguments); }; } aggrx_requestInterception(); (function() { 'use strict'; const css = document.createElement("style"); css.type = "text/css"; css.innerText = ` #aggrx-pannel { position: fixed; top: 5px; left: calc(50% + 300px); padding: 10px; background-color: #333333; color: white; z-index: 1000; display: flex; flex-direction: column; align-content: center; justify-content: flex-start; align-items: flex-start; } #aggrx-pannel button { padding: 5px 10px; font-size: 16px; cursor: pointer; border-radius: 8px; background: transparent; color: white; border: 2px solid #cdcdcd; } .aggrx-pannel-actions{ } .aggrx-collections-container{ max-width: 550px; max-height: 100px; overflow: scroll; } .aggrx_buttonBox{ height: 40px; /*top: 1px;*/ /*margin-left: 150px;*/ position: absolute; background: transparent; /*z-index:99999*/ } .aggrx_buttonBox-author-card-list{ height: 40px; position: absolute; top: 200px; z-index:99999 } .aggrx_buttonBox_button{ background: transparent; border: 2px solid #cdcdcd; padding: 4px; color: white; margin-right: 4px; cursor: pointer; } .aggrx-toast { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background-color: #333; color: white; padding: 10px 20px; border-radius: 5px; font-size: 16px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); opacity: 0; transition: opacity 0.5s ease; z-index: 9999; /* 设置 z-index 为 9999 确保 toast 在最上层 */ } .aggrx-toast.show { opacity: 0.8; } `; document.head.appendChild(css); const pannel = document.createElement('div'); pannel.id = 'aggrx-pannel'; pannel.innerHTML = ` <div class='aggrx-pannel-actions'> <button id="aggrx-copy" style='margin-right:8px;'>复制URL</button> <button id="aggrx-collection-toggle">采集专辑</button> <button id="aggrx-collection-copy">复制采集专辑结果</button> </div> <ul id='aggrx-collections'> </ul> `; // <button id="aggrx-scan">扫描</button> document.body.appendChild(pannel); document.getElementById("aggrx-copy").addEventListener("click", function() { // 获取当前页面的 URL const currentUrl = window.location.href; const button = this; button.textContent = "复制URL"; // 将 URL 写入剪贴板 navigator.clipboard.writeText(currentUrl).then(() => { // 修改按钮文字为 "已复制" button.textContent = "已复制"; // 2秒后恢复按钮原始文字 //setTimeout(() => { // button.textContent = "复制当前URL"; //}, 2000); }).catch(err => { console.error("复制失败:", err); }); }); //document.getElementById("aggrx-scan").addEventListener("click", function() { // //}); document.getElementById("aggrx-collection-toggle").addEventListener("click", function() { aggrx_collection_reset() aggrx_scan(); }) document.getElementById("aggrx-collection-copy").addEventListener("click", function() { aggrx_collection_copy() }) })(); let aggrx_searchList = [] let aggrx_scrollListHeight = 0 let scaned = false let aggrx_author_searchList = [] let aggrx_author_scrollListHeight = 0 let author_scaned = false function aggrx_scan(){ // div[data-e2e="user-post-list"]> let el_scrolls = Array.from(document.querySelectorAll('ul[data-e2e="scroll-list"]')) if(el_scrolls.length > 0){ let el_scroll = el_scrolls[el_scrolls.length - 1] if(!scaned){ scaned = true; aggrx_observerNodeChanged(el_scroll, 'user-post-list'); } aggrx_searchList = el_scroll.querySelectorAll('li'); aggrx_scrollListHeight = aggrx_searchList[0].clientHeight + 30; aggrx_searchList.forEach((li, index) => { if (li.querySelector('div.aggrx_buttonBox')) { console.info("已经处理过了") return } aggrx_addCopyCollectionButtonDom(li,'user-post-list', 'user-douyin'); }); }else{ console.error('对应列表不存在') } // 侧边栏作者页面 // data-e2e="author-card-list" let el_author_scrolls = Array.from(document.querySelectorAll('div[data-e2e="author-card-list"] ul')) if(el_author_scrolls.length > 0){ let el_author_scroll = el_author_scrolls[el_scrolls.length - 1] if(!author_scaned){ author_scaned = true; aggrx_observerNodeChanged(el_author_scroll, 'author-card-list'); } aggrx_author_searchList = el_author_scroll.querySelectorAll('li'); aggrx_author_scrollListHeight = aggrx_author_searchList[0].clientHeight + 30; aggrx_author_searchList.forEach((li, index) => { if (li.querySelector('div.aggrx_buttonBox')) { console.info("已经处理过了") return } aggrx_addCopyCollectionButtonDom(li, 'author-card-list', 'user-douyin'); }); }else{ console.error('作者列表不存在') } } // 复制文本 function aggrx_copyToClipboard(text, copy_success, copy_failed) { navigator.clipboard.writeText(text).then(function() { console.log('copied'); if (copy_success) { copy_success(text) } }).catch(function(err) { console.error('copy failed', err); if (copy_failed) { copy_failed(err) } }); } // 添加 复制合集按钮DOM /** * @param {'author-card-list'|'user-post-list'} page_type 页面类型 */ function aggrx_addCopyCollectionButtonDom(LiElement,page_type, page_site_type) { const divBOX = document.createElement('div'); divBOX.className = 'aggrx_buttonBox'; divBOX.classList.add(`aggrx_buttonBox-author-card-list`) if(page_type === 'author-card-list'){ } //divBOX.style.width = '100%'; divBOX.style.height = '40px'; const button1 = document.createElement('button'); // button1.className = 'aggrx_buttonBox_button' button1.classList.add('aggrx_buttonBox_button'); button1.classList.add(`aggrx_buttonBox_button-${page_site_type}`); // 设置按钮的文本 button1.textContent = '视频连接'; // 设置按钮的宽度和高度 //button1.style.width = '49%'; //button1.style.height = '40px'; //button1.style.float = 'left'; function copy_success(msg) { aggrx_showToast('info', `已复制 ${msg}`) } function copy_failed(error) { aggrx_showToast('error', `复制失败 ${error}`) } // 拦截按钮的点击事件 button1.addEventListener('click', (event) => { // 阻止事件冒泡 event.stopPropagation(); if(page_type === 'user-post-list'){ // 获取父元素 const parentElement = event.target.closest('li'); let videoUrl = parentElement.querySelector('div>a').href; if (!(videoUrl.includes('www.douyin.com/video'))) { return } let title = parentElement.querySelector('div>a>p').innerText; // 使用正则表达式从 href 中提取视频 ID // copy_button_ref.textContent = "复制"; let href = new URL(videoUrl); href.search = ''; let hrefString = href.toString() //if (0) { // aggrx_copyToClipboard(`${hrefString},1`, copy_success, copy_failed) //} else { // aggrx_copyToClipboard(`${hrefString}`, copy_success, copy_failed) //} let newOrder = aggrx_collection_add(title, hrefString); }else if(page_type === 'author-card-list'){ // 获取父元素 const parentElement = event.target.closest('li'); //let videoUrl = parentElement.querySelector('div>a').href; let title = parentElement.querySelector('div>a p').innerText; let video_id = (window.aggrx_collectionIDObject[title] || {}).videoID || ''; let videoUrl = `https://www.douyin.com/video/${video_id}` if (!(videoUrl.match(/www.douyin\.com\/video\/\d+/))) { aggrx_showToast('error', `没有拦截到title:${title}对应的数据`) return } // 使用正则表达式从 href 中提取视频 ID // copy_button_ref.textContent = "复制"; let href = new URL(videoUrl); href.search = ''; let hrefString = href.toString() //if (0) { // aggrx_copyToClipboard(`${hrefString},1`, copy_success, copy_failed) //} else { // aggrx_copyToClipboard(`${hrefString}`, copy_success, copy_failed) //} let newOrder = aggrx_collection_add(title, hrefString); }else{ console.error(`不支持的 ${page_type}`) } }); divBOX.appendChild(button1); // 设置 li 元素的高度 if(page_type === 'author-card-list'){ // LiElement.style.height = `${aggrx_author_scrollListHeight}px`; }else{ LiElement.style.height = `${aggrx_scrollListHeight}px`; } LiElement.style.marginBottom = `50px`; // 添加按钮到当前 li 元素 LiElement.appendChild(divBOX); // DOMUpdated() return true } function aggrx_collection_reset(){ let listEl = document.getElementById("aggrx-collections") listEl.innerHTML = '' } function aggrx_collection_add(title, url){ let listEl = document.getElementById("aggrx-collections") let order = listEl.querySelectorAll('li').length if (order === 0){ listEl.innerHTML = `<li data-link='${url}'>${title}</li>` }else{ listEl.innerHTML = `${listEl.innerHTML}<li data-link='${url}'>${title}</li>` } return order } function aggrx_collection_copy(){ let listEl = document.getElementById("aggrx-collections") let result = [] listEl.querySelectorAll('li').forEach(li=>{ let link = li.getAttribute('data-link') result.push(link) }) let joined = result.join('|') aggrx_copyToClipboard(joined, msg=>{aggrx_showToast('info', msg);}, error=>{aggrx_showToast('error', error);}); } // 监听 列表dom function aggrx_observerNodeChanged(element, page_type) { // 监听 // const targetNode = element // document.querySelector(dom_selector); // 'div[data-e2e="user-post-list"]>ul[data-e2e="scroll-list"]' // 创建一个 MutationObserver 实例 const observer = new MutationObserver(mutationsList => { // 遍历所有的 mutations mutationsList.forEach(mutation => { // 只有子节点变动才执行 if (mutation.type !== 'childList') { return } console.info(`${mutation}`) //return // 获取所有的 li 元素 //const liElements = document.querySelectorAll('ul[data-e2e="scroll-list"] li'); // 为每个 li 元素添加按钮 mutation.addedNodes.forEach((li, index) => { // 确保每个 li 只添加一个按钮 if (li.querySelector('div.aggrx_buttonBox')) { console.info("已经处理过了") return } aggrx_addCopyCollectionButtonDom(li, page_type); }); }); }); // 配置观察器 启动观察 服务 const config = { childList: true, subtree: false }; observer.observe(targetNode, config); } function aggrx_showToast(type, message) { // 创建一个新的 toast 元素 const toast = document.createElement('div'); toast.classList.add('aggrx-toast'); toast.textContent = message; if (type === 'info') { toast.style.color = 'white' } else { toast.style.color = 'red' } // 将 toast 添加到 body document.body.appendChild(toast); // 显示 toast setTimeout(() => { toast.classList.add('show'); }, 10); // 等待一小段时间(确保元素已经插入 DOM) // 5秒后隐藏并删除 toast setTimeout(() => { toast.classList.remove('show'); // 过渡动画结束后删除 toast 元素 setTimeout(() => { toast.remove(); }, 500); // 等待过渡动画完成 }, 2000); // 5秒后消失 }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址