// ==UserScript== // @name 2025最新可用-百度网盘不限制下载-神速Down(支持整个文件夹下载) // @namespace https://github.com/AFANOOO/sspan // @version 9.9.3 // @icon https://s2.loli.net/2025/04/19/dwVq7tx9NBgvfaz.png // @author GreasyFork // @description 2025持续更新可用的.不限制速度文件夹下载的百度网盘解析脚本,无视黑号,拥有IDM/Aria2/Motrix三种方式任意体验极速下载!支持Microsoft Edge、Google Chrome、Firefox等浏览器 面向所有网友免费交流学习使用,更多功能正在完善中... // @antifeature ads // @antifeature membership // @antifeature tracking // @license MIT // @match *://pan.baidu.com/* // @match *://yun.baidu.com/* // @match *://pan.baidu.com/disk/main* // @match *://yun.baidu.com/disk/main* // @match *://pan.baidu.com/s/* // @match *://yun.baidu.com/s/* // @match *://pan.baidu.com/share/* // @match *://yun.baidu.com/share/* // @homepage https://ass.sshezu.cn // @supportURL https://ass.sshezu.cn // @connect localhost // @connect 127.0.0.1 // @connect baidu.com // @connect * // @require https://lib.baomitu.com/jquery/3.7.1/jquery.js // @require https://lib.baomitu.com/layui/2.9.3/layui.min.js // @require https://lib.baomitu.com/limonte-sweetalert2/11.10.2/sweetalert2.all.min.js // @require https://lib.baomitu.com/layui/2.9.3/layui.js // @resource customCSS https://lib.baomitu.com/layui/2.9.3/css/layui.css // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_getResourceText // @run-at document-idle // @grant unsafeWindow // @connect oa.assco.cn // @connect jiexi.ssoos.cc // @connect pro.ssoos.cc // ==/UserScript== ;(async function () { if (window.top !== window) return if (location.href.indexOf('yun.baidu.com') > -1) { location.href = location.href.replace('yun.baidu.com', 'pan.baidu.com') return } const closepng = 'https://s2.loli.net/2025/04/19/ePHoOl3tz2YyIUr.png' const errorpng = 'https://s2.loli.net/2025/04/19/XPJUvmpOQdGc9lB.png' const css = GM_getResourceText('customCSS') GM_addStyle(css) if (!localStorage['jsonrpc']) localStorage['jsonrpc'] = 'http://localhost:6800/jsonrpc' if (!localStorage['savePath']) localStorage['savePath'] = 'D:\\SSDOWN' $('head').append(``) $('body').append( ``, ) async function fetchFolderPage(dir, page = 1) { try { const res = await fetch(`https://pan.baidu.com/api/list?clienttype=0&app_id=250528&web=1&order=time&desc=1&num=100&dir=${encodeURIComponent(dir)}&page=${page}`) const json = await res.json() if (json.errno !== 0) { console.error(`❌ 错误获取目录 ${dir}:`, res, json) return [] } return json.list || [] } catch (err) { console.error(`⚠️ 网络错误: ${dir} page ${page}:`, err.message) return [] } } async function fetchAllInFolder(dir) { let allItems = [] let page = 1 let hasMore = true while (hasMore) { const items = await fetchFolderPage(dir, page) if (items.length === 0) break allItems.push(...items) hasMore = items.length === 100 page++ } return allItems } async function collectAllFiles(files) { const allFiles = [] async function recurse(file) { const files = await fetchAllInFolder(file.path) for (const file of files) { if (file.isdir == 1) { await recurse(file) } else { allFiles.push(file) } } } for (const file of files) { if (file.isdir == 1) { await recurse(file) } else { allFiles.push(file) } } return allFiles } async function getSelectedList() { const selectedList = document.querySelector('.wp-s-core-pan').__vue__.selectedList return await collectAllFiles(selectedList) } function request(url, type = 'byte') { return new Promise((resolve) => { GM_xmlhttpRequest({ method: 'GET', url, responseType: 'arraybuffer', onload: function (response) { if (response.status === 200) { if (type != 'byte') { resolve(response.responseText) return } var arr = new Uint8Array(response.response) resolve(arr) } else { resolve() } }, onerror: function (error) { resolve() }, }) }) } const isNPage = function () { if (document.location.href.indexOf('.baidu.com/disk/main') > 0) { return true } return false } const isSharePage = function () { let pathurl = document.location.pathname.replace('/disk/', '') if (/^\/(s|share)\//.test(pathurl)) { return true } return false } const getCurType = function () { if (isNPage()) return 'new' if (isSharePage()) return 'share' return '' } const curType = getCurType() const copy = (text) => { const el = document.createElement('textarea') el.value = text document.body.appendChild(el) el.select() document.execCommand('copy') document.body.removeChild(el) } setInterval(function () { if ($('.layui-layer-close2').length > 0) $('.layui-layer-close2').html(``) }, 100) async function init(count = 0) { let sc = await request(`https://oa.assco.cn/old.json?t=${Math.random()}`) if (!sc) { if (count > 5) throw new Error('获取配置文件失败') return await init(count + 1) } var arr = new Uint8Array(sc) var decoder = new TextDecoder('utf-8') var stringData = decoder.decode(arr) sc = JSON.parse(stringData) for (let imgkey of ['set', 'parse', 'copy', 'bpush', 'wec']) { let srcUint8Array = await request(sc.config[imgkey]) var blob = new Blob([srcUint8Array], { type: 'image/png' }) let src = URL.createObjectURL(blob) sc.config[imgkey] = src } sc.config.proUrl = sc.config.proUrl ?? 'https://pro.ssoos.cc' sc.config.commonUrl = sc.config.commonUrl ?? 'https://http://jiexi.ssoos.cc' sc.config.version = sc.config.version ?? '0.0.0' localStorage.setItem('ssdown_version', sc.config.version) sc.config.updateUrl = sc.config.updateUrl ?? '' sc.config.ad = sc.config.ad ?? '' // sc.config.proUrl = 'http://localhost:8000' // sc.config.commonUrl = 'http://localhost:8000' localStorage.setItem('ssdown_hotfix1', true) return sc } let SCONFIG try { SCONFIG = await init() } catch (error) { Swal.fire({ title: '系统提示', html: '
获取配置文件失败,有以下几种可能:
1.等待脚本初始化完成后再操作,可尝试刷新页面‌
2.你当前的地区屏蔽(例如江苏)或代理无法访问
3.服务器被攻击导致服务崩溃暂时无法提供服务
4.可以尝试点击“神速Home”更新当前插件
', icon: 'error', }) console.error('获取配置文件失败', error) } console.log('SCONFIG', SCONFIG) async function getUsername() { let res = await fetch('https://pan.baidu.com/rest/2.0/membership/user/info?method=query&clienttype=0&app_id=250528') res = await res.json() return res?.user_info?.username } const USERNAME = await getUsername() console.log('USERNAME', USERNAME) switch (curType) { case 'share': $('.x-button-box') .eq(0) .prepend( '神速Down', ) $('#downbtn1').click(function () { Swal.fire({ title: '系统提示', html: '保存文件后到自己网盘内选择文件后使用 [神速Down]', icon: 'error', }) }) break case 'new': $('.wp-s-agile-tool-bar__header.is-header-tool') .prepend( '
', ) .prepend( '
', ) break default: return } let selectedItems = [] $('#downbtn').click(async function () { // 检查更新 if (SCONFIG.config.version !== GM_info.script.version) { Swal.fire({ title: '系统提示', html: '当前版本过老,请更新后使用呀 [神速Down]', icon: 'error', showCancelButton: true, confirmButtonText: '去更新', cancelButtonText: '稍后更新', preConfirm: () => { if (!SCONFIG.config.updateUrl || SCONFIG.config.updateUrl === '') { Swal.fire({ title: '系统提示', html: '获取更新链接失败', icon: 'error', }) } window.open(SCONFIG.config.updateUrl) }, }) return } layer.closeAll('loading') $('#loadingtext').hide() const readed = localStorage.readed ?? false if (!readed) { const result = await Swal.fire({ icon: 'info', html: `

