吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2082|回复: 0
收起左侧

[Python 原创] 爬虫-调用IDM利用API来快速下载Wall Haven账号收藏夹中的图片

  [复制链接]
xdxgkxq 发表于 2022-11-16 21:58

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有速度限制,为了保险所以设置的速度比较慢,耐心等待就好

免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Taoqi88 + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 03:05

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表