柒灵全能视频下载器

(目前支持)哔哩哔哩(bilibili)/优酷网(youku)/腾讯视频(qq)/爱奇艺(iqiyi)/中国大学慕课网(www.icourse163.org)视频批量下载, 加速下载, 随时随地想看就看. 支持微元素/花瓣网图片批量下载

  1. // ==UserScript==
  2. // @name 柒灵全能视频下载器
  3. // @namespace https://weibo.com/guoxuebiji/profile?is_all=1
  4. // @version 2.6.9
  5. // @description (目前支持)哔哩哔哩(bilibili)/优酷网(youku)/腾讯视频(qq)/爱奇艺(iqiyi)/中国大学慕课网(www.icourse163.org)视频批量下载, 加速下载, 随时随地想看就看. 支持微元素/花瓣网图片批量下载
  6. // @author 东风
  7. // @date 2020-04-25
  8. // @modified 2023-09-27
  9. // @match http*://*.bilibili.com/video/*
  10. // @match http*://*.bilibili.com/bangumi/play/*
  11. // @match http*://*.bilibili.com/*/favlist*
  12. // @match http*://v.youku.com/v_show/*
  13. // @match http*://m.youku.com/alipay_video/*
  14. // @match http*://v.qq.com/x/cover/*
  15. // @match http*://m.v.qq.com/x/cover/*
  16. // @match http*://v.qq.com/x/page/*
  17. // @match http*://m.v.qq.com/x/page/*
  18. // @match http*://m.v.qq.com/*
  19. // @match http*://www.iqiyi.com/v*
  20. // @match http*://m.iqiyi.com/*
  21. // @match http*://www.iqiyi.com/*
  22. // @match http*://m.iqiyi.com/kszt/*
  23. // @match http*://www.iqiyi.com/kszt/*
  24. // @match http*://www.element3ds.com/*
  25. // @match https://basic.smartedu.cn/syncClassroom*
  26. // @match https://weibo.com/*tabtype=album
  27. // @match http*://huaban.com/boards/*
  28. // @match http*://huaban.com/user/*
  29. // @match http*://mp.weixin.qq.com/*
  30. // @match https://www.icourse163.org/learn/*?tid=*
  31. // @icon http*://space.bilibili.com/favicon.ico
  32. // @license BSD 3-Clause License
  33. // @grant unsafeWindow
  34. // @grant GM_setClipboard
  35. // @grant GM_info
  36. // @grant GM_download
  37. // @grant GM_registerMenuCommand
  38. // @grant GM_xmlhttpRequest
  39. // @grant GM.xmlHttpRequest
  40. // @grant GM_openInTab
  41. // @grant GM.openInTab
  42. // @grant GM_getValue
  43. // @grant GM.getValue
  44. // @grant GM_setValue
  45. // @grant GM.setValue
  46. // ==/UserScript==
  47.  
  48. (function () {
  49. 'use strict';
  50. //==========utils=====================================================================
  51. //加载css文件
  52. function addCSS(href) {
  53. var link = document.createElement('link');
  54. link.type = 'text/css';
  55. link.rel = 'stylesheet';
  56. link.href = href;
  57. document.getElementsByTagName("head")[0].appendChild(link);
  58. }
  59. //加载js文件
  60. function addJS(src, cb, onerror ) {
  61. var script = document.createElement("script");
  62. script.type = "text/javascript";
  63. script.src = src;
  64. console.log("addJS",script)
  65. document.getElementsByTagName('head')[0].appendChild(script);
  66. script.onload = typeof cb === "function" ? cb : function () {};
  67. script.onerror = typeof onerror === "function" ? onerror : function () {};
  68. }
  69.  
  70. // 加载css字符串
  71. function GMaddStyleString(css) {
  72. var myStyle = document.createElement('style');
  73. myStyle.textContent = css;
  74. var doc = document.head || document.documentElement;
  75. doc.appendChild(myStyle);
  76. }
  77.  
  78. function AddHtml(html) {
  79. document.body.insertAdjacentHTML('afterEnd', html);
  80. }
  81.  
  82.  
  83. // 改用ZUI //https://www.openzui.com/
  84.  
  85. // 百度 CDN
  86. // <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
  87. // 新浪 CDN
  88. // <script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
  89. // 又拍云 CDN
  90. // <script src="https://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js"></script>
  91.  
  92. addJS("https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js", function () {
  93.  
  94. console.log("-------------------load jq-------------------")
  95. window.$ = $.noConflict();
  96. addJS("https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js")
  97. addJS("https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js")
  98. // addCSS("https://cdn.bootcdn.net/ajax/libs/zui/1.9.2/css/zui.min.css");
  99. // addJS("https://cdn.bootcdn.net/ajax/libs/zui/1.9.2/js/zui.min.js", function () {
  100. addCSS("https://lib.baomitu.com/zui/1.9.2/css/zui.min.css");
  101. addJS("https://lib.baomitu.com/zui/1.9.2/js/zui.min.js", function () {
  102.  
  103. console.log("-------------------load bootcdn zui.min.js-------------------")
  104.  
  105. })
  106. });
  107.  
  108.  
  109.  
  110.  
  111. function GetFileName(url) {
  112. var Business=url.split("/");
  113. return Business[Business.length-1];
  114. }
  115.  
  116. // String.prototype.TextFilter=function(){
  117. // var pattern=new RegExp("[`~%!@#^=''?~!@#¥……&——‘”“'?*()(),,。.、]"); //[]内输入你要过滤的字符
  118. // var rs="";
  119. // for(var i=0;i<this.length;i++){
  120. // rs+=this.substr(i,1).replace(pattern,'');
  121. // }
  122. // return rs;
  123. // }
  124.  
  125. // 把空格和斜杠转换成下划线
  126. function Trim(str, limit)
  127. {
  128. // str = str.TextFilter()
  129. console.log(str)
  130. var result = str.replace(/\s+/g,"_");
  131. result = result.replace(/\//g,"-");
  132. result = result.replace(/\\/g,"_");
  133. result = result.replace(/&/g,"-");
  134. result = result.replace(/"/g,"");
  135. result = result.replace(/:/g,"_");
  136. result = result.replace(/%/g,"_");
  137. result = result.replace(/\|/g,"_");
  138. if (limit) {
  139. result=result.substring(0,limit);
  140. }
  141. console.log(result)
  142. return result;
  143. }
  144.  
  145. // 去掉标题后缀
  146. function FormatTitle(str)
  147. {
  148. var title = Trim(document.title)
  149. var n = title.lastIndexOf(str);
  150. if (n >= 0) {
  151. title = title.substring(0,n);
  152. }
  153. return title;
  154. }
  155.  
  156. function ShowTips(str) {
  157. new $.zui.Messager(str, {
  158. type: 'success', // 定义颜色主题
  159. time:2000
  160. }).show();
  161. }
  162. function ShowDialog(str) {
  163. // (new $.zui.ModalTrigger({custom: str})).show();
  164. // console.log("ShowDialog"+str)
  165. alert(str)
  166. }
  167.  
  168. //字符串是否包含子串
  169. function isContains(str, substr) {
  170. //str是否包含substr
  171. return str.indexOf(substr) >= 0;
  172. }
  173.  
  174. // 把网页获取的对象转换成数组
  175. function objToArray(x) {
  176. var list = [];
  177. console.log(x)
  178. for (var i = 0; i < x.length; i++) {
  179. list[i] = x[i];
  180. }
  181. return list
  182. }
  183.  
  184. // 补零
  185. function PrefixZero(num, n) {
  186. return (Array(n).join(0) + num).slice(-n);
  187. }
  188.  
  189. // 文件加前缀
  190. function AddPreFilename(fileName, index, max) {
  191. var len = (max+"").length
  192. return "P"+PrefixZero(index,len)+"."+fileName
  193. }
  194.  
  195. function ShowSelect(senddata) {
  196. window.g_senddata = senddata
  197. console.log("ShowSelect", JSON.stringify(senddata))
  198. var select_window = $("#select_window")
  199. console.log(select_window)
  200.  
  201. console.log("解决插件冲突", $(".cssobj-jiangxiaobai"))
  202. var ocss = $(".cssobj-jiangxiaobai").removeClass(".cssobj-jiangxiaobai")
  203. for (var i = 0; i < ocss.length; i++) {
  204. ocss[i].innerHTML = ""
  205. }
  206.  
  207. if (!select_window[0]) {
  208. var html =
  209. `
  210. <div class="modal fade" id="select_window" style="z-index:10000">
  211. <div class="modal-dialog modal-lg">
  212. <div class="modal-content">
  213. <div class="modal-header">
  214. <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>
  215. <h4 class="modal-title">请选择要下载的视频</h4>
  216. </div>
  217. <div class="modal-body">
  218. <form id='select_form' class="layui-form" action="" lay-filter="example">
  219. </form>
  220. </div>
  221. <div class="modal-footer center">
  222.  
  223. <div class="select" style="width:100px;display:inline-block;display:none">
  224. <select class="form-control">
  225. <option value="">清晰度</option>
  226. <option value="80">1080p</option>
  227. <option value="64">720p</option>
  228. <option value="32">480p</option>
  229. <option value="16">360p</option>
  230. </select>
  231. </div>
  232.  
  233. <div class="switch" style="width:100px;display:inline-block">
  234. <input type="checkbox" id='checkbox_index'>
  235. <label>添加序号</label>
  236. </div>
  237.  
  238. <button type="button" class="btn btn-primary" id="btn_download_all">下载选中</button>
  239. <button type="button" class="btn btn-primary" id="btn_select_all">取消/全选</button>
  240. <button type="button" class="btn btn-primary" id="btn_download_self">仅下载本视频</button>
  241. <button type="button" class="btn btn-default" data-dismiss="modal" >关闭</button>
  242. </div>
  243. </div>
  244. </div>
  245. </div>
  246. `
  247. AddHtml(html)//style="display:none"
  248. // select_form = $("#select_form")
  249.  
  250. // $(function() {
  251. // $("#checkbox_index").click(function(){
  252. // // var obj = $("#checkbox_index")
  253. // // if(obj.checked){
  254. // // console.log("selected");
  255. // // }else{
  256. // // console.log("unselected");
  257. // // }
  258. // $("#select_window").hide()
  259. // Download(senddata)
  260. // });
  261. // });
  262.  
  263. $(function() {
  264. $("#btn_download_self").click(function(){
  265. RealDownload(DownloadSelfInfo())
  266. });
  267. });
  268.  
  269. $(function() {
  270. $("#btn_download_all").click(function(){
  271. var list = $("[id='listItem']:checkbox")
  272. var checkbox = $("#checkbox_index")[0]
  273. console.log("checkbox_index",checkbox.checked)
  274. var res = []
  275. for (var i = 0; i < list.length; i++) {
  276. if (list[i].checked) {
  277.  
  278. if (checkbox.checked) {
  279. window.g_senddata[i].fileName = AddPreFilename(window.g_senddata[i].fileName, i+1, list.length)
  280. }
  281. res.push(window.g_senddata[i])
  282. }
  283. }
  284. console.log(res)
  285. RealDownload(res)
  286. });
  287. });
  288.  
  289. $(function() {
  290. $("#btn_select_all").click(function(){
  291. var list = $("[id='listItem']:checkbox")
  292. var flag = true
  293. if (list[0] && list[0].checked) {
  294. flag = false
  295. }
  296. console.log("flag" , flag)
  297. console.log(list)
  298. for (var i = 0; i < list.length; i++) {
  299. list[i].checked = flag
  300. }
  301. });
  302. });
  303.  
  304. }
  305. else{
  306. if ($("#select_window").is(":visible")) {
  307. $("#select_window").hide()
  308. // alert("存在")
  309. return
  310. }
  311. }
  312. var select_form = $("#select_form")
  313.  
  314. //弹出表格
  315. var s_content = `
  316. <form class="layui-form" action="" lay-filter="example">
  317. <div class="layui-form-item" pane="">
  318. <label class="layui-form-label">视频列表</label>`
  319.  
  320. for (var i = 0; i < senddata.length; i++) {
  321. if (senddata[i]) {
  322. senddata[i].id = i+1
  323. var checkboxid = "select_checkbox_id"+i
  324. s_content = s_content + `<div class="checkbox-primary"><input type="checkbox" checked="checked" id="listItem"><label for="`+checkboxid+`">`+ senddata[i].fileName +`</label></div>`
  325. }
  326.  
  327. }
  328.  
  329. s_content = s_content + `</div></form>`
  330. console.log(s_content)
  331. select_form[0].innerHTML = s_content
  332.  
  333. console.log($('#select_window'))
  334. $('#select_window').modal({
  335. scrollInside : true,
  336. moveable : "inside",
  337. show : true
  338. })
  339. }
  340.  
  341. function Download(urls)
  342. {
  343. ShowSelect(urls)
  344. };
  345.  
  346. function WebGet(url, success, headers) {
  347. jQuery.ajax({
  348. url: url,
  349. async: false,
  350. success: success,
  351. headers: headers,
  352. omplete: function (data) {
  353. if (data.status === 200) {
  354. }
  355. else {
  356. ShowTips("系统错误:暂时无法连接服务器")
  357. }
  358. }
  359. });
  360. }
  361. function WebPost(url, data, success) {
  362. console.log("WebPost", url, data)
  363. $.ajaxSettings.async = false; //设置为同步
  364. $.post(url, data, success)
  365. $.ajaxSettings.async = true;
  366. }
  367.  
  368. //获取指定名称的cookie的值
  369. function getcookie(objname){
  370. var arrstr = document.cookie.split("; ");
  371. for(var i = 0;i < arrstr.length;i ++){
  372. var temp = arrstr[i].split("=");
  373. if(temp[0] == objname) return unescape(temp[1]);
  374. }
  375. }
  376.  
  377. //获取get参数
  378. function GetRequest() {
  379. var url = location.search; //获取url中"?"符后的字串
  380. var theRequest = new Object();
  381. if (url.indexOf("?") != -1) {
  382. var str = url.substr(1);
  383. console.log("--------------", url, str)
  384. var strs = str.split("&");
  385. for(var i = 0; i < strs.length; i ++) {
  386. theRequest[strs[i].split("=")[0]]=decodeURI(strs[i].split("=")[1]);
  387. }
  388. }
  389. return theRequest;
  390. }
  391.  
  392.  
  393. //==========以下是与下载器通讯=====================================================================
  394. var host = '127.0.0.1'
  395. ,port = '5678';
  396. function wsmessage(evt)
  397. {
  398. console.log(evt);
  399. var received_msg = evt.data;
  400. console.log("收到服务器的信息", received_msg);
  401. // ws.send(JSON.stringify(["https://www.bilibili.com/video/BV19E411D78Q?p=6","https://www.bilibili.com/video/BV19E411D78Q?p=3"]));
  402. // console.log(JSON.parse(received_msg));
  403. // 发送成功{id: 2333333, jsonrpc: "2.0", result: "a6ff40d33524229a"}
  404. // 开始下载{jsonrpc: "2.0", method: "aria2.onDownloadStart", params: [[gid: "a6ff40d33524229a"]]}
  405. // 下载完成{jsonrpc: "2.0", method: "aria2.onDownloadComplete", params: [[gid: "a6ff40d33524229a"]]}
  406. // 下载出错{jsonrpc: "2.0", method: "aria2.onDownloadError", params: [[gid: "a6ff40d33524229a"]]}
  407.  
  408. ShowTips("任务发送成功");
  409. };
  410. function wsclose()
  411. {
  412. console.log("连接关闭");
  413. // layui.use('layer', function(){
  414. // var layer = layui.layer;
  415. // layer.msg("连接关闭", {
  416. // icon: 1
  417. // });
  418. // });
  419. };
  420.  
  421. function RealDownload(url, out, dir)
  422. {
  423. console.log("RealDownload",url)
  424. console.log(JSON.stringify(url))
  425. // var json = MakeSendData(url, out, dir)
  426. var ws = new WebSocket("ws://" + host + ":" + port + "/jsonrpc");
  427.  
  428. function wsopen()
  429. {
  430. console.log("连接下载服务器");
  431. // var json = MakeSendData("http://aria2c.com/usage.html", "test.html", "./dow")
  432. // ws.send(JSON.stringify(["https://www.bilibili.com/video/BV19E411D78Q?p=5","https://www.bilibili.com/video/BV19E411D78Q?p=3"]));
  433. ws.send(JSON.stringify(url));
  434.  
  435. setTimeout(function() {
  436. ws.close()
  437. }, 10000)
  438. };
  439.  
  440. setTimeout(function() {
  441. if (ws.readyState===1) {
  442. //连接成功什么事情都不用处理
  443. }else{
  444. ShowTips("连接下载器失败,请确认开启下载器");
  445. }
  446. }, 1000)
  447.  
  448. ws.onopen = wsopen;
  449. ws.onmessage = wsmessage;
  450. ws.onclose = wsclose;
  451. };
  452.  
  453. function CreateWs(cb) {
  454. var ws = new WebSocket("ws://" + host + ":" + port + "/jsonrpc");
  455. function wsopen()
  456. {
  457. console.log("连接下载服务器");
  458. if (cb) {cb()}
  459. // var json = MakeSendData("http://aria2c.com/usage.html", "test.html", "./dow")
  460. // ws.send(JSON.stringify(["https://www.bilibili.com/video/BV19E411D78Q?p=5","https://www.bilibili.com/video/BV19E411D78Q?p=3"]));
  461. // ws.send(JSON.stringify(url));
  462. };
  463.  
  464. setTimeout(function() {
  465. if (ws.readyState===1) {
  466. //连接成功什么事情都不用处理
  467. }else{
  468. ShowTips("连接下载器失败,请确认开启下载器");
  469. }
  470. }, 1000)
  471.  
  472. ws.onopen = wsopen;
  473. ws.onmessage = wsmessage;
  474. ws.onclose = wsclose;
  475.  
  476. return ws
  477. }
  478.  
  479. function SendMsg(ws, data, isclose) {
  480. console.log("SendMsg readyState",ws.readyState)
  481. if (ws.readyState != 1) {
  482. ws = CreateWs(function() {
  483. SendMsg(ws, data, isclose)
  484. })
  485. return
  486. }
  487. ws.send(JSON.stringify(data));
  488. if (isclose) {
  489. setTimeout(function() {
  490. ws.close()
  491. }, 1000)
  492. }
  493. }
  494.  
  495. var g_ws = CreateWs()
  496.  
  497.  
  498. //===============================================================================
  499.  
  500. // 拷贝我的收藏视频网址
  501. function CopyFavlistUrls() {
  502.  
  503. var title = "我的收藏"
  504.  
  505. var x = document.getElementsByClassName("fav-video-list clearfix content")[0].children;
  506. console.log(title)
  507.  
  508. var list = [];
  509. console.log(x)
  510. for (var i = 0; i < x.length; i++) {
  511. console.log(i,x[i].attributes["class"].nodeValue)
  512.  
  513. if (x[i].attributes["class"].nodeValue != "small-item disabled") { //失效
  514. //list[i] = x[i];
  515. list.push(x[i])
  516. }
  517. }
  518.  
  519. console.log(list)
  520. // zoomfile
  521. if (list) {
  522.  
  523. // GM_setClipboard( list.map(function (pin) {
  524. // return "https:" + pin.children[0].attributes["href"].nodeValue + "\r\n";
  525. // }).join(""));
  526.  
  527. return list.map(function (pin) {
  528. var item = {"url": "https:" + pin.children[1].attributes["href"].nodeValue};
  529. item.folder = "我的收藏"
  530. item.islist = false;
  531. item.fileName=Trim(pin.children[1].title)
  532. return item;
  533. })
  534. }else
  535. {
  536. ShowTips("找不到视频");
  537. }
  538. }
  539.  
  540. // 拷贝播放列表视频网址
  541. function CopyVedioUrls() {
  542. var title = Trim(document.querySelector('meta[property="og:title"]').getAttribute('content'));//FormatTitle("_哔哩哔哩(゜-゜)つロ干杯~-bilibili")
  543.  
  544. var list_box = document.getElementsByClassName("list-box")
  545. if (list_box.length == 0) {
  546.  
  547.  
  548. var list_box = document.getElementsByClassName("video-sections-content-list") // sections
  549. if (list_box.length > 0) {//需要读页面信息
  550. console.log("------list_box.length---------")
  551. CopySeasonUrls()
  552. return
  553. }else{
  554. return DownloadSelfInfo()
  555. }
  556. }
  557.  
  558. var x = document.getElementsByClassName("list-box")[0].children;
  559. console.log(title)
  560.  
  561. var list = [];
  562. console.log(x)
  563. for (var i = 0; i < x.length; i++) {
  564. list[i] = x[i];
  565. }
  566.  
  567. console.log(list)
  568. if (list) {
  569. return list.map(function (pin,index) {
  570. var item = {"url": "https://www.bilibili.com" + pin.children[0].attributes["href"].nodeValue}
  571. item.folder = Trim(title, 30)
  572. item.fileName = Trim(pin.children[0].title)
  573. item.islist = false;
  574. return item;
  575. })
  576. }else
  577. {
  578. ShowTips("找不到视频");
  579. }
  580. }
  581. // 拷贝番剧播放列表视频网址
  582. function CopyBangumiUrls() {
  583. jQuery.ajax({
  584. url: window.location.href,
  585. async: false,
  586. success: function (res) {
  587. // console.log(res);
  588. var info = res
  589.  
  590. var n = info.lastIndexOf("<script>window.__INITIAL_STATE__");
  591. if (n >= 0) {
  592. info = info.substring(n+"<script>window.__INITIAL_STATE__=".length);
  593. var n2 = info.indexOf(";(function(){var s;(s=document.currentScript||document.scripts[document.scripts.length-1]).parentNode.removeChild(s);}());</script>");
  594. // console.log("1111",n, n2,info)
  595. info = info.substring(0,n2);
  596. }
  597. var bili_state = JSON.parse(info)
  598. if (bili_state) {
  599.  
  600. console.log(bili_state)
  601. var epList = bili_state.epList
  602. var title = bili_state.mediaInfo.title
  603. var ssType = bili_state.ssType
  604. // console.log(bili_state.epList)
  605. // console.log("epList =", epList, "mediaInfo = ", mediaInfo)
  606. // for (var i = 0; i < epList.length; i++) {
  607. // console.log(i, epList[i])
  608. // }
  609.  
  610. // if (ssType==1) { //番剧
  611.  
  612. var urls = epList.map(function (ep) {
  613. var item = {
  614. "url": "https://www.bilibili.com/bangumi/play/ep"+ ep.id,
  615. "titleFormat":Trim(ep.titleFormat),
  616. "longTitle":Trim(ep.longTitle),
  617. "fileName":Trim(ep.titleFormat+"_"+ep.longTitle)
  618. }
  619. if (ep.longTitle == "") {
  620. item.fileName = Trim(ep.titleFormat)
  621. }
  622. item.folder = Trim(title, 30)
  623. item.islist = false;
  624. return item;
  625. })
  626. Download(urls)
  627. // }else
  628. // {// 电影
  629. // DownloadSelf(title, false)
  630. // }
  631. }else
  632. {
  633. var title = document.querySelector('meta[property="og:title"]').getAttribute('content');
  634. DownloadSelf(title, true)
  635. }
  636. },
  637. omplete: function (data) {
  638. if (data.status === 200) {
  639. }
  640. else {
  641. ShowTips("系统错误:暂时无法连接服务器")
  642. var title = document.querySelector('meta[property="og:title"]').getAttribute('content');
  643. DownloadSelf(title, true)
  644. }
  645. }
  646. });
  647. }
  648.  
  649. // vedio 中的season
  650. function CopySeasonUrls() {
  651. jQuery.ajax({
  652. url: window.location.href,
  653. async: false,
  654. success: function (res) {
  655. // console.log(res);
  656. var info = res
  657.  
  658. var n = info.lastIndexOf("<script>window.__INITIAL_STATE__");
  659. if (n >= 0) {
  660. info = info.substring(n+"<script>window.__INITIAL_STATE__=".length);
  661. var n2 = info.indexOf(";(function(){var s;(s=document.currentScript||document.scripts[document.scripts.length-1]).parentNode.removeChild(s);}());</script>");
  662. // console.log("1111",n, n2,info)
  663. info = info.substring(0,n2);
  664. }
  665. var bili_state = JSON.parse(info)
  666. if (bili_state) {
  667.  
  668. console.log(bili_state)
  669. var sectionsInfo = bili_state.sectionsInfo
  670. var title = sectionsInfo.title
  671. var sections = bili_state.sections
  672.  
  673. var urls = [];
  674. console.log(sections, "-----sections---")
  675. for (var i = 0; i < sections.length; i++) {
  676. var episodes = sections[i].episodes
  677. for (var j = 0; j < episodes.length; j++) {
  678. var ep = episodes[j]
  679. console.log(i, ep)
  680.  
  681. var item = {
  682. "url": "https://www.bilibili.com/video/"+ ep.bvid,
  683. "fileName":Trim(ep.title)
  684. }
  685. item.folder = Trim(title, 30)
  686. item.islist = false;
  687. urls.push(item)
  688. }
  689. }
  690.  
  691. console.log(urls)
  692. Download(urls)
  693.  
  694. }else
  695. {
  696. var title = document.querySelector('meta[property="og:title"]').getAttribute('content');
  697. DownloadSelf(title, true)
  698. }
  699. },
  700. omplete: function (data) {
  701. if (data.status === 200) {
  702. }
  703. else {
  704. ShowTips("系统错误:暂时无法连接服务器")
  705. var title = document.querySelector('meta[property="og:title"]').getAttribute('content');
  706. DownloadSelf(title, true)
  707. }
  708. }
  709. });
  710. }
  711.  
  712. function DownloadSelf(title, islist, youtube) {
  713. Download(DownloadSelfInfo(title, islist, youtube))
  714. }
  715.  
  716. function DownloadSelfInfo(title, islist, youtube) {
  717. var item = {"url": window.location.href.replace(/&/g, '%26')}
  718. // item.folder = Trim(title); // 不能有空格,有时候下载失败是因为有空格
  719.  
  720. if (!title) {
  721. title = Trim(document.title)
  722. }
  723. if (!islist) {
  724. islist = false
  725. }
  726. item.fileName = Trim(title)
  727. item.islist = islist;
  728. var host = getEffectiveHost()
  729. if (host == "youku" || host=="eduyun") {
  730. item.youtube = true
  731. }
  732. return [item]
  733. }
  734.  
  735.  
  736. // 解析bilibili网站
  737. function ParseBilibiliUrl() {
  738. var arrUrl = window.location.pathname.split('/');
  739. console.log("arrUrl = ", arrUrl);
  740. if(!arrUrl[1]) return;
  741. if (arrUrl[1] == "video")
  742. return CopyVedioUrls();
  743. else if (arrUrl[1] == "bangumi")
  744. return CopyBangumiUrls();
  745. else if (arrUrl[2] == "favlist")
  746. return CopyFavlistUrls();
  747. else
  748. {
  749. return DownloadSelfInfo()
  750. }
  751. }
  752.  
  753. // 解析优酷网站
  754. function ParseYoukuUrl() {
  755. var arrUrl = window.location.pathname.split('/');
  756. console.log("arrUrl = ", arrUrl);
  757.  
  758. if(!arrUrl[1]) return;
  759. if (arrUrl[1] == "v_show")
  760. {
  761. var title = Trim(document.querySelector('meta[name="irAlbumName"]').getAttribute('content'));
  762. var l = document.getElementsByClassName("anthology-content")
  763. if (l.length == 2) {
  764. var x = document.getElementsByClassName("anthology-content")[0].children;
  765. var list = objToArray(x)
  766. if (list) {
  767. return list.map(function (pin) {
  768. var item = {"url": pin.children[0].attributes["href"].nodeValue}
  769. item.saveFileName = Trim(pin.title) //优酷下载的名称没有第几集, 所以需要重命名
  770. item.fileName = Trim(item.saveFileName)
  771. item.folder = Trim(title, 30)
  772. item.islist = false;
  773. item.youtube = true
  774. return item;
  775. })
  776. }
  777. }
  778. }
  779.  
  780. return DownloadSelfInfo(null, false, true)
  781. }
  782.  
  783. // 解析腾讯视频网站
  784. function ParseQQUrl() {
  785. var arrUrl = window.location.pathname.split('/');
  786. console.log("arrUrl = ", arrUrl);
  787.  
  788. if(!arrUrl[1]) return;
  789. if (arrUrl[1] == "x")
  790. {
  791. var player_title = document.getElementsByClassName("player_title")
  792. if (player_title.length==0) {
  793. }else{
  794. var x
  795. var title = Trim(document.getElementsByClassName("player_title")[0].children[0].text); //player_title
  796. var items = document.getElementsByClassName("figure_list _hot_wrapper")
  797. var item_detail_half = document.getElementsByClassName("item_detail_half")
  798. var mod_episode = document.getElementsByClassName("mod_episode")
  799.  
  800. if (items.length>0) {
  801. x = items[0].children;
  802. var list = objToArray(x)
  803. // console.log(list)
  804. if (list) {
  805. return list.map(function (pin) {
  806. // console.log(pin)
  807. var item = {"url": "https://v.qq.com" + pin.children[0].attributes["href"].nodeValue}
  808. item.fileName = Trim(pin.attributes["data-title"].nodeValue)
  809. item.folder = Trim(title,30)
  810. item.islist = false;
  811. return item;
  812. })
  813. }
  814. }
  815.  
  816. if(item_detail_half.length>0){
  817. x = document.getElementsByClassName("item_detail_half")
  818. var list = objToArray(x)
  819. // console.log(list)
  820. if (list) {
  821. return list.map(function (pin) {
  822. console.log(pin)
  823. var item = {"url": "https://v.qq.com" + pin.children[0].attributes["href"].nodeValue}
  824. item.fileName = Trim(pin.children[0].attributes["title"].nodeValue)
  825. item.folder = Trim(title,30)
  826. item.islist = false;
  827. return item;
  828. })
  829. }
  830. }
  831. if (mod_episode.length>0) {
  832. x = mod_episode[0].children;
  833. var list = objToArray(x)
  834. // console.log(list)
  835. if (list) {
  836. return list.map(function (pin) {
  837. // console.log(pin)
  838. if (pin.children[0].attributes["href"]) {
  839. var item = {"url": "https://v.qq.com" + pin.children[0].attributes["href"].nodeValue}
  840. item.fileName = "第"+Trim(pin.innerText) +"集"
  841. item.folder = Trim(title,30)
  842. item.islist = false;
  843. return item;
  844. }
  845. })
  846. }
  847. }
  848. // innerText
  849. }
  850. }
  851.  
  852. return DownloadSelfInfo()
  853. }
  854.  
  855. // 解析爱奇艺网站
  856. function ParseIqiyiUrl() {
  857. var title = Trim(document.querySelector('meta[name="irAlbumName"]').getAttribute('content'));
  858. var x = document.getElementsByClassName("select-title"); //专辑
  859. var list = objToArray(x)
  860.  
  861. if (list.length > 0) {
  862. return list.map(function (pin) {
  863. var item = {"url": "https:" + pin.children[1].attributes["href"].nodeValue}
  864. item.saveFileName = Trim(pin.children[0].innerText+"_"+pin.children[1].text)
  865. item.fileName = Trim(item.saveFileName)
  866. item.folder = Trim(title,30)
  867. item.islist = false;
  868. return item;
  869. })
  870. }else
  871. {
  872. return DownloadSelfInfo()
  873. }
  874. }
  875.  
  876. function GetEduyunCaseObj(caseCode) {
  877. // var obj2 = eval(xueduanJson);
  878. var caseobj = eval(caseJson);
  879. var caseobjlen = caseobj.clist.length;
  880. for(var a =0 ;a<caseobjlen;a++){
  881. var caseobjcode = caseobj.clist[a].caseCode;
  882.  
  883. if(caseobjcode == caseCode){
  884. return caseobj.clist[a]
  885. }
  886. }
  887. }
  888.  
  889. function GetEduyunM3u8(config) {
  890. console.log(config)
  891. var video_extend = config.video_extend;
  892. console.log(video_extend)
  893. var bestid = 0;
  894. var bestquality = 1;
  895. for (var i = 0; i < video_extend.files.length; i++) {
  896. var item = video_extend.files[i];
  897. if (item.height >= bestquality) {
  898. bestquality = item.height;
  899. bestid = i;
  900. }
  901. }
  902. return video_extend.urls[bestid].urls[0]
  903. }
  904.  
  905. // 解析国家中小学网络云课堂网站
  906. function ParseEduyunUrl() {
  907. var urlParm = GetRequest();
  908. console.log(urlParm);
  909.  
  910. var url = "https://s-file-2.ykt.cbern.com.cn/zxx/ndrv2/national_lesson/resources/details/" + urlParm.activityId +".json"
  911.  
  912. // // 视频信息
  913. // var url = "https://s-file-1.ykt.cbern.com.cn/zxx/s_course/v1/x_class_hour_activity/" + urlParm.activityId +".json"
  914. // WebGet(url, function(res) {
  915. // console.log(res)
  916. // WebGet("https://s-file-1.ykt.cbern.com.cn/zxx/s_course/v1/x_class_hour_activity/" + urlParm.activityId +"/resources.json",
  917. // function(res2) {
  918. // console.log(res2)
  919. // for (var i = 0; i < res2.length; i++) {
  920. // var it = res2[i];
  921. // if (it.resource_type == "video") {
  922. // console.log("----", it)
  923.  
  924. // var urls = []
  925. // var item = {"url":GetEduyunM3u8(it)}
  926. // item.saveFileName = Trim(res.name)
  927. // item.fileName = Trim(item.saveFileName)
  928. // item.folder = Trim(res.activity_set_name)
  929. // item.islist = false;
  930. // item.m3u8 = true
  931. // urls.push(item)
  932. // console.log(urls)
  933. // Download(urls)
  934. // }
  935. // }
  936. // })//WebGet 2
  937. // })//WebGet 1
  938.  
  939.  
  940.  
  941. WebGet("https://r1-ndr-private.ykt.cbern.com.cn/edu_product/65/video/17b0594b547a11eb96b8fa20200c3759/158bfc80999d1a8a01c504fce1012e6b.1920.1080.false/158bfc80999d1a8a01c504fce1012e6b.1920.1080.m3u8",
  942. function(res){
  943. console.log("-----private----",res)
  944. }, {
  945. "x-nd-auth": 'MAC id="7F938B205F876FC3A30551F3A4931383757DAFBA42F543C27D4FAAD9900F58A908688DD0730726915939914BD846259C990406ECD76F1590",nonce="1689319206522:3JWAHCSX",mac="bRyywGyMJ7nn9HZE1piMfV6KL11l0X5wOJ+exMyXEDY="'
  946. })
  947. }
  948.  
  949. // 解析微元素
  950. function ParseElement3ds() {
  951. var json = {};
  952. var title = document.title
  953. var n = title.lastIndexOf("-微元素");
  954. if (n >= 0) {
  955. title = title.substring(0,n);
  956. var n2 = title.lastIndexOf("-");
  957. if (n2 >= 0) {
  958. title = title.substring(0,n2);
  959. }
  960. }
  961. // title = "#title:" + title + "\n"
  962.  
  963. var x = document.getElementsByClassName("zoom");
  964. console.log(title)
  965.  
  966. var list = objToArray(x)
  967. console.log(list)
  968.  
  969. if (list) {
  970. var res= list.map(function (pin) {
  971. var url = pin.attributes["zoomfile"].nodeValue
  972. var n = url.lastIndexOf("?");
  973. if (n >= 0) {
  974. url = url.substring(0,n);
  975. }
  976. var item = {"url": url}
  977. item.saveFileName = Trim(GetFileName(url))
  978. item.fileName = Trim(item.saveFileName)
  979. item.folder = Trim(title,30)
  980. item.islist = false;
  981. item.image = true
  982. return item;
  983. })
  984.  
  985. RealDownload(res) // 图片直接下载就是了, 不提供选择
  986. ShowDialog("获取到"+res.length+"张图片,已经发送到下载器")
  987. }else
  988. {
  989. ShowTips("找不到图片")
  990. }
  991. }
  992.  
  993.  
  994.  
  995. function packageImages(list, index){
  996. // $('#status').text('处理中。。。。。');
  997. var imgsSrc = [];
  998. var imgBase64 = [];
  999. var imageSuffix = [];//图片后缀
  1000. var zip = new JSZip();
  1001. // zip.file("readme.txt", "案件详情资料\n");
  1002. var img = zip.folder("images");
  1003. for(var i=0;i<list.length;i++){
  1004. var src = list[i];
  1005. var suffix = src.substring(src.lastIndexOf("."));
  1006. imageSuffix.push(suffix);
  1007. getBase64(list[i])
  1008. .then(function(base64){
  1009. imgBase64.push(base64.substring(22));
  1010. },function(err){
  1011. console.log(err);//打印异常信息
  1012. });
  1013. }
  1014. function tt(){
  1015. setTimeout(function(){
  1016. if(list.length == imgBase64.length){
  1017. for(var i=0;i<list.length;i++){
  1018. img.file(i+imageSuffix[i], imgBase64[i], {base64: true});
  1019. }
  1020. zip.generateAsync({type:"blob"}).then(function(content) {
  1021. saveAs(content, "images"+index+".zip");
  1022. });
  1023. $('#status').text('处理完成。。。。。');
  1024. }else{
  1025. $('#status').text('已完成:'+imgBase64.length+'/'+list.length);
  1026. tt();
  1027. }
  1028. },100);
  1029. }
  1030. tt();
  1031. }
  1032. function packageImages2(list, index){
  1033. // $('#status').text('处理中。。。。。');
  1034. var imgsSrc = [];
  1035. var imgBase64 = [];
  1036. var imageSuffix = [];//图片后缀
  1037. var zip = new JSZip();
  1038. // zip.file("readme.txt", "案件详情资料\n");
  1039. var img = zip.folder("images");
  1040. for(var i=0;i<list.length;i++){
  1041. var src = list[i];
  1042. var suffix = src.substring(src.lastIndexOf("."));
  1043. imageSuffix.push(suffix);
  1044. getBase64(list[i])
  1045. .then(function(base64){
  1046. imgBase64.push(base64.substring(22));
  1047. },function(err){
  1048. console.log(err);//打印异常信息
  1049. });
  1050. }
  1051. function tt(){
  1052. setTimeout(function(){
  1053. if(list.length == imgBase64.length){
  1054. for(var i=0;i<list.length;i++){
  1055. img.file(i+".jpeg", imgBase64[i], {base64: true});
  1056. }
  1057. zip.generateAsync({type:"blob"}).then(function(content) {
  1058. saveAs(content, "images"+index+".zip");
  1059. });
  1060. $('#status').text('处理完成。。。。。');
  1061. }else{
  1062. $('#status').text('已完成:'+imgBase64.length+'/'+list.length);
  1063. tt();
  1064. }
  1065. },100);
  1066. }
  1067. tt();
  1068. }
  1069. //传入图片路径,返回base64
  1070. function getBase64(img){
  1071. function getBase64Image(img,width,height) {
  1072. var canvas = document.createElement("canvas");
  1073. canvas.width = width ? width : img.width;
  1074. canvas.height = height ? height : img.height;
  1075. var ctx = canvas.getContext("2d");
  1076. ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  1077. var dataURL = canvas.toDataURL();
  1078. return dataURL;
  1079. }
  1080. var image = new Image();
  1081. image.crossOrigin = 'Anonymous';
  1082. image.src = img;
  1083. var deferred=$.Deferred();
  1084. if(img){
  1085. image.onload =function (){
  1086. deferred.resolve(getBase64Image(image));
  1087. }
  1088. return deferred.promise();
  1089. }
  1090. }
  1091.  
  1092.  
  1093.  
  1094. // 解析微博相册
  1095. function ParseWeiboPhoto() {
  1096. console.log("--------------------")
  1097. // // $GLOBAL_INFO.owner_uid //拥有者id
  1098. // // $GLOBAL_DETAIL.page_album_id //相册id
  1099. // // $GLOBAL_DETAIL.album_info.count.photos //图片数量
  1100. // var count = $GLOBAL_DETAIL.album_info.count.photos
  1101. // var page = Math.floor(count/30+1)
  1102. // var owner_data = $GLOBAL_INFO.owner_data
  1103. // var totalcount = 0
  1104.  
  1105. // function download(i){
  1106. // setTimeout(function() {
  1107. // var t = new Date().getTime()
  1108. // var url = "https://photo.weibo.com/photos/get_all?uid="+$GLOBAL_INFO.owner_uid+"&album_id="+$GLOBAL_DETAIL.page_album_id+"&count=30&page="+i+"&type=3&__rnd="+t
  1109. // console.log(url)
  1110. // WebGet(url, function(res) {
  1111. // console.log(res)
  1112. // if (res.code == 0) {
  1113. // var list = res.data.photo_list
  1114. // var arr= list.map(function (pin) {
  1115. // // var node = pin.children[0].href
  1116. // var url = "https://wx3.sinaimg.cn/large/" + pin.pic_name
  1117. // var item = {"url": url}
  1118. // item.saveFileName = pin.pic_name
  1119. // item.fileName = Trim(item.saveFileName)
  1120. // item.folder = Trim(owner_data.name+"-"+$GLOBAL_DETAIL.album_info.caption,30)
  1121. // item.islist = false;
  1122. // item.image = true
  1123. // return item;
  1124. // })
  1125. // // console.log(arr)
  1126. // totalcount = totalcount + arr.length
  1127. // // console.log("----------------------------------------------", i, totalcount, arr.length)
  1128. // // RealDownload(arr) // 图片直接下载就是了, 不提供选择
  1129. // SendMsg(g_ws, arr)
  1130. // if (i+1 == page) {
  1131. // ShowDialog("获取到"+totalcount+"张图片,已经发送到下载器")
  1132. // }
  1133. // }//if (res.code == 0)
  1134. // })//WebGet
  1135. // }, 1000*i)//setTimeout
  1136. // }
  1137.  
  1138. // for (var i = 0; i < page; i++) {
  1139. // //https://photo.weibo.com/photos/get_all?uid=5538396801&album_id=3814561462485240&count=30&page=2&type=3&__rnd=1621934381145
  1140. // // https://photo.weibo.com/photos/get_all?uid=5538396801&album_id=3814561462485240&count=30&page=11&type=3&__rnd=1621998700612
  1141. // download(i+1)
  1142. // }
  1143.  
  1144.  
  1145. var x = document.getElementsByClassName("woo-picture-square");
  1146.  
  1147. var list = [];
  1148. console.log(x)
  1149. for (var i = 0; i < x.length; i++) {
  1150. // console.log(i,x[i].attributes["class"].nodeValue)
  1151.  
  1152. if (x[i].children[0].attributes["src"].nodeValue) {
  1153. // console.log(i, x[i].children[0].attributes["src"].nodeValue)
  1154. // https://wx1.sinaimg.cn/orj360/005E6opCgy1h7ivrosiucj33402c0kjm.jpg
  1155. // https://wx3.sinaimg.cn/mw2000/005E6opCgy1gf963ss9i1j30qo0g275o.jpg
  1156. // https://wx1.sinaimg.cn/webp720/005E6opCgy1h7ivrosiucj33402c0kjm.jpg
  1157. var url = x[i].children[0].attributes["src"].nodeValue
  1158. url = url.replace(/orj360/g,"mw2000");
  1159. list.push(url)
  1160. }
  1161. }
  1162.  
  1163. console.log("list",list)
  1164. // zoomfile
  1165. if (list) {
  1166.  
  1167. GM_setClipboard("["+ list.map(function (url) {
  1168. return "\""+url+"\"";
  1169. }).join(",\n")+"]");
  1170.  
  1171. var pnum = parseInt(list.length/50 + 1)
  1172. for (var i = 0; i < pnum; i++) {
  1173. var plist = []
  1174. for (var j = 0; j < 50; j++) {
  1175. var index = i*50+j
  1176.  
  1177. if (index<list.length) {
  1178. plist.push(list[index])
  1179. }
  1180. }
  1181. packageImages(plist, i);
  1182. }
  1183.  
  1184.  
  1185. // return list.map(function (url) {
  1186. // var arrUrl = url.split('/');
  1187. // var item = {"url": url};
  1188. // item.folder = "我的收藏"
  1189. // item.islist = false;
  1190. // item.fileName=arrUrl[arrUrl.length-1]
  1191. // return item;
  1192. // })
  1193. }else
  1194. {
  1195. ShowTips("相册空空");
  1196. }
  1197. }
  1198.  
  1199. // 微信
  1200. function ParseWeixinPhoto() {
  1201. console.log("--------ParseWeixinPhoto------------")
  1202. var x = document.getElementsByClassName("rich_pages wxw-img js_insertlocalimg");
  1203.  
  1204. var list = [];
  1205. console.log(x)
  1206. for (var i = 0; i < x.length; i++) {
  1207. console.log(i,x[i].attributes["src"].nodeValue)
  1208.  
  1209. var url = x[i].attributes["data-src"].nodeValue
  1210. list.push(url)
  1211. }
  1212.  
  1213. console.log("list",list)
  1214. // zoomfile
  1215. if (list) {
  1216. var i= 0;
  1217. var res= list.map(function (pin) {
  1218. i++;
  1219. var item = {"url": pin}
  1220. item.fileName = i+".jpeg"
  1221. item.saveFileName = i+".jpeg"
  1222. item.folder = Trim(document.title,30)
  1223. item.islist = false;
  1224. item.image = true
  1225. return item;
  1226. })
  1227. RealDownload(res) // 图片直接下载就是了, 不提供选择
  1228. }else
  1229. {
  1230. ShowTips("相册空空");
  1231. }
  1232. }
  1233. // 解析花瓣
  1234. function ParseHuabanPhoto() {
  1235. var arrUrl = window.location.pathname.split('/');
  1236. console.log("arrUrl = ", arrUrl);
  1237. if(!arrUrl[1]) return;
  1238. if (arrUrl[1] == "boards")
  1239. return ParseHuabanBoards(arrUrl[2]);
  1240. else if (arrUrl[1] == "user")
  1241. return ParseHuabanUser(arrUrl[2]);
  1242. }
  1243.  
  1244. function cbGetBoardsFirst(res, board_id) {
  1245. console.log(res, res.hasOwnProperty('board'));
  1246. var limit = 100
  1247. var board_data = res.board,
  1248. title=board_data.title,
  1249. //画板图片总数
  1250. pin_number = board_data.pin_count,
  1251. board_pins = res.pins,
  1252. user_id = board_data.user.urlname,
  1253. username = board_data.user.username,
  1254. //尝试向上取整,计算加载完画板图片需要的最大次数
  1255. retry = board_pins.length < pin_number ? Math.ceil(pin_number / limit) : 0
  1256. console.log('Current board <' + board_id + '> pins number is ' + pin_number +
  1257. ', first pins number is ' +board_pins.length +', retry is ' + retry )
  1258. var bf = setInterval(function () {
  1259. if (retry > 0) {
  1260. //说明没有加载完画板图片,需要ajax请求
  1261.  
  1262. //get ajax pin data
  1263. var last_pin = board_pins[board_pins.length - 1].pin_id
  1264. var board_next_url = "https://api.huaban.com/boards/" + board_id + "/pins?max="+last_pin+"&limit="+limit
  1265.  
  1266. WebGet(board_next_url, function (res) {
  1267. console.log(res);
  1268. var board_next_data = res
  1269. board_pins = board_pins.concat(
  1270. board_next_data.pins
  1271. )
  1272. console.debug( 'ajax load board with pin_id ' + last_pin + ', get pins number is ' +
  1273. board_next_data.pins.length + ', merged')
  1274. if (
  1275. board_next_data.pins.length ===
  1276. 0
  1277. ) {
  1278. retry = 0
  1279. return false
  1280. }
  1281. last_pin = board_next_data.pins[board_next_data.pins.length - 1].pin_id
  1282. })
  1283. retry--
  1284. } else {
  1285. console.log( '画板' + board_id + '共抓取' + board_pins.length + '个pin')
  1286. var pins = board_pins.map(function (pin) {
  1287. var suffix = !pin.file.type
  1288. ? 'png'
  1289. : pin.file.type.split('/')[1]
  1290. return {
  1291. url:
  1292. window.location.protocol +
  1293. '//hbimg.huabanimg.com/' +
  1294. pin.file.key,
  1295. pic_name: pin.pin_id + '.' + suffix
  1296. }
  1297. })
  1298. clearInterval(bf)
  1299. cbGetBoardsData(board_id, pins, title, username)
  1300. }
  1301. }, 200)
  1302. }
  1303.  
  1304. function cbGetBoardsData(board_id, pins, title, username) {
  1305. console.log("获取到的数据",board_id, pins, title, username)
  1306.  
  1307. var list = pins
  1308. var arr= list.map(function (pin) {
  1309. var item = {"url": pin.url}
  1310. item.saveFileName = pin.pic_name
  1311. item.fileName = item.saveFileName
  1312. item.folder = username+"/"+title
  1313. item.islist = false;
  1314. item.image = true
  1315. return item;
  1316. })
  1317. // console.log(arr)
  1318. // console.log("----------------------------------------------", i, totalcount, arr.length)
  1319. // RealDownload(arr) // 图片直接下载就是了, 不提供选择
  1320. SendMsg(g_ws, arr)
  1321. ShowDialog("获取画板["+title+"]图片"+arr.length+"张图片")
  1322. }
  1323.  
  1324. // 解析花瓣画板
  1325. function ParseHuabanBoards(board_id) {
  1326.  
  1327. console.group('花瓣网下载-当前画板:' + board_id)
  1328. var limit = 100,
  1329. url = "https://api.huaban.com/boards/" + board_id + "/pins?limit=" + limit
  1330. // loadingLayer = layer.load(0, {
  1331. // time: 5000
  1332. // })
  1333. //get first pin data
  1334. WebGet(url,function (res) {
  1335. cbGetBoardsFirst(res, board_id)
  1336. })
  1337.  
  1338. console.groupEnd()
  1339.  
  1340. }
  1341. // 解析花瓣个人页面
  1342. function ParseHuabanUser(user_id) {
  1343. // https://api.huaban.com/xntnsowysb/boards?limit=30&order_by_updated=0
  1344. // https://api.huaban.com/xntnsowysb/boards?max=70779717&limit=30&order_by_updated=0
  1345. console.log("获取用户画板列表", user_id)
  1346. var url = "https://api.huaban.com/"+ user_id +"/boards?limit=30&order_by_updated=0"
  1347. WebGet(url, function(res){
  1348. console.log(res)
  1349. var user_data = res.user,
  1350. board_number = user_data.board_count,
  1351. board_ids = res.boards,
  1352. limit=30,
  1353. retry = board_ids.length < board_number
  1354. ? Math.ceil(board_number / limit)
  1355. : 0
  1356. console.debug(
  1357. 'Current user <' +
  1358. user_id +
  1359. '> boards number is ' +
  1360. board_number +
  1361. ', first boards number is ' +
  1362. board_ids.length +
  1363. ', retry is' +
  1364. retry
  1365. )
  1366. var uf = setInterval(function () {
  1367. if (retry > 0) {
  1368. var last_board = board_ids[board_ids.length - 1].board_id
  1369. //get ajax board data
  1370. var user_next_url = "https://api.huaban.com/"+user_id+"/boards?max="+last_board+"&limit="+limit+"&order_by_updated=0"
  1371.  
  1372. WebGet(user_next_url, function (res) {
  1373. console.log(res);
  1374. var user_next_data = res.boards
  1375. board_ids = board_ids.concat(
  1376. user_next_data
  1377. )
  1378. console.debug(
  1379. 'ajax load user with board_id ' +
  1380. last_board +
  1381. ', get boards number is ' +
  1382. user_next_data.length +
  1383. ', merged'
  1384. )
  1385. if (user_next_data.length === 0) {
  1386. retry = 0
  1387. return false
  1388. }
  1389. last_board =
  1390. user_next_data[
  1391. user_next_data.length - 1
  1392. ].board_id
  1393. })
  1394. retry--
  1395. } else {
  1396. console.log(
  1397. '用户' +
  1398. user_id +
  1399. '共抓取' +
  1400. board_ids.length +
  1401. '个board'
  1402. )
  1403. var boards = board_ids.map(function (
  1404. board
  1405. ) {
  1406. return board.board_id
  1407. })
  1408. clearInterval(uf)
  1409. cbGetUserData(boards)
  1410. }
  1411. }, 200)
  1412. })
  1413. }
  1414. function cbGetUserData(boards) {
  1415. console.log("获取到的数据",boards)
  1416. var length = boards.length
  1417. var index = 0
  1418. var uf = setInterval(function () {
  1419. ParseHuabanBoards(boards[index])
  1420. ++index;
  1421. if (index>=length) {
  1422. clearInterval(uf)
  1423. }
  1424. }, 200)
  1425. }
  1426.  
  1427.  
  1428. // 中国大学慕课网
  1429. function ParseMooc() {
  1430. console.log("----------ParseMooc--------------")
  1431. Function.prototype.constructor = function(){} // 使用调试
  1432. var urlParm = GetRequest();
  1433. console.log(urlParm);
  1434. console.log(getcookie("NTESSTUDYSI"), urlParm.tid)
  1435.  
  1436. // 1.获取列表
  1437. var url = "https://www.icourse163.org/web/j/courseBean.getLastLearnedMocTermDto.rpc?csrfKey="+getcookie("NTESSTUDYSI");
  1438. var list = [];
  1439. WebPost(url, {"termId":urlParm.tid}, function(res){
  1440. console.log("----------WebPost--------------")
  1441. console.log(res)
  1442. if (res.code == 0) {
  1443. var courseName = res.result.mocTermDto.courseName
  1444. var chapters = res.result.mocTermDto.chapters
  1445. console.log(res.result.mocTermDto.chapters)
  1446. for (var i = 0; i < chapters.length; i++) {
  1447. var item = chapters[i]
  1448. var chapter_name = item.name
  1449. var lessons = item.lessons // 数组
  1450.  
  1451. if (!lessons) {continue;}
  1452. for (var j = 0; j < lessons.length; j++) {
  1453. var units = lessons[j].units //数组
  1454. var name = lessons[j].name
  1455.  
  1456. for (var k = 0; k < units.length; k++) {
  1457. var lesson = units[k]
  1458. var file_name = lesson.name
  1459. //var chapterId = lesson.chapterId
  1460. var contentId = lesson.contentId
  1461. var id = lesson.id
  1462. var contentType = lesson.contentType// 1视频 3pdf 6老师课堂交流区
  1463. if (contentType==1) {
  1464. list.push({"id":id, "contentId":contentId, "contentType":contentType,
  1465. "bizType":contentType,
  1466. "name":chapter_name+"_"+file_name, "folder":chapter_name})
  1467. }
  1468. // GetMoocResourceInfo(id, contentId, contentType, contentType)
  1469. }
  1470. }
  1471. }
  1472. }
  1473. console.log("list = ", list)
  1474. var urls=[]
  1475. for (var i = 0; i < list.length; i++) {
  1476. GetMoocResourceInfo(list[i])
  1477. }
  1478. console.log("list = ", list)
  1479. })
  1480. var title = Trim(document.title)
  1481. var res= list.map(function (pin) {
  1482. var item = {"url": pin.url}
  1483. item.saveFileName = Trim(pin.name)
  1484. item.fileName = item.saveFileName
  1485. item.folder = Trim(title,30)
  1486. item.islist = false;
  1487. //item.video = true;
  1488. if (isContains(pin.url, ".m3u8")) {
  1489. item.m3u8 = true;
  1490. }
  1491. return item;
  1492. })
  1493. return res
  1494. // https://www.icourse163.org/web/j/resourceRpcBean.getResourceToken.rpc?csrfKey=7c1bc0e4212b467e972e7be9f8b5d34f
  1495. // post
  1496. // bizId: 550645
  1497. // bizType: 1
  1498. // contentType: 1
  1499.  
  1500. }
  1501.  
  1502. function GetMoocResourceInfo(data) {
  1503. var bizId = data.id
  1504. var contentId = data.contentId
  1505. var bizType = data.bizType
  1506. var contentType = data.contentType
  1507. var folder = data.folder
  1508. var url = "https://www.icourse163.org/web/j/resourceRpcBean.getResourceToken.rpc?csrfKey="+getcookie("NTESSTUDYSI");
  1509. if(contentType != 1) return;
  1510. // 获取token
  1511. WebPost(url, {"bizId":bizId,"bizType":bizType,"contentType":contentType }, function(res){
  1512. console.log("----------GetMoocResourceInfo--------------")
  1513. console.log(res)
  1514. // var list = [];
  1515. if (res.code == 0) {
  1516. // 真正获取信息
  1517. var signature = res.result.videoSignDto.signature;
  1518. var name = res.result.videoSignDto.name;
  1519. var url2 = "https://vod.study.163.com/eds/api/v1/vod/video?videoId="+contentId+"&signature="+signature+"&clientType=1"
  1520. WebGet(url2, function(res2) {
  1521. console.log("----------GetMoocResourceInfo2--------------", url2)
  1522. console.log(res2)
  1523. var videos = res2.result.videos
  1524. var resource_url = videos[0].videoUrl;
  1525. var size = 0;
  1526. // 找到品种最佳的视频下载
  1527. for (var i = 0; i < videos.length; i++) {
  1528. var item = videos[i]
  1529. if (item.size > size) {
  1530. size = item.size;
  1531. resource_url = item.videoUrl;
  1532. }
  1533. }
  1534.  
  1535. console.log("resource_url = ", resource_url)
  1536. data.url = resource_url
  1537. })
  1538. }
  1539. // console.log("list = ", list)
  1540. })
  1541. }
  1542.  
  1543.  
  1544. //获取可使用域名
  1545. function getEffectiveHost() {
  1546. var host = window.location.host;
  1547. if (!host) {
  1548. host = document.domain;
  1549. }
  1550. if (!host) {
  1551. host = "bilibili.com";
  1552. }
  1553. if (isContains(host, "bilibili")) {
  1554. host = "bilibili";
  1555. } else if (isContains(host, "youku")) {
  1556. host = "youku";
  1557. } else if (isContains(host, "iqiyi")) {
  1558. host = "iqiyi";
  1559. } else if (isContains(host, "weixin.qq.com")) {
  1560. host = "weixin";
  1561. } else if (isContains(host, "qq.com")) {
  1562. host = "qq";
  1563. } else if (isContains(host, "element3ds")) {
  1564. host = "element3ds";
  1565. } else if (isContains(host, "basic.smartedu.cn")) {
  1566. host = "eduyun";
  1567. } else if (isContains(host, "weibo.com")) {
  1568. host = "photo_weibo";
  1569. } else if (isContains(host, "huaban")) {
  1570. host = "huaban";
  1571. } else if (isContains(host, "icourse163")) {
  1572. host = "icourse163";
  1573. }
  1574. else {
  1575. host = "bilibili";
  1576. }
  1577. return host;
  1578. }
  1579.  
  1580. function ParseUrl() {
  1581. // console.log("----------------------222222",$.fn.jquery)
  1582. var host = getEffectiveHost()
  1583. console.log("host = ",host)
  1584. if (host == "bilibili") {
  1585. return ParseBilibiliUrl()
  1586. } else if (host == "youku") {
  1587. return ParseYoukuUrl()
  1588. } else if (host == "iqiyi") {
  1589. return ParseIqiyiUrl()
  1590. } else if (host == "qq") {
  1591. return ParseQQUrl()
  1592. } else if (host == "element3ds") {
  1593. return ParseElement3ds()
  1594. } else if (host == "eduyun") {
  1595. return ParseEduyunUrl()
  1596. } else if (host == "photo_weibo") {
  1597. return ParseWeiboPhoto()
  1598. } else if (host == "huaban") {
  1599. return ParseHuabanPhoto()
  1600. } else if (host == "weixin") {
  1601. return ParseWeixinPhoto()
  1602. } else if (host == "icourse163") {
  1603. return ParseMooc()
  1604. }
  1605. else {
  1606. return DownloadSelfInfo()
  1607. }
  1608. }
  1609.  
  1610. var isInit = 0;
  1611. function DoInit() {
  1612.  
  1613. // isInit ++;
  1614. // if (isInit != 2 ) {return}
  1615. // console.log("----------------DoInit-------------")
  1616. var btn = document.getElementsByClassName("btnDownload")
  1617. if (btn.length > 0) {
  1618. return
  1619. }
  1620.  
  1621. GMaddStyleString(`#download_movie_box {cursor:pointer; position:fixed; top:` + 60 + `px; left:` + 0 + `px; width:0px; background-color:#2E9AFE; z-index:2147483647; font-size:20px; text-align:left;}
  1622. #download_movie_box .item_text {width:28px; padding:4px 0px; text-align:center;}
  1623. #download_movie_box .item_text img {width:35px; height:35px; display:inline-block; vertical-align:middle;}
  1624. `);
  1625.  
  1626. // var $ = $ || window.$;
  1627. var ImgBase64Data = "data:image/png;base64,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"
  1628.  
  1629. var html =
  1630. `<div id='download_movie_box' class="btnDownload">
  1631. <div class='item_text'>
  1632. <img src='`+ ImgBase64Data +`' title='下载视频' id="downloadVideos"/>
  1633. </div>
  1634. </div>`;
  1635.  
  1636. document.body.insertAdjacentHTML('afterEnd', html);
  1637.  
  1638. document.getElementById("downloadVideos").onclick = function () {
  1639. var urls = ParseUrl();
  1640. console.log("urls = ",urls)
  1641. if (urls) {
  1642. Download(urls)
  1643. }
  1644. };
  1645. }
  1646. /*
  1647. 主入口,分出不同模块:用户、画板,监听并刷新URL
  1648. */
  1649. window.onload =function() {
  1650. DoInit()
  1651. }
  1652.  
  1653. // GM_setValue("mytset","mytset---------------------------")
  1654. // console.log(GM_getValue("mytset"))
  1655. })();
  1656.  

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址