// ==UserScript== // @name 哔哩哔哩(bilibili)视频下载 // @namespace https://weibo.com/guoxuebiji/profile?is_all=1 // @version 1.4 // @description 获取哔哩哔哩(https://space.bilibili.com)视频链接并下载 // @author 东风 // @date 2020-4-25 // @modified 2020-10-24 // @match http*://*.bilibili.com/video/* // @match http*://*.bilibili.com/bangumi/play/* // @match http*://*.bilibili.com/*/favlist* // @icon https://space.bilibili.com/favicon.ico // @license BSD 3-Clause License // @grant unsafeWindow // @grant GM_setClipboard // @grant GM_info // @grant GM_download // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @grant GM.xmlHttpRequest // @grant GM_openInTab // @grant GM.openInTab // @grant GM_getValue // @grant GM.getValue // @grant GM_setValue // @grant GM.setValue // @downloadURL none // ==/UserScript== (function () { 'use strict'; //==========以下是与下载器通讯===================================================================== var host = '127.0.0.1' ,port = '5678'; var ws = new WebSocket("ws://" + host + ":" + port + "/jsonrpc"); function wsopen() { console.log("连接下载服务器"); // var json = MakeSendData("http://aria2c.com/usage.html", "test.html", "./dow") // ws.send(JSON.stringify(["https://www.bilibili.com/video/BV19E411D78Q?p=5","https://www.bilibili.com/video/BV19E411D78Q?p=3"])); }; function wsmessage(evt) { console.log(evt); var received_msg = evt.data; console.log("收到服务器的信息",received_msg); // ws.send(JSON.stringify(["https://www.bilibili.com/video/BV19E411D78Q?p=6","https://www.bilibili.com/video/BV19E411D78Q?p=3"])); // console.log(JSON.parse(received_msg)); // 发送成功{id: 2333333, jsonrpc: "2.0", result: "a6ff40d33524229a"} // 开始下载{jsonrpc: "2.0", method: "aria2.onDownloadStart", params: [[gid: "a6ff40d33524229a"]]} // 下载完成{jsonrpc: "2.0", method: "aria2.onDownloadComplete", params: [[gid: "a6ff40d33524229a"]]} // 下载出错{jsonrpc: "2.0", method: "aria2.onDownloadError", params: [[gid: "a6ff40d33524229a"]]} }; function wsclose() { console.log("连接关闭"); }; ws.onopen = wsopen; ws.onmessage = wsmessage; ws.onclose = wsclose; function Download(url, out, dir) { // var json = MakeSendData(url, out, dir) ws.send(JSON.stringify(url)); }; //==========以下是与下载器通讯===================================================================== //字符串是否包含子串 function isContains(str, substr) { //str是否包含substr return str.indexOf(substr) >= 0; } //数组是否包含某元素 function arrayContains(arr, obj) { var i = arr.length; while (i--) { if (arr[i] === obj) { return true; } } return false; } //判断页面中id是否存在 function hasId(id) { //有此id返回true,否则返回false var element = document.getElementById(id); if (element) { return true } else { return false } } //获取url查询参数 function getUrlQuery(key, acq) { /* 获取URL中?之后的查询参数,不包含锚部分,比如url为http://passport.saintic.com/user/message/?status=1&Action=getCount 若无查询的key,则返回整个查询参数对象,即返回{status: "1", Action: "getCount"}; 若有查询的key,则返回对象值,返回值可以指定默认值acq:如key=status, 返回1;key=test返回acq */ var str = location.search; var obj = {}; if (str) { str = str.substring(1, str.length); // 以&分隔字符串,获得类似name=xiaoli这样的元素数组 var arr = str.split("&"); //var obj = new Object(); // 将每一个数组元素以=分隔并赋给obj对象 for (var i = 0; i < arr.length; i++) { var tmp_arr = arr[i].split("="); obj[decodeURIComponent(tmp_arr[0])] = decodeURIComponent(tmp_arr[1]); } } return key ? obj[key] || acq : obj; } //计算百分比 function calculatePercentage(num, total) { //小数点后两位百分比 return (Math.round(num / total * 10000) / 100.00 + "%"); } //加载css文件 function addCSS(href) { var link = document.createElement('link'); link.type = 'text/css'; link.rel = 'stylesheet'; link.href = href; document.getElementsByTagName("head")[0].appendChild(link); } //加载js文件 function addJS(src, cb) { var script = document.createElement("script"); script.type = "text/javascript"; script.src = src; document.getElementsByTagName('head')[0].appendChild(script); script.onload = typeof cb === "function" ? cb : function () {}; } //获取可使用域名 function getEffectiveHost() { var host = window.location.host; if (!host) { host = document.domain; } if (!host) { host = "huaban.com"; } if (isContains(host, "meiwu.co")) { host = "login.meiwu.co"; } else if (isContains(host, "huabanpro.com")) { host = "huabanpro.com"; } else { host = "huaban.com"; } return host; } //时间戳转化为日期格式 function formatUnixtimestamp(unixtimestamp) { var unixtimestamp = new Date(unixtimestamp * 1000); var year = 1900 + unixtimestamp.getYear(); var month = "0" + (unixtimestamp.getMonth() + 1); var date = "0" + unixtimestamp.getDate(); var hour = "0" + unixtimestamp.getHours(); var minute = "0" + unixtimestamp.getMinutes(); var second = "0" + unixtimestamp.getSeconds(); return year + "-" + month.substring(month.length - 2, month.length) + "-" + date.substring(date.length - 2, date.length) + " " + hour.substring(hour.length - 2, hour.length) + ":" + minute.substring(minute.length - 2, minute.length); } //加星隐藏部分 function setStarHidden(str) { if (str) { return str.substr(0, 4) + " **** " + str.substr(-4); } } //封装localStorage class StorageMix { constructor(key) { this.key = key; this.obj = window.localStorage; if (!this.obj) { console.error("浏览不支持localStorage"); return false; } } //设置或跟新本地存储数据 set(data) { if (data) { return this.obj.setItem(this.key, JSON.stringify(data)); } } //获取本地存储数据 get() { var data = null; try { data = JSON.parse(this.obj.getItem(this.key)); } catch (e) { console.error(e); } finally { return data; } } clear() { //清除对象 return this.obj.removeItem(this.key); } } //由于@require方式引入jquery时layer使用异常,故引用cdn中jquery v1.10.1;加载完成后引用又拍云中layer v3.1.1 addJS("https://cdn.bootcss.com/jquery/1.10.1/jquery.min.js", function () { $.noConflict(); addJS("https://static.saintic.com/cdn/layer/3.1.1/layer.js"); }); //当前URL var initUrl = window.location.href; //判断UA是否为移动端 var isMobile = ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone|Opera Mini)/i))) ? true : false; //加载优化 var loadingLayer = null; // 设置提醒弹框 function setupRemind() { var email = getReceiveBy('email') || '', mobile = getReceiveBy('mobile') || '', token = getReceiveBy('token') || ''; var content_overview = [ '
', '