首次使用声明

欢迎使用本项目!请阅读并同意以下声明:

本项目不会存储您的共享链接与提取密码,仅用于获取文件列表。(如不放心,您可以使用后取消或修改提取密码)

仅用于个人研究学习使用,请勿违法用处,否则后果自负!(请勿解析黄色文件,以及其他违法文件,一旦发现禁用IP地址+禁用授权密钥公布使用者QQ)

`, showCancelButton: true, confirmButtonText: '✓ 同意', cancelButtonText: '× 不同意', allowOutsideClick: false, allowEscapeKey: false, preConfirm: () => { const inputValue = document.getElementById('agreeInput').value.trim() if (inputValue !== '我同意') { Swal.showValidationMessage('请输入 “我同意” 才能继续') return false } localStorage.readed = true }, }) if (!result.isConfirmed) return } Swal.fire({ title: '获取文件信息中...', allowOutsideClick: false, allowEscapeKey: false, showConfirmButton: false, }) layer.closeAll('loading') $('#loadingtext').hide() selectedItems = await getSelectedList() const selectedFsIds = selectedItems.map((item) => item.fs_id) console.log('selectedItems', selectedItems) console.log('selectedFsIds', selectedFsIds) Swal.close() if (selectedFsIds.length === 0) { Swal.fire({ showConfirmButton: true, title: '系统提示', html: '请选择需要下载的文件', icon: 'error', }) return } const htmlcode = `

