前言
需要用油猴采集并下载一个网站的图片,直接下下不了,搜了一下,是禁止跨域,使用CORS Unblock
也不行,所以使用油猴自带的GM_xmlhttpRequest
发送跨域请求。
项目
目标网站
代码编写
代码仅作为学习使用,禁止商用。
// ==UserScript==
// @name ***** Image Downloader and Zipper with GM_xmlhttpRequest
// @namespace http://tampermonkey.net/
// @version 1.7
// @description Download all matching product images as a zip file from the **** product page using GM_xmlhttpRequest (For learning purposes only)
// @author slowfeather@163.com
// @match
// @icon
// @grant GM_xmlhttpRequest
// @grant GM_download
// @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js
// ==/UserScript==
(function() {
'use strict';
// List to store image URLs
let imageUrls = new Set();
// Function to periodically collect image URLs
function collectImageUrls() {
const imageElements = document.querySelectorAll('img');
const regex1 = /*****\.com\/package-screenshot\/.+?_scaled\.jpg$/;
const regex2 = /*****\.****\.com\/key-image\/.+?\.jpg$/;
imageElements.forEach((img) => {
const url = img.src;
if ((regex1.test(url) || regex2.test(url)) && !imageUrls.has(url)) {
imageUrls.add(url);
showNotification('捕获了一张图片地址 :'+url);
}
});
}
// Function to show notification
function showNotification(message) {
const notification = document.createElement('div');
notification.innerText = message;
notification.style.position = 'fixed';
notification.style.top = '50px';
notification.style.right = '10px';
notification.style.zIndex = 1000;
notification.style.backgroundColor = 'lightgreen';
notification.style.padding = '5px';
notification.style.border = '1px solid green';
notification.style.borderRadius = '5px';
document.body.appendChild(notification);
setTimeout(() => {
document.body.removeChild(notification);
}, 1000);
}
// Set an interval to collect image URLs every second
setInterval(collectImageUrls, 300);
// Function to download all images in the list and zip them
async function downloadAndZipImages() {
const zip = new JSZip();
let count = 0;
const fetchImage = (url, filename) => {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
url: url,
responseType: 'blob',
onload: function(response) {
if (response.status === 200) {
zip.file(filename, response.response);
count++;
resolve();
} else {
reject(`HTTP error! status: ${response.status}`);
}
},
onerror: function(error) {
reject(`Failed to fetch image ${url}: ${error}`);
}
});
});
};
const fetchPromises = Array.from(imageUrls).map((url, index) => {
const filename = `image_${index + 1}.jpg`;
return fetchImage(url, filename);
});
try {
await Promise.all(fetchPromises);
if (count > 0) {
const content = await zip.generateAsync({ type: "blob" });
saveAs(content, "images.zip");
} else {
alert("No matching images found.");
}
} catch (error) {
console.error(error);
}
}
// Wait for the page to fully load
window.addEventListener('load', () => {
// Create a button to trigger the download
const button = document.createElement('button');
button.innerText = 'Download All Images as Zip';
button.style.position = 'fixed';
button.style.top = '10px';
button.style.right = '10px';
button.style.zIndex = 1000;
button.addEventListener('click', downloadAndZipImages);
document.body.appendChild(button);
});
})();
运行效果