一键批量下载天猫图片

一键批量下载天猫主图,sku以及详情页(重构和经过了一些逻辑上的改良,按钮更协调;内存占用更小;操作更流畅)

// ==UserScript==
// @name         一键批量下载天猫图片
// @namespace    https://www.tmall.com
// @version	1.0.1
// @description	 一键批量下载天猫主图,sku以及详情页(重构和经过了一些逻辑上的改良,按钮更协调;内存占用更小;操作更流畅)
// @author       Leo
// @homepage
// @match        https://detail.tmall.com/*
// @match        https://detail.tmall.hk/*
// @grant        GM_log
// @grant        GM_setClipboard
// @grant        GM_notification
// @grant        GM_download
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant			   GM_addStyle
// ==/UserScript==
/*jshint multistr:true */

/*
 * 下载天猫图片工具
 * 下载商品主图
 * 下载sku
 * 下载详情页
 * */

window.onload = () => {
	const props = getData()
	setStyle()
	getProductImage(props)
	getProductSKU(props)
	getProductInfoPage(props)
}

// 获取数据方法
function getData() {
	// 全部变量
	const props = {}
	const params = location.search.substr(1).split('&')
	for (let i in params) {
		props[params[i].split('=')[0]] = unescape(params[i].split('=')[1])
	}
	return props
}

// 注入下载商品主图方法
function getProductImage(props) {
	// 获取主图缩略图列表DOM
	let imgList = document.getElementById('J_UlThumb')

	// 创建并注入下载专区
	const downBox = document.createElement('div')
	document.getElementsByClassName('tb-gallery')[0].appendChild(downBox)
	// 创建并注入标题
	const title = document.createElement('h2')
	title.innerHTML = '下载主图'
	title.style = 'text-align: center; margin-bottom: 20px'
	downBox.appendChild(title)
	// 创建并插入下载按钮列表
	const downList = document.createElement('ul')
	downList.className = 'tb-thumb tm-clear thumbUlOverride'
	downBox.appendChild(downList)

	// 创建主图的下载链接列表
	const imgArr = []

	// 遍历主图缩略图,并插入下载按钮
	for (let k = 0; k < imgList.getElementsByTagName('li').length; k++) {
		// 获取主图下载链接
		const xpath = document.evaluate(
			`//li[${k + 1}]/a/img`,
			imgList,
			null,
			XPathResult.ANY_TYPE,
			null
		)
		let img = xpath.iterateNext()
		let src = img?.src
		if (src) {
			src = src.substr(0, src.length - 13)
			// 注入给下载列表
			imgArr.push(src)
			// 创建并注入按钮
			const downButton = document.createElement('li')
			const downImg = document.createElement('img')
			downImg.src = src
			downImg.style.cursor = 'pointer'
			downImg.title = (k + 1).toString()
			downImg.onmouseover = () => {
				imgList.getElementsByTagName('li')[k].className = 'tb-selected'
			}
			downImg.onmouseout = () => {
				imgList.getElementsByTagName('li')[k].className = 'tb-thumb tm-clear'
			}
			downImg.onclick = () => {
				GM_download(src, `${props.id}_主图_${k >= 9 ? k + 1 : '0' + (k + 1)}`)
			}
			downList.appendChild(downButton)
			downButton.appendChild(downImg)
		}
	}

	// 注入下载全部按钮
	const downAll = document.createElement('li')
	const downAllSpan = document.createElement('a')
	downAllSpan.style.cursor = 'pointer'
	downAllSpan.onclick = () => {
		GM_notification('共下载 ' + imgArr.length + ' 张图片', '下载主图')
		imgArr.forEach((i, k) => {
			GM_download(
				i,
				`${props.id}_主图_${k >= 9 ? k + 1 : '0' + (k + 1)}${i.substr(-4, 4)}`
			)
		})
	}
	downAllSpan.innerHTML = '全部'
	downList.appendChild(downAll)
	downAll.appendChild(downAllSpan)

	return imgArr
}

