您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Launch a script on Huaban that automatically scrolls the page and converts all images on the page into large images (with links, names) to be added to the Eagle App.
// ==UserScript== // @name 批量导入花瓣图片到 Eagle // @name:zh 批量导入花瓣图片到 Eagle // @name:zh-TW 批次導入花瓣圖片到 Eagle // @name:ja-JP 花瓣の画像を Eagle に保存 // @description Launch a script on Huaban that automatically scrolls the page and converts all images on the page into large images (with links, names) to be added to the Eagle App. // @description:zh 请确保你的网路环境可以正常访问 花瓣,如果设备网路无法访问,此脚本将无法正常运作。在 花瓣 画版页面启动脚本,此脚本会自动滚动页面,将页面中所有图片转换成大图(包含链接、名称),添加至 Eagle App。 // @description:zh-TW 在 花瓣 畫版頁面啓動腳本,此腳本會自動滾動頁面,將頁面中所有圖片轉換成大圖(包含鏈接、名稱),添加至 Eagle App。 // @description:ja-JP 花瓣のボードページ上でスクリプトを起動すると、ページが自動的にスクロールし、ページ上のすべての画像を大きな画像(リンク、名前付き)に変換してEagleアプリに追加することができます。 // @author Augus // @namespace https://eagle.cool/ // @homepageURL https://eagle.cool/ // @supportURL https://docs-cn.eagle.cool/ // @icon https://cn.eagle.cool/favicon.png // @license MIT License // @match https://huaban.com/* // @grant GM_xmlhttpRequest // @connect localhost // @connect 127.0.0.1 // @run-at context-menu // @date 01/27/2022 // @modified 05/31/2022 // @version 0.0.7 // ==/UserScript== (function() { if (location.href.indexOf("huaban.") === -1) { alert("此脚本只能在花瓣网运行"); return; } // Eagle API 服务器位置 const EAGLE_SERVER_URL = "http://localhost:41595"; const EAGLE_IMPORT_API_URL = `${EAGLE_SERVER_URL}/api/item/addFromURLs`; const EAGLE_CREATE_FOLDER_API_URL = `${EAGLE_SERVER_URL}/api/folder/create`; let SELECTOR_IMAGE; let SELECTOR_LINK; let SELECTOR_NODATA; let SELECTOR_BOX; // 新版 if (document.querySelector(".infinite-scroll-component")) { SELECTOR_IMAGE = `.infinite-scroll-component a[href*='pins'] img`; SELECTOR_LINK = `.infinite-scroll-component a[href*='pins']`; SELECTOR_NODATA = `.infinite-scroll-component .noMore`; SELECTOR_BOX = `[data-pin-id]`; } // 旧版 else { SELECTOR_IMAGE = `#waterfall a.img img`; SELECTOR_LINK = `#waterfall a.img`; SELECTOR_NODATA = `img[src="/img/end.png"]`; SELECTOR_BOX = `[data-id]`; } var startTime = Date.now(); // 开始滚动时间 var scrollInterval; // 无限滚动,直到底部 var lastScrollPos; // 上一次滚轴位置 var retryCount = 0; // 目前重试次数 var scrollDelay = 100; // 滚动页面延迟 var retryThreshold = 20; // 无法滚动页面重试次数,当超过次数,表示到底部了 var pageInfo = { imageCount: 0, imageSet: {}, folderId: "" }; // 创建文件夹 var createFolder = function(folderName, callback) { GM_xmlhttpRequest({ url: EAGLE_CREATE_FOLDER_API_URL, method: "POST", data: JSON.stringify({ folderName: folderName }), onload: function(response) { try { var result = JSON.parse(response.response); if (result.status === "success" && result.data && result.data.id) { callback(undefined, result.data); } else { callback(true); } } catch (err) { callback(true); } } }); }; // 滚动至页面顶端 var scarollToTop = function() { window.scrollTo(0, 0); lastScrollPos = window.scrollY; }; // 滚动至页面底端 var scarollToBottom = function() { window.scrollTo(0, window.scrollY + 125); // window.scrollTo(0, window.innerHeight); lastScrollPos = window.scrollY; }; // 取得当前画面所有图片链接 var getImgs = function() { var imgs = []; var imgElements = Array.from(document.querySelectorAll(SELECTOR_IMAGE)); // 避免重复添加 imgElements = imgElements.filter(function(elem) { var src = elem.src; if (!pageInfo.imageSet[src]) { pageInfo.imageSet[src] = true; return true; } return false; }); var getLink = function(img) { var links = Array.from(document.querySelectorAll(SELECTOR_LINK)); for (var i = 0; i < links.length; i++) { if (links[i].contains(img)) { return absolutePath(links[i].href); } } return ""; }; var getTitle = function(img) { var gridItem = img.closest(SELECTOR_BOX); if (img.alt) { return img.alt; } if (gridItem && gridItem.textContent) { return gridItem.textContent; } return ""; }; imgs = imgElements.map(function(elem, index) { pageInfo.imageCount++; let src = getHighestResImg(elem) || elem.src; src += `?v=${Date.now()}`; // hack 💀 return { name: getTitle(elem), url: src, // 取得最大分辨率 website: getLink(elem), // 取得图片链接 modificationTime: startTime - pageInfo.imageCount // 强制设置时间,确保在 Eagle 顺序与 花瓣 相同 } }); return imgs; }; // 滚动页面并取得图片信息,发送至 Eagle App var fetchImages = function() { var currentScrollPos = window.scrollY; scarollToBottom(); addImagesToEagle(getImgs()); // 到底了 if (lastScrollPos === currentScrollPos || currentScrollPos === 0) { // 画面如果出现 Spinner 表示后面还有内容尚未载入完成 if (document.querySelector(SELECTOR_NODATA)) { retryCount++; console.log(retryCount) if (retryCount >= retryThreshold) { clearInterval(scrollInterval); alert(`添加完成,一共添加了 ${pageInfo.imageCount} 张图像。`); } } } // 还有内容 else { retryCount = 0; var images = getImgs(); addImagesToEagle(images); } } // 将图片添加至 Eagle var addImagesToEagle = function(images) { if (!images || images.length === 0) return; GM_xmlhttpRequest({ url: EAGLE_IMPORT_API_URL, method: "POST", data: JSON.stringify({ items: images, folderId: pageInfo.folderId }), onload: function(response) {} }); } function absolutePath(href) { if (href && href.indexOf(" ") > -1) { href = href.trim().split(" ")[0]; } var link = document.createElement("a"); link.href = href; return link.href; } function getHighestResImg(element) { var src = element.currentSrc || element.src; return src.replace(/_\/fw(.*)/, '').replace(/_sq\d+\/format(.*)/, '').split('/format/')[0].replace(/_sq235$/, '').replace(/_sq75$/, '').replace(/_fw[\d]+[w]*$/, '').split("_fw")[0].split('/fw/')[0]; } // 脚本开始 scarollToTop(); // 创建本次保存使用文件夹 var folderName = document.querySelector("title").text; createFolder(folderName, function(err, folder) { if (folder) { // 持续滚动列表,直到列表没有更多内容 pageInfo.folderId = folder.id; scrollInterval = setInterval(fetchImages, scrollDelay); } else { alert("软件尚未打开,或当前软件版本不支持,需至 Eagle 官网下载,手动重新安装最新版本"); } }); })();