编辑代码

// ==UserScript==
// @name         下载国内1688主图视频详情图
// @namespace    https://detail.1688.com
// @version	1.0.0
// @description	 下载国内1688主图视频详情图
// @author       ABC
// @homepage
// @match        https://detail.1688.com/*
// @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 = async () => {
  insertJQuery('https://stuk.github.io/jszip/vendor/FileSaver.js')
  insertJQuery('https://stuk.github.io/jszip/dist/jszip.js')
  insertJQuery('https://stuk.github.io/jszip-utils/dist/jszip-utils.js')
  const props = getData()
  if (!props) {
    return
  }
  getProductImage()
  await getProductInfoPage(props)
}

function insertJQuery (url) {
  let script = document.createElement('script')
  script.src = url
  document.head.appendChild(script)
  return script
}

/**
 * 获取网络图片content
 * @param {Srting}url
 * @return {Promise<unknown>}
 */
function getPicture (url) {
  return new Promise((resolve, reject) => {
    fetch(url, {
      method: 'get',
      responseType: 'arraybuffer'
    }).then(data => {
      return data.blob()
    }).then(data => {
      //console.log('data---',data)
      resolve(data)
    }).catch(error => {
      reject(error)
    })
  })
}

function download (images, folderName) {
  // 这里用的element-ui组件,提示用户输入压缩包文件名
  //console.log('images+++',images)
  const zip = new JSZip()
  const folder = zip.folder(folderName)
  const promises = images.map((image, i) => {
    return getPicture(image).then(data => {
      // 获取图片名
      const name = image.split('/')[image.split('/').length - 1]

      //文件后缀
      var FileExt = image.replace(/.+\./, '')

      folder.file((i + 1).toString() + '.' + FileExt, data, { binary: true })
    })
  })
  Promise.all(promises).then(() => {
    zip.generateAsync({ type: 'blob' }).then(content => {
      saveAs(content, folderName + '.zip')
    })
  })

}

// 获取数据方法
function getData () {
  // 全部变量
  const props = {}
  // 获取产品id
  const i = location.href.indexOf('.html')
  if (i) {
    let k = 5
    while (location.href[i - k - 1] !== '/' && k < 20) {
      k++
    }
    props.id = location.href.substr(i - k, k)
    return props
  }
}

// 注入下载商品主图方法
function getProductImage (props) {
  // 获取主图缩略图列表DOM
  let imgList = document.getElementsByClassName('img-list-wrapper')[0]

  const editForm = document
    .getElementById('vbar-main')
  // 创建下载按钮
  const downButton = document.createElement('div')
  downButton.className = 'tab-li first de-selected'
  downButton.innerHTML = `<button type="button">主图</button>`

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

  // 遍历主图缩略图,并插入下载按钮 && k < 5
  for (let k = 0; k < imgList.getElementsByTagName('div').length; k++) {
    // 获取图片链接
    let src = imgList
      .getElementsByTagName('div')
      [k]?.getElementsByTagName('img')?.[0]?.src
    if (src) {
      // 注入给下载列表
      imgArr.push(src)
    }
  }

  downButton.onclick = () => {
    // 下载图片
    //console.log('imgArr++++',JSON.stringify(imgArr))
    download(imgArr, '主图')
  }
  // 将下载按钮注入表单
  editForm.insertBefore(downButton, editForm?.getElementsByTagName('div')?.[0])

  const style =
    'cursor:pointer; margin:5px; padding:0 5px; border:1px solid black; font-size:20px; color:red; fontweight:bold;'

  // 注入下载视频按钮 detail-main-video-content
  const video = document
    .getElementById('detail-main-video-content')
    .getElementsByClassName('lib-video')?.[0]
    ?.getElementsByTagName('video')?.[0]?.src
  //console.log('video----',video)
  if (video) {
    const downVideo = document.createElement('div')
    downVideo.className = 'tab-li first de-selected'
    downVideo.innerHTML = `<button type="button">视频</button>`

    downVideo.onclick = () => {
      GM_download(video, `${props.id}_视频_$`)
    }
    editForm.insertBefore(downVideo, editForm?.getElementsByTagName('div')?.[0])
  }

  return imgArr
}

// 注入下载详情页方法
function getProductInfoPage (props) {
  // 创建详情页图片列表
  // 获取表单
  const editForm = document
    .getElementById('vbar-main')
  // 创建下载按钮
  const downButton = document.createElement('div')
  downButton.className = 'tab-li first de-selected'
  downButton.innerHTML = `<button type="button">详情</button>`
  downButton.onclick = () => {
    const imgList = document.getElementById('detailContentContainer')?.childNodes
    if (!imgList) return
    // 改成多层遍历,穿透获取
    // 分层穿透,
    // 检查节点是否含有src
    // 检查节点是否有子元素 ———闭包遍历
    const imgArr = []
    const mapChild = list => {
      list.forEach(i => {
        if (i?.src) {
          imgArr.push(i.src)
        }
        if (i.childNodes.length !== 0) {
          mapChild(i.childNodes)
        }
      })
    }
    mapChild(imgList)
    //console.log('imgArr++++',JSON.stringify(imgArr))
    // 下载图片
    download(imgArr, '详情图')
  }
  // 将下载按钮注入表单
  editForm.insertBefore(downButton, editForm?.getElementsByTagName('div')?.[0])
}