您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Batch Download on creator, not post
当前为
- // ==UserScript==
- // @name Fanbox Batch Downloader
- // @namespace http://tampermonkey.net/
- // @version 0.11
- // @description Batch Download on creator, not post
- // @author https://github.com/amarillys
- // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.2/jszip.min.js
- // @match https://www.pixiv.net/fanbox/creator/*
- // @grant GM_xmlhttpRequest
- // @grant GM_download
- // ==/UserScript==
- (function() {
- 'use strict';
- const fetchOptions = {
- credentials: 'include',
- headers: { Accept: 'application/json, text/plain, */*' }
- }
- window.onload = () => {
- let baseBtn = document.querySelector('[href="/fanbox/notification"]')
- let className = baseBtn.parentNode.className
- let parent = baseBtn.parentNode.parentNode
- let downloadBtn = document.createElement('div')
- downloadBtn.className = className
- downloadBtn.innerHTML = '<a href="javascript:void(0)"><div style="width: 100px;height: 32px;background-color: rgba(102, 102, 102, 0.96);border-radius: 10px;color: #EEE;text-align: center;">Click Here to Download</div></a>'
- downloadBtn.addEventListener('click', () => { console.log('startDownloading'); downloadByFanboxId(parseInt(document.URL.split('/')[5])); })
- parent.appendChild(downloadBtn)
- }
- function gmRequireImage(url) {
- return new Promise((resolve, reject) => {
- GM_xmlhttpRequest({
- method: 'GET',
- url,
- responseType: 'blob',
- onload: res => {
- resolve(res.response)
- }
- })
- })
- }
- async function downloadByFanboxId(creatorId) {
- let creatorInfo = await getAllPostsByFanboxId(creatorId)
- let zip = new JSZip()
- let amount = 0
- let processed = 0
- let waittime = 0
- zip.file('cover.jpg', await gmRequireImage(creatorInfo.cover), { compression: "STORE" })
- for (let i = 0, p = creatorInfo.posts; i < p.length; ++i) {
- let folder = p[i].title
- console.log(p[i].body)
- if (!p[i].body) continue
- let images = p[i].body.images
- if (!images) continue
- for (let j = 0; j < images.length; ++j) {
- let extension = images[j].extension === 'jpeg' ? 'jpg' : 'png'
- amount++
- gmRequireImage(images[j].originalUrl).then(blob => {
- zip.folder(folder).file(`${folder}_${j}.${extension}`, blob, { compression: "STORE" })
- waittime--
- processed++
- console.log(` Progress: ${ processed } / ${ amount }`)
- })
- }
- }
- // generate zip to download
- let timer = setInterval(() => {
- waittime++
- if (amount === processed || waittime > 10) {
- zip.generateAsync({ type: 'blob' }).then(zipBlob => saveBlob(zipBlob, `${creatorId}.zip`))
- clearInterval(timer)
- }
- }, 1000)
- }
- async function getAllPostsByFanboxId(creatorId) {
- let fristUrl = `https://www.pixiv.net/ajax/fanbox/creator?userId=${ creatorId }`
- let creatorInfo = {
- cover: null,
- posts: []
- }
- let firstData = await (await fetch(fristUrl, fetchOptions)).json()
- let body = firstData.body
- creatorInfo.cover = body.creator.coverImageUrl
- creatorInfo.posts.push(...body.post.items)
- let nextPageUrl = body.post.nextUrl
- while (nextPageUrl) {
- let nextData = await (await fetch(nextPageUrl, fetchOptions)).json()
- creatorInfo.posts.push(...nextData.body.items)
- nextPageUrl = nextData.body.nextUrl
- }
- return creatorInfo
- }
- function saveBlob(blob, fileName) {
- let downloadDom = document.createElement('a')
- downloadDom.id = 'fuck'
- document.body.appendChild(downloadDom)
- downloadDom.style = `display: none`
- let url = window.URL.createObjectURL(blob)
- downloadDom.href = url
- downloadDom.download = fileName
- downloadDom.click()
- window.URL.revokeObjectURL(url)
- }
- })();