您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
提取抖音用户关注的所有作者的信息,并提供复制为JSON和下载JSON的悬浮按钮
// ==UserScript== // @name 抖音关注作者信息提取器 (JSON 导出版) // @namespace http://tampermonkey.net/ // @version 1.1.4 // @description 提取抖音用户关注的所有作者的信息,并提供复制为JSON和下载JSON的悬浮按钮 // @author qqlcx5 // @match https://www.douyin.com/user/* // @icon https://www.google.com/s2/favicons?sz=64&domain=douyin.com // @grant GM_setClipboard // @run-at document-end // @license MIT // ==/UserScript== (function() { 'use strict'; /** * 存储提取到的作者信息 * Stores the extracted author information */ let authorInfoList = []; /** * 提取用户关注的所有作者信息 * Extracts all followed authors' information from the user's profile page */ function extractAuthorInfo() { // 定义关注作者列表的容器选择器 const containerSelector = 'div[data-e2e="user-fans-container"]'; const container = document.querySelector(containerSelector); if (!container) { console.warn('未找到关注作者的容器元素 (Followed authors container not found)'); return; } // 定义每个作者信息的项选择器 // 根据提供的DOM结构,每个作者的信息在 `div.i5U4dMnB` 中 const authorItems = container.querySelectorAll('div.i5U4dMnB'); if (!authorItems.length) { console.warn('未找到任何关注作者的信息项 (No followed authors found)'); return; } authorInfoList = Array.from(authorItems).map(item => { // 提取个人主页链接 const linkElement = item.querySelector('a.uz1VJwFY'); const profileUrl = linkElement ? (linkElement.href.startsWith('http') ? linkElement.href : `https:${linkElement.href}`) : 'N/A'; // 提取用户名 const nameElement = item.querySelector('a.uz1VJwFY > span > span.arnSiSbK span span span span'); const username = nameElement ? nameElement.textContent.trim() : 'N/A'; // 提取头像图片链接 const avatarImg = item.querySelector('span[data-e2e="live-avatar"] img'); const avatarUrl = avatarImg ? (avatarImg.src.startsWith('http') ? avatarImg.src : `https:${avatarImg.src}`) : 'N/A'; // 提取用户简介 const descriptionElement = item.querySelector('div.B_5R_Mpq span.arnSiSbK span span span span'); const description = descriptionElement ? descriptionElement.textContent.trim() : 'N/A'; return { username, profileUrl, avatarUrl, description }; }); console.info(`提取到 ${authorInfoList.length} 个关注作者的信息。`); } /** * 复制所有作者信息到剪贴板(JSON 格式) * Copies all author information to the clipboard in JSON format */ function copyAllAuthorInfoAsJSON() { extractAuthorInfo(); if (authorInfoList.length === 0) { alert('未提取到关注作者的信息,请确保页面已完全加载后重试。'); return; } const jsonContent = JSON.stringify(authorInfoList, null, 2); GM_setClipboard(jsonContent); notifyUser(`已复制 ${authorInfoList.length} 个作者的信息 (JSON) 到剪贴板。`); } /** * 下载所有作者信息为JSON文件 * Downloads all author information as a JSON file */ function downloadAllAuthorInfoAsJSON() { extractAuthorInfo(); if (authorInfoList.length === 0) { alert('未提取到关注作者的信息,请确保页面已完全加载后重试。'); return; } const jsonContent = JSON.stringify(authorInfoList, null, 2); const blob = new Blob([jsonContent], { type: 'application/json;charset=utf-8;' }); const url = URL.createObjectURL(blob); const timestamp = new Date().toISOString().replace(/[:.-]/g, ''); const filename = `douyin_followed_authors_${timestamp}.json`; const link = document.createElement("a"); link.href = url; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); // 释放URL对象 URL.revokeObjectURL(url); notifyUser(`已生成并下载 ${authorInfoList.length} 个作者的信息 (JSON)。`); } /** * 创建并添加悬浮复制和下载按钮到页面 * Creates and adds floating copy and download buttons to the page */ function createFloatingButtons() { // 创建容器 const container = document.createElement('div'); container.id = 'author-info-buttons-container'; Object.assign(container.style, { position: 'fixed', right: '20px', bottom: '110px', display: 'flex', flexDirection: 'column', gap: '10px', zIndex: '10000' }); // 创建复制按钮 const copyButton = document.createElement('button'); copyButton.id = 'copy-author-info-btn'; copyButton.textContent = '复制为JSON'; Object.assign(copyButton.style, { padding: '10px 15px', backgroundColor: '#52c41a', color: '#fff', border: 'none', borderRadius: '5px', boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)', cursor: 'pointer', fontSize: '14px', transition: 'background-color 0.3s, transform 0.3s', width: '150px' }); // 创建下载按钮 const downloadButton = document.createElement('button'); downloadButton.id = 'download-author-info-btn'; downloadButton.textContent = '下载为JSON'; Object.assign(downloadButton.style, { padding: '10px 15px', backgroundColor: '#1890FF', color: '#fff', border: 'none', borderRadius: '5px', boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)', cursor: 'pointer', fontSize: '14px', transition: 'background-color 0.3s, transform 0.3s', width: '150px' }); // 鼠标悬停效果(复制按钮) copyButton.addEventListener('mouseenter', () => { copyButton.style.backgroundColor = '#73d13d'; copyButton.style.transform = 'scale(1.05)'; }); copyButton.addEventListener('mouseleave', () => { copyButton.style.backgroundColor = '#52c41a'; copyButton.style.transform = 'scale(1)'; }); // 鼠标悬停效果(下载按钮) downloadButton.addEventListener('mouseenter', () => { downloadButton.style.backgroundColor = '#40a9ff'; downloadButton.style.transform = 'scale(1.05)'; }); downloadButton.addEventListener('mouseleave', () => { downloadButton.style.backgroundColor = '#1890FF'; downloadButton.style.transform = 'scale(1)'; }); // 点击事件(复制按钮) copyButton.addEventListener('click', copyAllAuthorInfoAsJSON); // 点击事件(下载按钮) downloadButton.addEventListener('click', downloadAllAuthorInfoAsJSON); // 添加按钮到容器 container.appendChild(copyButton); container.appendChild(downloadButton); // 添加容器到页面主体 document.body.appendChild(container); } /** * 显示提示通知给用户 * Displays a notification to the user * @param {string} message - 要显示的消息 (Message to display) */ function notifyUser(message) { // 创建通知元素 const notification = document.createElement('div'); notification.textContent = message; // 样式设计 (Styling) Object.assign(notification.style, { position: 'fixed', bottom: '220px', right: '20px', backgroundColor: '#333', color: '#fff', padding: '10px 15px', borderRadius: '5px', opacity: '0', transition: 'opacity 0.5s', zIndex: '10000', fontSize: '13px', maxWidth: '300px', wordWrap: 'break-word' }); document.body.appendChild(notification); // 触发动画 setTimeout(() => { notification.style.opacity = '1'; }, 100); // Slight delay to allow transition // 自动淡出和移除 setTimeout(() => { notification.style.opacity = '0'; setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 500); // 等待淡出完成 }, 3000); // 显示3秒 } /** * 初始化脚本 * Initializes the userscript */ function initializeScript() { createFloatingButtons(); console.info('抖音关注作者信息提取器 (JSON 导出版) 已启用。'); } // 等待页面内容加载完毕后初始化脚本 // Wait for the DOM to be fully loaded before initializing if (document.readyState === 'complete' || document.readyState === 'interactive') { initializeScript(); } else { document.addEventListener('DOMContentLoaded', initializeScript); } })();