花瓣网下载脚本功能设置,包括提醒、公告等。


', '
提醒功能旨在提交远程下载后,查询下载进度并在下载完成发送邮箱、短信、微信等消息,以供用户下载。
', '

    邮箱:' + (email || '未设置!') + '

', '

    手机:' + (mobile || '未设置!') + '

', '

    密钥:' + (setStarHidden(token) || '未设置!') + '

', '

    微信:采用本站公众号,关注后,发送"@下载链接"即可查询状态。

', '
公告功能目前支持清理缓存公告。
', '

    点击重置状态:将已读公告标记为未读,下次请求会重新展示公告。

', '

    重新阅读公告:手动查看花瓣网公告。

', '
帮助说明与反馈。
', '

    查看FAQ:关于设置方面的问题说明,亦可阅读详细文档

', '

    在线反馈:问题反馈或功能建议,若页面异常可直接发邮件

', '
捐赠。
', '

    如果您觉得此脚本对您有所裨益,您可以点此捐赠

', '
' ].join(""); var content_remind = [ '
', '
保存邮箱
', '

保存手机

', '

保存密钥

', '

微信下载进度查询:

', '', '
' ].join(""); var content_weixin = [ '
', '

微信下载进度查询:

', '

  请使用微信APP扫描此二维码并关注,发送"@下载链接"即可,服务器会返回下载进度。

', '', '
' ].join(""); var content_help = [ '
', '

