// ==UserScript== // @name 微博一键取图(9宫格) // @namespace https://github.com/wah0713/getWeiboImage // @version 1.01 // @description 一个兴趣使然的脚本,微博(weibo|wb)一键取图脚本。 // @supportURL https://github.com/wah0713/getWeiboImage/issues // @author wah0713 // @compatible chrome // @license MIT // @icon https://weibo.com/favicon.ico // @require https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js // @require https://cdn.bootcss.com/jszip/3.1.5/jszip.min.js // @match *://weibo.com/* // @noframes true // @run-at document-idle // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_download // @grant unsafeWindow // @downloadURL none // ==/UserScript== (async function () { let vueRecycleScrollerDom = $('.Main_full_1dfQX') vueRecycleScrollerDom.on('click', '.woo-box-flex .head-info_info_2AspQ', async function (event) { const status = gettextDom(this) if (status === '中') return false retextDom(this, '中') // const imgUrlList = getfileUrlByDom(this) const writerName = $(this).prev().find('.head_name_24eEB').text() const time = $(this).find('.head-info_time_6sFQg').attr('title') || $(this).find('.head-info_time_6sFQg').text() const href = $(this).find('.head-info_time_6sFQg').attr('href') const imgUrlList = await getfileUrlByInfo(this) if (imgUrlList.length <= 0) { retextDom(this, '失败,未找到图片资源', true) return false } const promiseList = imgUrlList.map(getFileBlob) const imageRes = await Promise.all(promiseList) retextDom(this, '结束(点击再次下载)', true) // 打包 var zip = new JSZip(); imageRes.forEach(function (obj) { const suffixName = new URL(obj.finalUrl).pathname.match(/\.\w+$/)[0] const name = `${writerName}${time}-${obj._id}${suffixName}` zip.file(name, obj._blob); }); // 生成zip文件并下载 zip.generateAsync({ type: 'blob' }).then((content) => { GM_download({ url: URL.createObjectURL(content), name: `${writerName}${time}.zip`, }) }) }) function getFileBlob(url, index) { return new Promise((resolve, rejcet) => { GM_xmlhttpRequest({ url, method: 'get', responseType: 'blob', headers: { referer: 'https://weibo.com/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36' }, onload: (res) => { console.log(`onload`, res) resolve({ ...res, _blob: res.response, _id: index + 1 }) }, onerror: (res) => { console.log(`onerror`, res) resolve(null) } }) }) } function getfileUrlByDom(dom) { const UrlList = [] const $imgDomList = $(dom).parents('.Feed_body_3R0rO').find('.picture.content_row_-r5Tk .woo-picture-slot') $imgDomList.each((index, item) => { let fileDom = null if ($(item).find('img,video').length) { fileDom = $(item).find('img,video')[0] } else { fileDom = $(item).prevAll('img,video')[0] } let url = fileDom.src if (fileDom.nodeName === 'IMG') { url = fileDom.src.replace(/(?<=(cn)\/).+(?=(\/))/, 'large') } UrlList.push(url) }) return UrlList } function getInfoById(id) { return new Promise((resolve, rejcet) => { GM_xmlhttpRequest({ url: `https://weibo.com/ajax/statuses/show?id=${id}`, responseType: 'json', onload: (res) => { console.log(`onload`, res) resolve(res.response.pic_infos) }, onerror: (res) => { console.log(`onerror`, res) resolve(null) } }) }) } async function getfileUrlByInfo(dom) { const idList = [] $(dom).parents('.Feed_body_3R0rO').find('.head-info_time_6sFQg').each((index, item) => { idList.push($(item).attr('href').match(/(?<=\/)\w+$/)[0]) }) const resList = await Promise.all(idList.map(getInfoById)) const urlList = [] resList.forEach(item => { if (!item) return false; [...Object.keys(item)].forEach(ele => { urlList.push(item[ele].largest.url) }) }) return urlList } function retextDom(dom, text, isReset) { const $dom = $(dom) $dom.attr('show-text', text) if (isReset) { setTimeout(() => { $dom.attr('show-text', '') }, 2000) } } function gettextDom(dom, text) { return $(dom).attr('show-text') } GM_addStyle(` .woo-box-flex .head-info_info_2AspQ:after{content:"下载" attr(show-text);color:#ff8200;cursor:pointer} `) // debugJS // unsafeWindow.$ = $ // setTimeout(() => { // }, 5 * 1000); })()