当前文件

加载中...

扫一扫不失联

发送 免费白嫖

四个字获取暗号/测试程序

IDM

选项 ->下载->用户代理(UA) ->填入复制UA的内容-在IDM新建任务,粘贴链接即可。


Aria2/Motrix

点击 推送到 Aria2(Motrix)将自动下载,支持Windows/MAC客户端需要手动设置保存路径。

` layer.open({ type: 1, closeBtn: 2, title: '', shadeClose: true, area: ['850px', '600px'], content: htmlcode, success: function () { $('.layui-layer-close2').html(` 神速Down·Home

当该项目无法正常运行/或无法打开脚本可通过下方地址更新:

官网:sswpdd.xyz/doc/doc.html

GitHub:https://github.com/AFANOOO/sspan

防失联群组:TG群组

`, icon: 'info', showCancelButton: false, confirmButtonText: '我知道了', // preConfirm: () => { // if (!SCONFIG.config.updateUrl || SCONFIG.config.updateUrl === '') { // Swal.fire({ // title: '系统提示', // html: '获取更新链接失败', // icon: 'error', // }) // } // window.open(SCONFIG.config.updateUrl) // }, }) }) function getPassword() { return localStorage.password ?? null } function getServersUrl() { const password = getPassword() if (!password || password.length <= 4) return SCONFIG.config.commonUrl return SCONFIG.config.proUrl } async function updatePassword(message, selectedItems, selectedFsIds) { $('#loadingtext').hide() const tips = layui.layer.open({ type: 1, title: '', area: ['600px', '470px'], content: '
' + '' + '
' + message + '
' + '
' + '' + '
' + '
', success: function () { $('#subanhao').click(function () { if (!$(this).prev().val()) { layer.msg('请输入暗号') return false } $('#loadingtext').show() localStorage.password = $(this).prev().val() layui.layer.close(tips) $('.demo').hide() layer.load(2, { shade: [0.3, '#FFF'], }) $('#loadingtext').show() getDownloadLinks(selectedItems, selectedFsIds) }) }, cancel: function () { layer.closeAll('loading') $('#loadingtext').hide() }, }) } // 所有下载链接 let links = [] function chunkBySize(arr, maxSize = 20 * 1024 * 1024 * 1024, maxItems = 10) { const result = [] let currentChunk = [] let currentSize = 0 for (const item of arr) { // 如果当前块已满(达到 maxItems),或者加上当前 item 后超出 maxSize,则新建一个块 if (currentChunk.length >= maxItems || currentSize + item.size > maxSize) { result.push(currentChunk) currentChunk = [] currentSize = 0 } currentChunk.push(item) currentSize += item.size } if (currentChunk.length > 0) { result.push(currentChunk) } return result.filter((item) => item.length > 0) } function generateRandomRequestId() { // 生成一个16位的随机字符串 return Math.random().toString(36).substr(2, 16) } function makeRequest(url, requestData, retries = 5) { const requestId = generateRandomRequestId() // 生成 request_id requestData['request_id'] = requestId // 添加 request_id const originRetries = retries return new Promise((resolve, reject) => { function sendRequest() { GM_xmlhttpRequest({ method: 'POST', url, data: JSON.stringify(requestData), headers: { 'Content-Type': 'application/json' }, onload: (res) => { if (!res.response || res.response === '') { setTimeout(() => { sendRequest() }, 10 * 1000) } else { let json = JSON.parse(res.response) if (json.message.includes('处理中')) { setTimeout(() => { sendRequest() }, 10 * 1000) } else { resolve(res) } } }, onerror: (err) => { if (retries > 0) { retries-- console.log(`Request failed, retrying... (${retries}/${originRetries})`) setTimeout(() => { sendRequest() // 递归调用进行重试 }, 1000) } else { reject(err) // 超过最大重试次数,拒绝 Promise } }, }) } sendRequest() // 初次发起请求 }) } async function getDownloadLinks(selectedItems, selectedFsIds) { layer.load(2, { shade: [0.3, '#FFF'], }) $('#loadingtext').text('') $('#loadingtext').show() $('#copy').addClass('layui-btn-disabled') $('#pusharia').addClass('layui-btn-disabled') $('#copyUa').addClass('layui-btn-disabled') const pwd = 'zzzz' $('#loadingtext').text('正在分享文件...') const htmlString = $('html').html() const regex = /"bdstoken":"(\w+)"/ const match = regex.exec(htmlString) const bdstoken = match ? match[1] : null if (!bdstoken) throw new Error('未能获取 bdstoken,请刷新页面重试') const res = await $.ajax({ method: 'POST', url: `https://pan.baidu.com/share/set?channel=chunlei&bdstoken=${bdstoken}`, data: `period=1&pwd=${pwd}&eflag_disable=true&channel_list=%5B%5D&schannel=4&fid_list=[${selectedFsIds}]`, contentType: 'application/json', }) console.log('response share ===>', res) if (res.show_msg === '该文件禁止分享') throw new Error('该文件禁止分享') const url = res.link const surl = url ? url.substring(url.lastIndexOf('/') + 1) : null if (!surl) throw new Error(res.show_msg || '获取分享链接失败') console.log('SURL', surl) $('#loadingtext').text('正在获取文件信息......') const listRequest = { surl, pwd, password: getPassword(), token: getPassword(), user: USERNAME, dir: '/', } console.log('listRequest=====>', listRequest) const listResponse = await makeRequest(`${getServersUrl()}/api/parse/list`, listRequest) const listResponseJson = JSON.parse(listResponse.response) console.log('listResponse=====>', listResponse, listResponseJson) if (listResponseJson.code !== 200) { $('#texttip').val(listResponseJson.message) if (listResponseJson.code === 403) await updatePassword(listResponseJson.message, selectedItems, selectedFsIds) return } $('#loadingtext').text('正在获取下载链接......') const { randsk, shareid, uk } = listResponseJson.data const fileChunks = chunkBySize(selectedItems) links = [] let quotaMessage = '' let isBreak = false for (let i = 0; i < fileChunks.length; i++) { const fileChunk = fileChunks[i] $('#loadingtext').text(`正在获取第${i + 1}/${fileChunks.length}块文件`) const linkRequest = { randsk, uk, shareid, surl, url, dir: '/', pwd, fs_ids: fileChunk.map((file) => file.fs_id), password: getPassword(), token: getPassword(), user: USERNAME, } console.log('linkReq========>', linkRequest) const linkResponse = await makeRequest(`${getServersUrl()}/api/parse/link`, linkRequest) const linkResponseJson = JSON.parse(linkResponse.response) console.log('linkResponse=====>', linkResponse, linkResponseJson) if (linkResponse.status === 403) { isBreak = true Swal.fire({ title: '系统提示', html: `
积分不足${links.length > 0 ? ',但您可以下载已解析完成的文件。' : ''}
${SCONFIG.config.ad}