1. 什么是密钥?
  答:密钥是在您在诏预开放平台创建的Api Token,与用户一一对应,拥有它可以访问平台公共接口、处理您账号的相关事务等,此处仅作为您使用此脚本查询远端下载记录,以便及时下载完成的压缩包,省去了复制下载链接等步骤。切记密钥不可泄露,否则可能造成账号风险!

', '

2. 怎么创建密钥?
  答:请登录开放平台:https://open.saintic.com,在控制台处可以创建密钥(您可以使用QQ/微博/码云/GitHub等快捷登录)!

', '

3. 微信怎么查询下载进度?
  答:请使用微信APP扫描此二维码并关注,发送"@下载链接"即可,服务器会返回下载状态。

', '
' ].join(""); layer.tab({ area: isMobile ? '90%' : ['550px', '520px'], maxmin: true, tab: [{ title: '概述', content: content_overview }, { title: '设置提醒', content: content_remind }], success: function (layero, index) { var body = layer.getChildFrame('body', index); body.context.getElementById("save_remind_email").onclick = function () { var value = body.context.getElementById("set_remind_email").value; setupReceiveTo("email", value); body.context.getElementById("overview_email").innerHTML = (value || '已清空'); } body.context.getElementById("save_remind_mobile").onclick = function () { var value = body.context.getElementById("set_remind_mobile").value; setupReceiveTo("mobile", value); body.context.getElementById("overview_mobile").innerHTML = (value || '已清空'); } body.context.getElementById("reset_notice_status").onclick = function () { var storage = new StorageMix("grab_huaban_board"); storage.clear(); layer.msg("重置成功", { icon: 1 }); } body.context.getElementById("reshow_notice").onclick = function () { var storage = new StorageMix("grab_huaban_board"); storage.clear(); showNotice(); } body.context.getElementById("save_remind_token").onclick = function () { var value = body.context.getElementById("set_remind_token").value; setupReceiveTo("token", value); body.context.getElementById("overview_token").innerHTML = (!value) ? '已清空' : setStarHidden(value); } body.context.getElementById("grab_setting_help").onclick = function () { layer.open({ type: 1, title: "FAQ", content: content_help, closeBtn: false, shadeClose: false, shade: 0, btn: '我知道了', btnAlign: 'c', zIndex: layer.zIndex, success: function (layero) { layer.setTop(layero); }, yes: function (index, layero) { layer.close(index); } }); } body.context.getElementById("grab_setting_donation").onclick = function () { layer.tab({ shadeClose: false, shade: 0, tab: [{ title: '支付宝', content: '
' }, { title: '微信', content: '
' }] }); } } }); } /** * 设置接收信息 * @param type 参数: mobile|email|token */ function setupReceiveTo(type, value) { var es = new StorageMix("grab_huaban_board_remind_email"); var ms = new StorageMix("grab_huaban_board_remind_mobile"); var ts = new StorageMix("grab_huaban_board_token"); if (type === 'email') { var isEmail = /^[\w.\-]+@(?:[a-z0-9]+(?:-[a-z0-9]+)*\.)+[a-z]{2,3}$/i; if (value) { if (!isEmail.test(value)) { layer.msg('请输入正确的邮箱地址'); return; } es.set(value); layer.msg('邮箱:' + value + ',设置成功!', { icon: 1 }); } else { es.clear(); layer.msg('邮箱已清空!', { icon: 1 }); } } else if (type === 'mobile') { var isMobile = /^1\d{10}$/i; if (value) { if (!isMobile.test(value)) { layer.msg('请输入正确的手机号'); return; } ms.set(value); layer.msg('手机号:' + value + ',设置成功!', { icon: 1 }); } else { ms.clear(); layer.msg('手机号已清空!', { icon: 1 }); } } else if (type === 'token') { if (!value) { ts.clear(); layer.msg('密钥已清空!', { icon: 1 }); } else { ts.set(value); layer.msg('密钥:' + value + ',设置成功!', { icon: 1 }); } } else { layer.msg('暂不支持此方式!'); return; } } /** * 读取接收信息值 * @param type 参数: mobile|email|token */ function getReceiveBy(type) { var str = '', es = new StorageMix("grab_huaban_board_remind_email"), ms = new StorageMix("grab_huaban_board_remind_mobile"), ts = new StorageMix("grab_huaban_board_token"); if (type === 'email') { str = es.get(); } else if (type === 'mobile') { str = ms.get(); } else if (type === 'token') { str = ts.get(); } return str || ""; } /* 下载用户画板接口 */ //交互确定画板下载方式 function interactiveBoard(board_id, pins, pin_number, user_id) { /* board_id int: 画板id pins list: 包含所有程序加载到的图片数据 pin_number int: 这个画板总共有多少图片 user_id str: 这个画板所属的用户 */ layer.close(loadingLayer); var downloadMethod = 0, msg = [ '
当前画板共' + pin_number + '张图片,抓取了' + pins.length + '张,抓取率:' + calculatePercentage(pins.length, pin_number) + '!提示: 只有登录后才可以抓取几乎所有图片哦。
', '请选择以下三种下载方式:
', '1. 文本
    即所有图片地址按行显示,提供复制,粘贴至迅雷、QQ旋风等下载工具批量下载即可(或这个工具),推荐使用此方式。