// 注入下载sku方法
function getProductSKU(props) {
	// 获取SKU列表DOM
	let skuList = document.getElementsByClassName('tb-img')[0]

	// 创建并注入下载专区
	const downBox = document.createElement('dl')
	downBox.className = 'tb-prop'
	document
		.getElementsByClassName('tb-sku')[0]
		.getElementsByTagName('dl')[0]
		.insertAdjacentElement('afterend', downBox)
	// 创建并注入标题
	const title = document.createElement('dt')
	title.innerHTML = '下载 SKU'
	title.className = 'tb-metatit'
	downBox.appendChild(title)
	// 创建注入下载图按钮的列表
	const downListBox = document.createElement('dd')
	downBox.appendChild(downListBox)
	const downList = document.createElement('ul')
	downList.className = 'tm-clear J_TSaleProp tb-img'
	downListBox.appendChild(downList)

	// 创建主图的下载链接列表
	const imgArr = []

	//遍历SKU,生成并注入下载按钮
	for (let k = 0; k < skuList.getElementsByTagName('li').length; k++) {
		// 获取sku下载链接
		let img = skuList
			.getElementsByTagName('li')
			?.[k]?.getElementsByTagName('a')?.[0]?.style.backgroundImage
		if (img) {
			const src = 'https:' + img.substr(5, img.length - 20)
			// 注入给下载列表
			imgArr.push(src)
			// 创建并注入按钮
			const downButton = document.createElement('li')
			const downImg = document.createElement('a')
			downImg.style = `background: ${img} center no-repeat;`
			downImg.onmouseover = function () {
				skuList.getElementsByTagName('li')[k].className = 'tb-selected'
			}
			downImg.onmouseout = function () {
				skuList.getElementsByTagName('li')[k].className = ''
			}
			downImg.onclick = () => {
				GM_download(src, `${props.id}_SKU_${k >= 9 ? k + 1 : '0' + (k + 1)}`)
			}
			downList.appendChild(downButton)
			downButton.appendChild(downImg)
		}
	}

	// 创建并注入下载全部按钮
	const downButton = document.createElement('li')
	const downImg = document.createElement('a')
	downImg.innerHTML = '全部'
	downImg.style = 'color: red; font-weight: bold;'
	downImg.onclick = () => {
		GM_notification('共下载 ' + imgArr.length + ' 张图片', '下载 SKU')
		imgArr.forEach((i, k) => {
			GM_download(i, `${props.id}_SKU_${k >= 9 ? k + 1 : '0' + (k + 1)}`)
		})
	}
	downList.appendChild(downButton)
	downButton.appendChild(downImg)
}

// 注入下载详情页方法
function getProductInfoPage(props) {
	// 创建详情页图片列表
	const imgArr = []

	// 获取表单
	const editForm = document.getElementById('J_TabBar')
	// 创建下载按钮
	const downButton = document.createElement('li')
	const downA = document.createElement('a')
	// 调整属性
	downA.innerHTML = '下载详情页'
	downA.style = 'color: red; font-weight: bold;'
	downA.title =
		'请注意,下载详情图之前请先将所有详情图片显示完毕再点击此按钮下载,否则会出现下载不完整等问题'
	downA.onclick = () => {
		downButton.className = 'tm-selected'
		const imgList = document.getElementsByClassName('ke-post')[0].childNodes
		if (typeof imgList[0] !== 'undefined') {
			for (let i = 0; i < imgList.length; i++) {
				if (imgList[i].nodeName === 'IMG') {
				} else if (imgList[i].childNodes.length > 0) {
					for (let i1 = 0; i1 < imgList[i].childNodes.length; i1++) {
						if (imgList[i].childNodes[i1].nodeName === 'IMG')
							imgArr.push(imgList[i].childNodes[i1]?.src)
					}
				}
			}
			GM_notification('共下载 ' + imgArr.length + ' 张图片', '下载详情页')
			for (let k = 0; k < imgArr.length; k++) {
				GM_download(
					imgArr[k],
					`${props.id}_详情页_${k >= 9 ? k + 1 : '0' + (k + 1)}`
				)
			}
		}
	}
	// 将下载按钮注入表单
	editForm.insertBefore(
		downButton,
		document.getElementsByClassName('tm-qrcode-icon')[0]
	)
	downButton.appendChild(downA)
}

// 注入样式
function setStyle() {
	GM_addStyle(`
/* style for thumbs */
.thumbUlOverride li{
    padding-top:0 !important;
}
.thumbUlOverride li a {
    border:2px solid #000;
    width:56px!important;
    height:56px!important;
    font-size:22px;
    font-family: Arial, serif;
    font-weight:bold;
    color:#FE0335!important;
    line-height:56px!important;
}
.img-down li a{
    font-family: Arial, serif;
    cursor:pointer;
    color:#FE0335;
    font-weight:bold;
    font-size:16px;
}
.cat-ul{

}
.cat-ul li{
    line-height:28px;
    float:left;
    position:relative;
    margin:0 4px 4px 0;
    vertical-align:middle;
    padding:1px;
    list-style:none;
}
.cat-ul li a{
    width:38px!important;
    height:38px;
    padding:0;
    line-height:38px;
    outline:0;
    font-family: Arial, serif;
    color:#FE0335;
    font-weight:bolder;
}
`)
}