使用js在网页中批量下载图片

3,096 阅读2分钟

想法来源

想法来源于,想把原神所有角色的小头像都保存下来,于是就去官网查看,发现了页面中有图片,但是自己一个一个右键下载实在是太慢了,就像一次性都下载下来

image.png

具体实现

首先要选中图片列表的ul

image.png

在控制台中输入$0,我们就拿到了页面中的元素。定义一个变量,保存所有的li,方便以后取url和角色名称

var lis = $0.querySelectorAll("li")

查看下lis,得到了一个NodeList

image.png

每个li里面有两个子元素,img和p

image.png

在lis中 ,使用firstChild.src得到url,使用lastChild.innerText得到角色名字

image.png

接来下只要遍历,将url和名字保存下来就可以进行下载操作了

然而你会发现,刚刚保存的lis无法使用forEach。这是因为lis为NodeList类型,他不是一个数组

image.png

我们可以使用call方法,改变this指向,遍历lis

var roles = []  //保存角色信息的数组

var a = [] //空数组

a.forEach.call(lis, item => {
  let r = {}
  r.url = item.firstChild.src
  r.name = item.lastChild.innerText
  roles.push(r)
})

遍历后得到角色的url和名字

image.png

有了url和名字,就可以进行下载了

//根据url下载图片方法

const downloadRes = async (url, name) => {
  let response = await fetch(url) // 内容转变成blob地址
  let blob = await response.blob() // 创建隐藏的可下载链接
  let objectUrl = window.URL.createObjectURL(blob)
  let a = document.createElement("a")
  a.href = objectUrl
  a.download = name
  a.click()
  a.remove()
}

最后,遍历roles数组,执行下载方法就行了

但是这里需要加延时,不加延时的话,不会下载全部,这19张图片只会下载一部分,原因未知,如有知道的请评论区解答,非常感谢!

//延时,一秒下载一张图片

roles.forEach((item, index) => {
  setTimeout(() => {
    downloadRes(item.url, item.name)
  }, 1000 * index)
})

执行后,一次下载了所有图片,非常方便!

image.png

完整代码


var lis = $0.querySelectorAll("li")   //获取dom元素

var roles = []  //保存角色信息的数组

var a = [] //空数组

//遍历保存图片信息
a.forEach.call(lis, item => {
  let r = {}
  r.url = item.firstChild.src
  r.name = item.lastChild.innerText
  roles.push(r)
})

//下载方法
const downloadRes = async (url, name) => {
  let response = await fetch(url) // 内容转变成blob地址
  let blob = await response.blob() // 创建隐藏的可下载链接
  let objectUrl = window.URL.createObjectURL(blob)
  let a = document.createElement("a")
  a.href = objectUrl
  a.download = name
  a.click()
  a.remove()
}

//延时,一秒下载一张图片
roles.forEach((item, index) => {
  setTimeout(() => {
    downloadRes(item.url, item.name)
  }, 1000 * index)
})