您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
下载快手视频
当前为
// ==UserScript== // @name 快手视频高清下载 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 下载快手视频 // @author xelicev // @run-at document-start // @license MIT License // @grant GM_download // @include *://*kuaishou.com // @include *://*.kuaishou.com/* // @inject-into page // @require http://greasyfork.icu/scripts/440006-mono/code/mono.js?version=1021395 // ==/UserScript== const metaCache = {}; //hook fetch const fetchListKeys = ['brilliantData', 'visionSearchPhoto', 'brilliantTypeData', 'visionProfilePhotoList'] const originFetch = fetch unsafeWindow.fetch = async (url, request) => { const response = await originFetch(url, request) if (url && url.indexOf('graphql') > -1) { try { const text = await response.text() response.text = () => { return new Promise((resolve) => { resolve(text) }) } const res = JSON.parse(text) for (i in fetchListKeys) { const key = fetchListKeys[i]; if (res?.data[key] && res.data[key].feeds && res.data[key].feeds.length > 0) { const feeds = res.data[key].feeds; for (var i = 0; i < feeds.length; i++) { var itemData = feeds[i].photo; itemData.author = feeds[i].author metaCache[itemData.id] = itemData } // console.log(feeds) } } } catch (e) { console.error(e) } } return response } //hook xhr const xhrListKeys = ['hotPhotoInfos', 'inspiredAds'] var origOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function() { this.addEventListener('load', function() { if (this.responseType && this.responseType !== "text") return; const res = JSON.parse(this.responseText) for (i in xhrListKeys) { const key = xhrListKeys[i]; if (res?.data && typeof res.data === 'object' && key in res.data && res.data[key].length > 0) { const feeds = res.data[key]; for (var i = 0; i < feeds.length; i++) { const url = new URL(feeds[i].coverThumbnailUrls[0].url); const id = url.searchParams.get('clientCacheKey')?.replace('.jpg', ''); // console.log(id, feeds[i]) feeds[i].id = id; metaCache[id] = feeds[i]; } // console.log(feeds) } } }); // console.log(arguments) origOpen.apply(this, arguments); }; (function () { var mono = window['mono-descargar']; var $ = mono.jQuery; var md5 = mono.md5; var onRequest = mono.onRequest; var filename = mono.filename; var errCode = mono.FAIL_TO_DEFAULT; var idKey = 'mono-dsg-id'; var getItemByMeta = (meta, selector='', selClass='') => { const id = `ks-${md5(meta.id)}` if ($(`[${idKey}=${id}]`).length > 0) return null; const url = meta.photoUrl; meta.title = meta.caption; meta.cover = meta.coverUrl; meta.name = filename(meta.title || document?.title); let $el = null; if (selector) $el = $(selector) if ($el.length > 0 && selClass) { const ps = $el.parentsUntil(selClass); if (ps.length > 0) $el = $(ps[ps.length - 1]) } if ($el.length <= 0) return null; const container = $el[0]; return { id, url, container, meta } }; var detail = async () => { const url = new URL(window.location.href); const video_id = url.pathname.replace("/short-video/", ''); if (video_id in metaCache) { const item = getItemByMeta(metaCache[video_id], '.kwai-player-container-video') return item ? [item] : []; } return []; } var list = async () => { const items = [] for (const [id, meta] of Object.entries(metaCache)) { const selector = `img[src*='clientCacheKey=${id}']` const item = getItemByMeta(meta, selector, '.video-card') if (item) items.push(item); } return items } var cc = async () => { const items = []; for (const [id, meta] of Object.entries(metaCache)) { const selector = `.cc-player-poster[style*='clientCacheKey=${id}']`; const item = getItemByMeta(meta, selector, '.common-video-item') if (!item) continue; item.url = meta.mainMvUrls[0].url; item.meta.cover = meta.coverThumbnailUrls[0].url; item.meta.title = `快手-${meta.firstIndustryName}-${meta.nickName}`; if (item) items.push(item); } return items } var parser = async function () { const url = new URL(window.location.href); const paths = url.pathname.split('/'); const path = paths[1]; if (path === "short-video") { return await detail(); } else if (!path || ["search", "brilliant", "profile"].includes(path)) { return await list(); } else if (url.host === 'cc.e.kuaishou.com' && ["/inspiration/ads", "/inspiration/hot"].includes(url.pathname)) { return await cc(); } else { throw errCode; } } if (mono?.init) mono.init({ parser }); })()