', '2. 本地
    即所有图片直接保存到硬盘中,由于是批量下载,所以浏览器设置中请关闭"下载前询问每个文件的保存位置",并且允许浏览器下载多个文件的授权申请,以保证可以自动批量保存,否则每次保存时会弹出询问,对您造成困扰。
', '3. 远程
    即所有图片将由远端服务器下载并压缩,提供压缩文件链接,直接下载此链接解压即可。
', '

寻求帮助?请点击我!

' ].join(''); layer.open({ type: 1, title: "选择画板图片下载方式", content: msg, closeBtn: false, shadeClose: false, shade: 0, btn: ['文本', '本地', '远程'], btnAlign: 'c', zIndex: layer.zIndex, success: function (layero) { layer.setTop(layero); }, yes: function (index, layero) { //文本方式下载,比如迅雷、QQ旋风 downloadMethod = 1; layer.close(index); layer.open({ type: 1, title: "文本方式下载", content: '
请点击复制按钮,粘贴到迅雷等工具中下载!
', closeBtn: false, shadeClose: false, shade: 0, btn: '复制', btnAlign: 'c', maxmin: true, zIndex: layer.zIndex, success: function (layero) { layer.setTop(layero); }, yes: function (index, layero) { layer.close(index); GM_setClipboard(pins.map(function (pin) { return pin.imgUrl + "\n"; }).join("")); layer.msg("复制成功", { icon: 1 }); } }); }, btn2: function (index, layero) { //本地下载 downloadMethod = 2; layer.close(index); pins.map(function (pin) { GM_download(pin.imgUrl, pin.imgName); }); }, btn3: function (index, layero) { //远端下载 downloadMethod = 3; layer.close(index); // 提醒接收配置信息读取 var email = getUrlQuery("email", getReceiveBy('email')); var mobile = getUrlQuery("sms", getReceiveBy('mobile')); jQuery.ajax({ url: "https://open.saintic.com/CrawlHuaban/", type: "POST", data: { site: 1, version: GM_info.script.version, board_total: pin_number, board_id: board_id, user_id: user_id, pins: JSON.stringify(pins), email: email, sms: mobile }, beforeSend: function (request) { request.setRequestHeader("Authorization", "Token " + getReceiveBy('token')); }, success: function (res) { if (res.success === true) { var msg = ['
下载任务已经提交!
根据画板图片数量,所需时间不等,请稍等数分钟后访问下载链接:
', res.downloadUrl + '
它将于', res.expireTime + '过期,那时资源会被删除,请提前下载。', res.tip + '
' ].join(""); layer.open({ type: 1, title: "温馨提示", content: msg, closeBtn: false, shadeClose: false, shade: 0, area: '350px', btn: '我已知晓并复制下载链接', btnAlign: 'c', maxmin: true, zIndex: layer.zIndex, success: function (layero) { layer.setTop(layero); }, yes: function (index, layero) { layer.close(index); GM_setClipboard(res.downloadUrl); var tips = '复制成功!'; if (email) { tips += ' 接收提醒邮箱:' + email; } if (mobile) { tips += ' 接收提醒手机:' + mobile; } layer.msg(tips, { icon: 1 }); } }); } else { layer.msg("远端服务提示: " + res.msg, { icon: 2, time: 8000 }); } } }); }, end: function () { jQuery.ajax({ url: "https://open.saintic.com/CrawlHuaban/putClick", type: "POST", data: { site: 1, version: GM_info.script.version, total_number: pin_number, pin_number: pins.length, board_id: board_id, user_id: user_id, downloadMethod: downloadMethod } }); } }); } //交互确定用户下载方式 function interactiveUser(user_id, boards, board_number) { boards.map(function (board_id) { var msg = [ '
当前画板是:' + board_id + '!提示: 只有登录后才可以抓取几乎所有画板哦。
', '请选择以下两种功能按钮:
', '1. 开始下载
    点击此按钮将开始抓取画板图片,抓取完成后弹出下载方式,请选择某种方式后完成当前画板下载。
