https://wallhaven.cc/ 网站中有许多好看图片,平时看到就顺手就收藏了,那么如何快速批量下载自己收藏夹中的图片呢?
网站很贴心地提供了api,(https://wallhaven.cc/help/api) 所以直接利用api来下载,特别方便。为了提高下载速度,可以通过调用IDM来进行下载,速度嘎嘎快。
导入库:
from asyncio.windows_events import NULL
from math import ceil
import requests
import os
import json
import subprocess
from time import sleep
为了方便直接写一个类
class Wallhaven_master(requests.Session):
def __init__(self):
super(Wallhaven_master, self).__init__()
self.APIKEY = 'apikey='
self.logjson = []
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/527.36 (KHTML, like Gecko) Chrome/61.0.3143.79 Safari/527.36",
}
self.firurl = f"https://wallhaven.cc/api/v1/collections?{self.APIKEY}"
APIKEY里填自己的,毕竟是要下载自己收藏夹里的图片
若干个函数
获得键值
观察打开的api链接。需要比较频繁地获得键值,图方便就写了这个函数
参数key填字符串'mate'或者'data'
def get_dict(self, url, key):
'''
获得字典中data键或mate键的键值
'''
r = self.get(url, headers=self.headers)
req = r.json()
sleep(5)
dict = req[key]
return dict
调用IDM
IDMPath填自己的IDM安装路径
def IDMdownload(self, DownUrl, DownPath, FileName):
IDMPath = "D:\\Internet Download Manager\\IDMan.exe"
command = f'"{IDMPath}" /d {DownUrl} /p "{DownPath}" /f {FileName} /n /a'
subprocess.Popen(command)
因为硬盘太小下的图片有点多,所以没有写开始下载的命令,仅仅是把下载链接添加到下载队列里,如果有需要再手动点开始队列下载。
防止重复下载
我的思路是:因为图片名称是唯一的,所以把名称添加到一个列表中,然后保存在json文件中,每次下载前,检查列表中是否含有被下载图片的名称,有则跳过,以此来达到排重目的。
def readjson(self):
'''
读取json文件中的已下载链接,若无则创建
'''
try:
if os.path.isfile("WH-pics\\DownloadLog.json"):
with open("WH-pics\\DownloadLog.json", 'r') as dl:
self.logjson = json.load(dl)
return self.logjson
else:
with open("WH-pics\\DownloadLog.json", 'a') as dl:
self.logjson = []
return self.logjson
except:
self.logjson = []
return self.logjson
下载部分
def Run(self):
if not os.path.exists(("WH-pics")):
os.mkdir(("WH-pics"))
firdata = self.get_dict(self.firurl, "data")
for col in firdata:
colid = col["id"]
label = col["label"]
count = col["count"]
origpath = os.path.abspath(".")
flag = 1
page = 1
print(f"正在下载 {label} 中的图片,共 {count} 张")
if not os.path.exists((f"WH-pics\\{colid}-{label}")):
os.mkdir((f"WH-pics\\{colid}-{label}"))
if not count:
continue
# 若收藏夹中图片数为0则跳过
else:
lastpage = ceil(count/24)
while page <= lastpage:
securl = f"https://wallhaven.cc/api/v1/collections/id/{colid}?page={page}&{self.APIKEY}"
secdata = self.get_dict(securl, "data")
for picinfo in secdata:
picid = picinfo["id"]
if (picid in self.readjson()):
print(f"{str(flag).rjust(3)}*", end=" ")
if not (flag % 8):
print("")
flag += 1
sleep(1)
continue
picpath = picinfo["path"]
with open(f"WH-pics\\{colid}-{label}\\{colid}-{label}.txt", 'a+') as fl:
fl.write(f"{picpath}\n")
savepath = f"{origpath}\\WH-pics\\{colid}-{label}"
self.IDMdownload(picpath, savepath, NULL)
self.logjson.append(picid)
with open("WH-pics\\DownloadLog.json", 'w') as dl:
json.dump(self.logjson, dl)
print(f"{str(flag).rjust(3)}", end=" ")
if not (flag % 8):
print("")
flag += 1
sleep(1)
page += 1 # 当前页数+1
print(f"\n{label} 中的图片链接已全部写入\n\n")
因为这个网站设置的是每页是24张图片,然后为了便于观察运行结果,加了点提示信息,每个收藏夹里每下载一张图片,输出序号,每8个换一次行,如果是已下载的图片则会在序号后面输出*。
正在下载 xxxxxx 中的图片,共 39 张
1 2 3* 4* 5* 6* 7* 8*
最后创建一个实例,运行函数.Run()就可以了,开始愉快爬图
结尾
网站调用api有速度限制,为了保险所以设置的速度比较慢,耐心等待就好