配额信息
${linkResponseJson?.quota_message ?? ''}
`, icon: 'error', }) break } if (linkResponseJson.message.includes('-20') || !linkResponseJson.data) { i-- continue } links.push(...linkResponseJson.data) quotaMessage = linkResponseJson.quota_message } console.log('links=====>', links) if (!isBreak) { Swal.fire({ title: '解析成功', html: `
下载提示信息
IDM下载务必设置好(UA),填入页面上正确的UA,否则下载报错403。推送至 Aria2/Motrix 时需提前启动软件并检查 RPC 地址是否正确,推送失败尝试取消 Token!请关闭代理工具!
${SCONFIG.config.ad}

配额信息
${quotaMessage}
`, icon: 'success', }) } if (links.length > 0) { $('#copy').removeClass('layui-btn-disabled') $('#pusharia').removeClass('layui-btn-disabled') $('#copyUa').removeClass('layui-btn-disabled') } layer.closeAll('loading') $('#loadingtext').hide() } async function sendAria2() { layer.load(2, { shade: [0.3, '#FFF'], }) let rpcDir = $('#dialogTxtSavePath').val().replace(/\\/g, '/') let rpcHostUrl = $('#dialogAriaRPC').val() let rpcToken = $('#dialogAriaToken').val() try { links.forEach((link) => { link.dir = selectedItems.find((item) => item.fs_id === link.fs_id)?.path ?? '' GM_xmlhttpRequest({ method: 'POST', responseType: 'json', timeout: 3000, url: rpcHostUrl, data: JSON.stringify({ id: 'shensuDown', jsonrpc: '2.0', method: 'aria2.addUri', params: [ `token:${rpcToken}`, [link.url], { "max-connection-per-server": "4", split: "4", "max-overall-download-limit": "10M", "max-concurrent-downloads": "4", dir: rpcDir, out: link.dir, 'user-agent': link.ua, }, ], }), onload: function (res) { if (res.status === 200) { if (!res.response.result) { Swal.fire({ title: '系统提示', html: '发生错误,没有找到该端口/路径的下载器 请检查PRC是否正确或已打开下载器!', icon: 'error', }) } } else { Swal.fire({ title: '系统提示', html: '发生错误,没有找到该端口/路径的下载器 请检查PRC是否正确或已打开下载器!', icon: 'error', }) } }, ontimeout: (res) => { Swal.fire({ title: '系统提示', html: '连接到RPC服务器超时:请检查推送前Aria2/Motrix是否正在运行, RPC已连接? RPC配置是否正确!若是远程下载器请你配置内网穿透!或取消Token推送!', icon: 'error', }) }, onerror: (res) => { Swal.fire({ title: '系统提示', html: '发送至Aria2/Motrix时发生错误,请重试!推送前检查Aria2/Motrix是否正在运行,RPC已连接? RPC配置是否正确!若是远程下载器请你配置内网穿透!或取消Token推送!' + res.responseText, icon: 'error', }) }, }) $('#loadingtext').hide() layer.closeAll('loading') }) } catch (error) { $('#loadingtext').hide() layer.closeAll('loading') console.log(error) Swal.fire({ title: '系统提示', html: '发生错误,请刷新页面重试!', icon: 'error', }) } Swal.fire({ title: '系统提示', html: `推送成功!快去看看吧 若下载失败请检查保存文件路径有无配置,关闭您的代理下载!
${SCONFIG.config.ad}`, icon: 'success', }) } })()