', '2. 跳过
    即忽略此画板,并关闭本窗口。
', '

请注意:用户存在多个画板时会弹出多个窗口,请移动或最小化当前窗口以显示其他窗口。

', '

寻求帮助?请点击我!

' ].join(''); layer.open({ type: 1, title: "花瓣网用户抓取:" + user_id, content: msg, closeBtn: false, shadeClose: false, shade: 0, btn: ['开始下载', '跳过'], btnAlign: 'c', maxmin: true, zIndex: layer.zIndex, success: function (layero) { layer.setTop(layero); }, yes: function (index, layero) { //按钮【开始下载】的回调 layer.close(index); downloadBoard(board_id); }, btn2: function (index, layero) { //按钮【跳过】的回调 layer.close(index); } }); }); layer.open({ type: 1, title: "温馨提示", content: '
当前用户画板数量总共为' + board_number + '个,抓取了' + boards.length + '个,抓取率:' + calculatePercentage(boards.length, board_number) + '!
寻求帮助?Bug反馈?请点击我!
', closeBtn: false, shadeClose: false, shade: 0, btn: '我已知晓', btnAlign: 'c', zIndex: layer.zIndex, success: function (layero) { layer.setTop(layero); }, yes: function (index, layero) { //按钮【我已知晓】的回调 layer.close(index); } }); } //画板解析与下载 function downloadBoard(board_id) { if (board_id) { console.group("花瓣网下载-当前画板:" + board_id); var limit = 100, loadingLayer = layer.load(0, { time: 5000 }); //get first pin data console.log("请求:",window.location.protocol + '//' + getEffectiveHost() + '/boards/' + board_id); jQuery.ajax({ url: window.location.protocol + '//' + getEffectiveHost() + '/boards/' + board_id, async: false, success: function (res) { try { console.log(res); if (res.hasOwnProperty("board") === true) { var board_data = res.board, //画板图片总数 pin_number = board_data.pin_count, board_pins = board_data.pins, user_id = board_data.user.urlname, //尝试向上取整,计算加载完画板图片需要的最大次数 retry = board_pins.length < pin_number ? Math.ceil(pin_number / limit) : 0; console.debug("Current board <" + board_id + "> pins number is " + pin_number + ", first pins number is " + board_pins.length + ", retry is " + retry); var bf = setInterval(function () { if (retry > 0) { //说明没有加载完画板图片,需要ajax请求 var last_pin = board_pins[board_pins.length - 1].pin_id; //get ajax pin data var board_next_url = window.location.protocol + "//" + getEffectiveHost() + "/boards/" + board_id + "/?max=" + last_pin + "&limit=" + limit + "&wfl=1"; console.log("请求:",board_next_url); jQuery.ajax({ url: board_next_url, async: false, success: function (res) { //console.log(res); var board_next_data = res.board; board_pins = board_pins.concat(board_next_data.pins); console.log("ajax load board with pin_id " + last_pin + ", get pins number is " + board_next_data.pins.length + ", merged"); if (board_next_data.pins.length === 0) { retry = 0; return false; } last_pin = board_next_data.pins[board_next_data.pins.length - 1].pin_id; } }); retry--; } else { console.log("画板" + board_id + "共抓取" + board_pins.length + "个pin"); var pins = board_pins.map(function (pin) { var suffix = (!pin.file.type) ? "png" : pin.file.type.split("/")[1]; return { imgUrl: window.location.protocol + "//hbimg.huabanimg.com/" + pin.file.key, imgName: pin.pin_id + "." + suffix }; }) //交互确定下载方式 interactiveBoard(board_id, pins, pin_number, user_id); clearInterval(bf); } }, 200); } } catch (e) { console.error(e); } } }); console.groupEnd(); } } //用户解析与下载 function downloadUser(user_id) { if (user_id) { console.group("花瓣网下载-当前用户:" + user_id); var limit = 10; //get first board data jQuery.ajax({ url: window.location.protocol + '//' + getEffectiveHost() + '/' + user_id, async: false, success: function (res) { try { //console.log(res); if (res.hasOwnProperty("user") === true) { var user_data = res.user, board_number = user_data.board_count, board_ids = user_data.boards, retry = board_ids.length < board_number ? Math.ceil(board_number / limit) : 0; console.debug("Current user <" + user_id + "> boards number is " + board_number + ", first boards number is " + board_ids.length + ", retry is" + retry); var uf = setInterval(function () { if (retry > 0) { var last_board = board_ids[board_ids.length - 1].board_id; //get ajax board data var user_next_url = window.location.protocol + "//" + getEffectiveHost() + "/" + user_id + "/?max=" + last_board + "&limit=" + limit + "&wfl=1"; jQuery.ajax({ url: user_next_url, async: false, success: function (res) { //console.log(res); var user_next_data = res.user.boards; board_ids = board_ids.concat(user_next_data); console.debug("ajax load user with board_id " + last_board + ", get boards number is " + user_next_data.length + ", merged"); if (user_next_data.length === 0) { retry = 0; return false; } last_board = user_next_data[user_next_data.length - 1].board_id; } }); retry--; } else { console.log("用户" + user_id + "共抓取" + board_ids.length + "个board"); var boards = board_ids.map(function (board) { return board.board_id; }); //交互确定下载方式 interactiveUser(user_id, boards, board_number); clearInterval(uf); } }, 200); } } catch (e) { console.error(e); } } }); console.groupEnd(); } } function GetFileName(url) { var Business=url.split("/"); return Business[Business.length-1]; } // 拷贝视频网址 function CopyPicUrls() { var json = {}; var title = document.title // var n = title.lastIndexOf("-微元素"); // if (n >= 0) { // title = title.substring(0,n); // var n2 = title.lastIndexOf("-"); // if (n2 >= 0) { // title = title.substring(0,n2); // } // } title = "#title:" + title + "\n" json[title] = [] var x = document.getElementsByClassName("fav-video-list clearfix content")[0].children; console.log(title) var list = []; console.log(x) for (var i = 0; i < x.length; i++) { console.log(i,x[i].attributes["class"].nodeValue) if (x[i].attributes["class"].nodeValue != "small-item disabled") { list[i] = x[i]; } } console.log(list) // zoomfile if (list) { GM_setClipboard( list.map(function (pin) { return "https:" + pin.children[0].attributes["href"].nodeValue + "\r\n"; }).join("")); layer.msg("复制成功", { icon: 1 }); return list.map(function (pin) { return "https:" + pin.children[0].attributes["href"].nodeValue; }) }else { layer.msg("找不到图片", { icon: 1 }); } // console.log(json); } // 拷贝播放列表视频网址 function CopyVedioUrls() { var json = {}; var title = document.title // var n = title.lastIndexOf("-微元素"); // if (n >= 0) { // title = title.substring(0,n); // var n2 = title.lastIndexOf("-"); // if (n2 >= 0) { // title = title.substring(0,n2); // } // } title = "#title:" + title + "\n" json[title] = [] var x = document.getElementsByClassName("list-box")[0].children; console.log(title) var list = []; console.log(x) for (var i = 0; i < x.length; i++) { list[i] = x[i]; } console.log(list) // zoomfile if (list) { GM_setClipboard( list.map(function (pin) { return "https://www.bilibili.com" + pin.children[0].attributes["href"].nodeValue + "\r\n"; }).join("")); layer.msg("复制成功", { icon: 1 }); return list.map(function (pin) { return "https://www.bilibili.com" + pin.children[0].attributes["href"].nodeValue ; }) }else { layer.msg("找不到图片", { icon: 1 }); } // console.log(json) } // 拷贝番剧播放列表视频网址 function CopyBangumiUrls() { var json = {}; var title = document.title title = "#title:" + title + "\n" json[title] = [] var x = document.getElementsByClassName("list-wrapper longlist")[0].children[0].children; console.log(title) console.log(x, "x----------") var index = 0; for (var i = 0; i < x.length; i++) { console.log(i, x[i]) if (x[i].attributes["class"].nodeValue == "ep-item cursor visited") { index = i; } } console.log("当前第"+index+"集") var arrUrl = window.location.pathname.split('/'); console.log("arrUrl = ", arrUrl); var videoID = parseInt(arrUrl[3].substring(2))-index console.log("videoID = ", videoID) var list = []; console.log(x) for (var i = 0; i < x.length; i++) { list[i] = videoID + i; } console.log(list) // zoomfile if (list) { GM_setClipboard( list.map(function (pin) { return "https://www.bilibili.com" + pin + "\r\n"; }).join("")); layer.msg("复制成功", { icon: 1 }); return list.map(function (pin) { return "https://www.bilibili.com" + pin; }) }else { layer.msg("找不到图片", { icon: 1 }); } } function ParseUrl() { console.log("onclick-----------------") var arrUrl = window.location.pathname.split('/'); console.log("arrUrl = ", arrUrl); if(!arrUrl[1]) return; if (arrUrl[1] == "video") return CopyVedioUrls(); if (arrUrl[1] == "bangumi") return CopyBangumiUrls(); if (arrUrl[2] == "favlist") return CopyPicUrls(); } /* 主入口,分出不同模块:用户、画板,监听并刷新URL */ window.onload =function() { var int=self.setInterval(function (){ console.log("Interval---------------"); var user_text = "拷贝下载链接"; var tmpHtml = '' var btn = document.getElementsByClassName("CopyPicUrls") // console.log(btn,"-======") if (btn.length > 0) { btn.innerHTML = tmpHtml return } var gelement = document.getElementsByClassName("nav-search-box") // console.log(gelement,"----------", gelement.length, gelement[0]); var pab = document.getElementsByClassName("nav-search-box")[0]; // console.log(pab,"----------222"); // console.log(pab); pab.insertAdjacentHTML('afterEnd', tmpHtml); //监听用户点击下载事件 document.getElementById("CopyPicUrls").onclick = function () { ParseUrl(); }; function GMaddStyle(css) { var myStyle = document.createElement('style'); myStyle.textContent = css; var doc = document.head || document.documentElement; doc.appendChild(myStyle); } var left = 0; var top = 100; GMaddStyle(`#vip_movie_box {cursor:pointer; position:fixed; top:` + top + `px; left:` + left + `px; width:0px; background-color:#2E9AFE; z-index:2147483647; font-size:20px; text-align:left;} #vip_movie_box .item_text {width:28px; padding:4px 0px; text-align:center;} #vip_movie_box .item_text img {width:35px; height:35px; display:inline-block; vertical-align:middle;} #vip_movie_box .vip_mod_box_action {display:none; position:absolute; left:28px; top:0; text-align:center; background-color:#272930; border:1px solid gray;} #vip_movie_box .vip_mod_box_action li{font-size:12px; color:#DCDCDC; text-align:center; width:60px; line-height:21px; float:left; border:1px solid gray; padding:0 4px; margin:4px 2px;} #vip_movie_box .vip_mod_box_action li:hover{color:#FF4500;} #vip_movie_box .selected_text {width:28px; padding:4px 0px; text-align:center;} #vip_movie_box .selected_text img {width:35px; height:35px;display:inline-block; vertical-align:middle;} #vip_movie_box .vip_mod_box_selected {display:none; position:absolute; left:28px; top:0; text-align:center; background-color:#F5F6CE; border:1px solid gray;} #vip_movie_box .vip_mod_box_selected ul{height:455px; overflow-y: scroll;} #vip_movie_box .vip_mod_box_selected li{font-size:14px; color:#00FF00; text-align:center; width:120px; line-height:27px; float:left; border:1px dashed gray; padding:0 4px; margin:4px 2px;} #vip_movie_box .vip_mod_box_selected li:hover{color:#FF4500;}`); // var $ = $ || window.$; var ImgBase64 = "data:image/png;base64,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" var html = `
`; document.body.insertAdjacentHTML('afterEnd', html); document.getElementById("downloadVideos").onclick = function () { var urls = ParseUrl(); console.log("urls = ",urls) if (urls) { Download(urls) } }; },3000) } })();