您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
一键下载twitter页面所有图片。需要注意使用chrome会一直疯狂跳弹窗,建议使用firefox.
当前为
// ==UserScript== // @name Twitter: Download All Images // @name:zh-CN Twitter:下载全部图片 // @version 0.0.2 // @description One button click to download all imgs in twitter page. Firefox is recommended for this script. Chrome will keep popping up the annoying saveAs dialog. // @description:zh-CN 一键下载twitter页面所有图片。需要注意使用chrome会一直疯狂跳弹窗,建议使用firefox. // @author aji // @namespace https://github.com/hjyssg // @icon https://i.imgur.com/M9oO8K9.png // @include https://twitter.com/* // @include https://mobile.twitter.com/* // @grant GM_download // ==/UserScript== /* jshint esversion: 6 */ //https://stackoverflow.com/questions/6480082/add-a-javascript-button-using-greasemonkey-or-tampermonkey function addButton(text, onclick, cssObj, id) { const defaultCSS = {position: 'fixed', top: '7%', left:'50%', 'z-index': 3, "background-color": "#57cff7", "color": "white", "padding": "10px", "border": "0px", "font-size": "1rem","font-weight": "bold" } cssObj = Object.assign(defaultCSS, cssObj || {} ) let button = document.createElement('button'), btnStyle = button.style; document.body.appendChild(button) button.innerHTML = text; button.onclick = onclick btnStyle.position = 'fixed'; button.id = id; Object.keys(cssObj).forEach(key => btnStyle[key] = cssObj[key]); return button; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } const downloadedLink = {} function formatDate(date) { var d = new Date(date), month = '' + (d.getMonth() + 1), day = '' + d.getDate(), year = d.getFullYear(); if (month.length < 2) month = '0' + month; if (day.length < 2) day = '0' + day; return [year, month, day].join('-'); } async function findImgAndDownload(){ let queue = []; document.querySelectorAll("article").forEach(article => { //e.g 水洗卜イレ@suisentoire· asdsad let spans = Array.from(article.querySelectorAll("span span")); let author; let timestamp; for(let ii = 0; ii < spans.length; ii++){ let e1 = spans[ii]; let e2 = e1.parentElement.parentElement.parentElement.parentElement; if(e2.textContent.includes("@")){ author = e2.textContent; break; } } if(!author){ return; } let timeSpan = article.querySelector("article time"); if(timeSpan){ dt = new Date(timeSpan.getAttribute("datetime")); timestamp = formatDate(dt); } // console.log(author); const imgs = article.querySelectorAll("img"); if(imgs.length > 1) { imgs.forEach(img => { if(img.clientWidth < 80 && img.clientHeight < 80){ //skip icon and emoji return; } const link = img.src; queue.push({ author, link, timestamp }); }); } }) // queue = queue.filter(e => !downloadedLink[e.link]); for(let ii = 0; ii < queue.length; ii++){ const info = queue[ii]; const { link, author, timestamp } = info; if(_stop_download_){ break; } if(downloadedLink[link]){ continue; } const url = new URL(link); let format; if(url.search){ if(url.searchParams.get("name")){ url.searchParams.set("name", "orig") } format = url.searchParams.get("format") } // else{ // // http://fridge-dweller.blogspot.com/2012/09/obtaining-tweeted-images-in-original.html // url.href += ":orig"; // } let _link = url.href; const segment = url.pathname.substring(url.pathname.lastIndexOf('/') + 1); let fn = author +" -- " + timestamp||"" + " " + segment; if(format){ fn = fn + "." + format; } fn = fn.trim(); try{ // console.log("begin download", _link) downloadedLink[link] = true; await GM_downloadPromise(_link, fn); // console.log("downloaded", _link); console.log(Object.keys(downloadedLink).length, "imgs downloaded") await sleep(100); }catch(err){ // console.error(err) debugger } } } function GM_downloadPromise(_link, fn){ return new Promise((resolve, reject) => { GM_download({ url: _link, name: fn, saveAs: false, // this do not work for Chrome onerror: err => { console.error("error", _link); reject(err); }, ontimeout: ()=>{ console.error("timeout", _link); reject("timeout"); }, onload: ()=>{ resolve(); } }); }) } let _stop_download_; async function beginDownloadAndScroll(){ _stop_download_ = false; let scrollReachEndCount = 0; while(!_stop_download_ && scrollReachEndCount < 30){ await findImgAndDownload(); const newY = window.scrollY + 500; window.scrollTo(0, newY); await sleep(200); if(window.scrollY < newY){ //not scroll as much as expected //meaning reaching the end scrollReachEndCount++; }else{ //use count here //be very careful here, I want to download all imgs scrollReachEndCount = 0; } } console.log("download stop"); } (function() { 'use strict'; addButton("download all images", beginDownloadAndScroll, {top: '7%'}, "a-begin-button"); addButton("stop download", () => { _stop_download_ = true; }, {top: '12%'}, "a-stop-button"); })();