油猴工具-西瓜下载脚本
本帖最后由 堂哥哥好帅 于 2023-6-27 09:11 编辑脚本的起源是为了给家里的老人下载戏剧,因为本地戏剧比较小众几乎找了许多视频平台最后发现只有西瓜平台有,所以想下载西瓜平台的视频下来。试着自己开发工具发现不是很好用,尝试了几种方案,而且看了许多的工具也都不好用,最后选择进行方案三脚本关联第三方下载程序进行开发。
代码:
// ==UserScript==
// @name 西瓜堂Down-西瓜视频下载工具
// @namespace Violentmonkey Scripts
// @match https://www.ixigua.com/*
// @grant none
// @version 1.0
// @license MIT
// @AuThor 堂哥哥
// @description 2023/06/23 15:06
// ==/UserScript==
let isInit = false;
// 初始化
function HTMLInit() {
// 如果是西瓜视频则加载迅雷的js
var g = document.createElement('script');
var s = document.getElementsByTagName('script');
g.setAttribute("src", "https://open.thunderurl.com/thunder-link.js");
s.parentNode.insertBefore(g, s);
isInit = true;
}
var _wr = function(type) {
var orig = history;
return function() {
var rv = orig.apply(this, arguments);
var e = new Event(type);
e.arguments = arguments;
window.dispatchEvent(e);
return rv;
};
};
history.pushState = _wr('pushState');
// 监听事件history的pushState事件
window.addEventListener('pushState', function(e) {
console.log("网页地址存在变换")
xiguaChange();
});
// 迅雷下载
function xunleiDownload(url,name){
thunderLink.newTask({
tasks: [{
name: name, // 指定下载文件名(含扩展名)。【若不填此项,将根据下载 URL 自动获取文件名】
url: url // 指定下载地址【必填项】
}]
});
}
// json转换
var safetyParse = (str) => {
try {
return JSON.parse(str);
} catch (error) {
return null;
}
};
var getXiGuaVideoInfo = async () => {
let data = null;
try {
console.log("window.location.href is "+ window.location.href);
const res = await fetch(window.location.href);
const str = await res.text();
// console.log("res is --------------",res)
// console.log(str)
data = safetyParse(
str.match(/window?._SSR_HYDRATED_DATA=([\d\D]+?)<\/script>/).replaceAll("undefined", "null")
);
// console.log("data is -----------",data)
// console.log(data)
}catch (e){
console.log(e)
}
finally {
return data;
}
}
async function handlerVideoData(){
let downloadOption = [];
let ids = [];
const data = await getXiGuaVideoInfo();
if(data == null){
return null;
}
const videoResource = data?.anyVideo?.gidInformation?.packerData?.video?.videoResource || data?.anyVideo?.gidInformation?.packerData?.videoResource;
const videoList = Object.values(videoResource?.normal?.video_list ?? {}).sort(
(a, b) => b?.vheight - a?.vheight
);
for (var index in videoList) {
let video = videoList;
// console.log("video is -------------");
// console.log(video);
let url = atob(video.main_url);
// // 添加点击事件
let fileName = data.anyVideo.gidInformation.packerData.video.title + "." + video.vtype;
// 为了保留文件名称,后续下载重新处理
fileName = fileName.replaceAll(" ", "-空格-");
let id = "downBtId"+video.definition;
let downloadData = {id: id,mainUrl: url,videoResolution: video.definition,fileName: fileName}
ids.push(id);
downloadOption.push(downloadData)
}
let returnData = {
downloadOption,
ids
}
return returnData;
}
async function createXiguaVideoDownload(){
let downloadOption = [];
let handlerDatas = await handlerVideoData();
if(handlerDatas == null){
return null;
}
downloadOption = handlerDatas.downloadOption;
let rightGrid = document.querySelector('.xg-right-grid');
let playControl = rightGrid.querySelector('div:nth-of-type(2)');
let control = playControl.cloneNode(true);
let isDownControleId = null;
try {
isDownControleId = playControl.querySelector('#downControleId');
}catch (e){
console.log(e)
}
let entry= control.querySelector('.xgplayer-control-item__entry');
entry.innerHTML = '<div class="xgpcPlayer_textEntry"><span id="downControleId">下载</span></div>';
let popover = control.querySelector('.xgplayer-control-item__popover');
let downloadList = '<ul>';
downloadOption.forEach(function(item){
try {
downloadList += `<li tabindex="0" role="menuitemradio" aria-checked="false" id="${item.id}"data-downUrl=${item.mainUrl}data-downTitle=${item.fileName}>${item.videoResolution}</li>`;
}catch (e){
console.log("没有数据");
}
})
downloadList += '</ul>';
popover.innerHTML = downloadList;
try {
if(isDownControleId != null){
playControl.replaceWith(control);
}else {
playControl.before(control);
}
}catch (e){
console.log(e)
}
let divDom = document.createElement('div');
divDom.style="width: 80px; height: 140px;position:absolute;bottom:40px;left:20px;z-index:-1";
control.appendChild(divDom);
control.onmouseover=function(){
popover.style.display='block';
}
control.onmouseout=function(){
popover.style.display='none';
}
return handlerDatas.ids;
}
/*--Class--*/
class BaseClass{
createElement(dom,domId){
var rootElement = document.body;
var newElement = document.createElement(dom);
newElement.id = domId;
var newElementHtmlContent = document.createTextNode('');
rootElement.appendChild(newElement);
newElement.appendChild(newElementHtmlContent);
}
static getElement(css){
return new Promise((resolve,reject)=>{
let num = 0;
let timer = setInterval(function(){
num++
let dom = document.querySelector(css);
if(dom){
clearInterval(timer);
resolve(dom);
}else{
if(num==20){clearInterval(timer);resolve(false);}
}
},300)
})
}
}
async function loadingXigua() {
try{
var _this = this;
if (document.location.toString() !== "https://www.ixigua.com/") {
if(!isInit){
HTMLInit();
}
window.addEventListener('load',function(){
getControls();
})
}
}catch (e){
console.log(e);
}
}
async function xiguaChange() {
var _this = this;
if (document.location.toString() !== "https://www.ixigua.com/") {
if(!isInit){
HTMLInit();
}
getControls();
}
}
async function getControls(){
let videoDom = await BaseClass.getElement('video');
if(!videoDom){
console.log('没有找到DOM');return;
}
let ids = await createXiguaVideoDownload();
ids.forEach(function(id){
let jsId = "#" + id;
document.querySelector(jsId).addEventListener('click',function(eve){
console.log("-------------------有点击下载-------------------");
console.log(eve.target.dataset);
let fileName = eve.target.dataset.downtitle;
fileName = fileName.replaceAll("-空格-", " ");
// 转换回原来的文件名称
xunleiDownload(eve.target.dataset.downurl,fileName);
})
})
}
loadingXigua();
本脚本运行前提是安装第三方程序——迅雷,然后需要下载油猴,然后打开https://greasyfork.org/zh-CN/scripts/469452-%E8%A5%BF%E7%93%9C%E5%A0%82down-%E8%A5%BF%E7%93%9C%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%B7%A5%E5%85%B7,点击进行安装脚本。
最后说一下跟一般下载脚本的区别,一边脚本和插件都是直接调用浏览器下载,下载文件越大越容易卡浏览器,比如下载5-10G的视频文件,浏览器的下载容易卡爆,调用第三方API调用第三方程序则可以减轻浏览器的负担,而且浏览器多文件同时下载会出现一些问题,比如某些文件速度慢很多和文件没速度,暂停后未必能继续下载。第三方下载程序有非常完善的多任务下载,暂停和继续任务,最大能支持好几十个文件同时下载,多个下载链接合并成一个合集等等,浏览器下载就未必能实现该功能。
最后演示一下
吉祥喵 发表于 2023-6-26 11:36
感谢分享,不必要这么麻烦的,刚好也研究过,chrome有现成的插件,PC网页版西瓜,视频点开,就有下载按钮, ...
是什么插件呢 堂哥哥好帅 发表于 2023-6-27 17:11
刚查安装了IDM好像没有唤起的操作呢,IDM下载方式都是手动复制点击下载?
需要设定好 也是自动唤起的 网页端要下载idm插件 并且开启状态。
IDM 历史更新同步
https://prajna.lanzoui.com/b04gihtfa
这是最新的idm 可以从这里下载。
我这电脑里没有迅雷 安装了你的插件 打开了一个西瓜的视频网页 选择清晰度 旁边没有下载的按钮没有任何显示。 你图片里有个下载的选项 我这里是没有的,不知道什么情况。 感谢分享,不必要这么麻烦的,刚好也研究过,chrome有现成的插件,PC网页版西瓜,视频点开,就有下载按钮,无水印 学习了插件具体内部实现,感谢 手机端用360浏览器就可以下载视频,没用过pc端的,你也可以在手机上批量下载好打包传到电脑里 吉祥喵 发表于 2023-6-26 11:36
感谢分享,不必要这么麻烦的,刚好也研究过,chrome有现成的插件,PC网页版西瓜,视频点开,就有下载按钮, ...
请教,是什么插件呢,可否赐予一个链接?谢谢。 感谢分享,其实可以用资源嗅探一类的插件,通杀所有音视频媒体内容。 感谢分享,学习了 MAOZHUA_V1.0.16(猫抓-网页视频嗅探插件)用这个谷歌插件可以轻松获取下载链接 视频号视频有什么方法可以下载呢?