您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
樊登所有听书信息导出 json。(打造自己读书阅读网站)
// ==UserScript== // @name 樊登提取器(简洁版) // @namespace http://tampermonkey.net/ // @version 1.0.5 // @description 樊登所有听书信息导出 json。(打造自己读书阅读网站) // @author qqlcx5 // @match https://www.dushu365.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=dushu365.com // @grant GM_setClipboard // @run-at document-end // @license MIT // ==/UserScript== ;(function () { 'use strict' /** * 提取所有卡片的信息 * Extracts information from all cards */ function extractAllCardsInfo() { // 选择所有卡片的容器 const cards = document.querySelectorAll('a.css-o3rmpk') if (cards.length === 0) { console.warn('未找到卡片信息 (No cards found)') return } // 存储所有卡片的信息 const allCardsInfo = [] cards.forEach((card) => { // 提取封面图片URL const coverImg = card.querySelector('.chakra-image.css-cquex') const coverUrl = coverImg ? coverImg.src : null // 提取标题 const titleElement = card.querySelector('.css-fekyw2') const title = titleElement ? titleElement.textContent.trim() : null // 提取副标题(介绍) const subtitleElement = card.querySelector('.css-10uyroi') const subtitle = subtitleElement ? subtitleElement.textContent.trim() : null // 提取上新日期 const dateElement = card.querySelector('.css-bokfi4') const date = dateElement ? dateElement.textContent.trim() : null // 提取播放量 const playCountElement = card.querySelector('.css-166fvu2') const playCount = playCountElement ? playCountElement.textContent.trim() : null // 提取 <a> 标签的 href 属性 const href = card.getAttribute('href') // 拼接完整的 source URL const source = href ? `https://www.dushu365.com${href}` : null // 将提取的信息存储为对象 const cardInfo = { coverUrl, title, subtitle, date, playCount, source, // 添加 source 属性 } allCardsInfo.push(cardInfo) }) // 根据 playCount 进行排序 allCardsInfo.sort((a, b) => { const aCount = parsePlayCount(a.playCount) const bCount = parsePlayCount(b.playCount) return bCount - aCount }) console.info('提取到的所有卡片信息:', allCardsInfo) // 导出信息为JSON格式 const jsonInfo = JSON.stringify(allCardsInfo, null, 2) console.info('导出的JSON信息:', jsonInfo) // 将信息复制到剪贴板 GM_setClipboard(jsonInfo) notifyUser('所有卡片信息已复制到剪贴板。') } /** * 解析 playCount 字符串为数字 * Parses the playCount string into a number * @param {string} playCount - 播放次数字符串 (Play count string) * @returns {number} - 解析后的数字 (Parsed number) */ function parsePlayCount(playCount) { if (!playCount) return 0 // 处理 "播放量" 的情况 if (playCount.includes('播放量')) { const count = parseFloat(playCount.replace('播放量', '').replace('万', '')) * 10000 return count } return 0 } /** * 显示提示通知给用户 * 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: '80px', right: '20px', backgroundColor: '#333', color: '#fff', padding: '10px 15px', borderRadius: '5px', opacity: '0', transition: 'opacity 0.5s', zIndex: '10000', fontSize: '13px', }) document.body.appendChild(notification) // 触发动画 setTimeout(() => { notification.style.opacity = '1' }, 100) // Slight delay to allow transition // 自动淡出和移除 setTimeout(() => { notification.style.opacity = '0' setTimeout(() => { document.body.removeChild(notification) }, 500) // 等待淡出完成 }, 3000) // 显示3秒 } /** * 自动滚动到页面底部 * Automatically scrolls to the bottom of the page */ function autoScrollToBottom() { // 监听页面内容的变化 const observer = new MutationObserver(() => { // 滚动到页面底部 window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth', // 平滑滚动 }) }) // 配置观察选项:监听子节点的变化 const config = { childList: true, subtree: true, } // 开始观察页面主体 observer.observe(document.body, config) // 初始滚动到底部 window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth', }) } /** * 初始化脚本 * Initializes the userscript */ function initializeScript() { // 创建一个按钮来触发信息提取 const button = document.createElement('button') button.textContent = '提取所有卡片信息' // 样式设计 (Styling) Object.assign(button.style, { position: 'fixed', right: '20px', bottom: '100px', padding: '12px 20px', backgroundColor: '#FF4D4F', color: '#fff', border: 'none', borderRadius: '8px', boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)', cursor: 'pointer', fontSize: '14px', zIndex: '10000', transition: 'background-color 0.3s, transform 0.3s', }) // 鼠标悬停效果 (Hover Effects) button.addEventListener('mouseenter', () => { button.style.backgroundColor = '#FF7875' button.style.transform = 'scale(1.05)' }) button.addEventListener('mouseleave', () => { button.style.backgroundColor = '#FF4D4F' button.style.transform = 'scale(1)' }) // 点击事件 (Click Event) button.addEventListener('click', extractAllCardsInfo) // 添加按钮到页面主体 (Append button to the body) document.body.appendChild(button) console.info('卡片信息提取脚本已启用。') // 启动自动滚动 autoScrollToBottom() } // 等待页面内容加载完毕后初始化脚本 // Wait for the DOM to be fully loaded before initializing if (document.readyState === 'complete' || document.readyState === 'interactive') { initializeScript() } else { document.addEventListener('DOMContentLoaded', initializeScript) } })()