python3 下载符合分辨率要求的壁纸

99 阅读2分钟

@TOC


前言

两个电脑屏幕一成不变的壁纸枯燥又乏味,给苦涩的搬砖之路加点甜


一、知乎获取文件集合

因为知乎的图片有预加载,所以获取文件不需要登录。只需要获取到预加载的图片数据即可

# 这个接口是获取图片预加载数据, q就是查询的内容
zhiHuPath = "https://www.zhihu.com/api/v4/search_v3?t=general&q=%E5%A3%81%E7%BA%B8&correction=1&offset=0&limit=20&lc_idx=0&show_all_topics=0"

然后从请求头中扒拉五条数据,这五数据分别是: x-zse-83, x-zse-86, referer, user-agent 如果要获取别的类型图片,那 x-zse-83, x-zse-86, referer, 以及 zhiHuPath中q的值需要修改。 可能解析的时候,字典的key也需要根据报错内容微调一下。

headers = {"x-zse-83": "",
           "x-zse-86": "",
           "referer": "",
           "user-agent": "",
           "cookie": ""}

然后就是获取请求中的数据了。

def searchFile():
    """
    获取文件集合
    :return: void
    """
    url = requests.get(zhiHuPath, headers=headers)
    UrlContent = url.content
    obj = json.loads(UrlContent)
    objs = obj["data"]
    for i in range(0, len(objs)):
        if "object" not in objs[i]:
            continue
        data = objs[i]["object"]
        if "content_list" in data:
            content_list = data["content_list"]
            # comment_count 评论数
            # voteup_count 点赞数
            # updated_time 更新时间
            # 排序逻辑,点赞数最多
            if len(content_list) > 1:
                content_listSort = sorted(content_list, key=lambda x: x["voteup_count"], reverse=True)
                # 转JSON
                for i in range(0, len(content_listSort)):
                    if "content" in data:
                        content = content_listSort[i]["content"]
                        resolveContent(content)
        elif "content" in data:
            content = data["content"]
            resolveContent(content)
        else:
            print("no content_list, continue.")

二、解析文件集合,正则剥离其文件路径

正则表达式解析文件集合 获取到图片src之后会保存到全局变量imgSrcList中

imgSrcList = set()

def resolveContent(content):
    """
    解析出图片路径
    :param content: 需要解析的内容
    :return: void
    """
    findallSrc = re.findall(r'data-original="(.*?)"', content, re.M | re.I)
    if findallSrc:
        for j in range(len(findallSrc)):
            imgSrcList.add(findallSrc[j])
    else:
        print("no data")

三、根据文件路径下载壁纸

因为下载文件是IO密集型 而我电脑8核,所以线程数大概<= 80 (cpu / (1 - 阻塞系数))

def downloadImages():
    """
    多线程下载文件
    :return: void
    """
    imgSrcListSize = len(imgSrcList)
    print("imgSrcListSize: ", imgSrcListSize)
    executor = ThreadPoolExecutor(max_workers=80)
    all_task = [executor.submit(downloadImage, imgSrc) for imgSrc in imgSrcList]
    # 阻塞主线程,等待线程池中线程运行完毕
    wait(all_task, return_when=ALL_COMPLETED)
    print("executor end")

四、筛选出符合分辨率要求的壁纸

因为图片是在知乎用户大大,编辑的内容中筛选出来的,所以可能会有表情包,等等不适用于壁纸的图片。所以写了一个简单筛选方法来筛选符合电脑分辨率的壁纸

def getImgDetail():
    """
    将不符合要求的文件移动到, deleteFiles文件夹
    :return: void
    """
    files = os.listdir(savePath)
    print(len(files))
    for i in range(len(files)):
        fileName = files[i]
        filePath = savePath + '/' + fileName
        # 不符合的图片将移动到deleteFiles文件夹
        fileMovePath = deleteFiles + '/' + fileName
        try:
            imageFile = Image.open(filePath)
            imageFile.close()
            # 符合条件,根据自己情况修改
            if (imageFile.width < 1920 or imageFile.height < 1080):
                shutil.move(filePath, fileMovePath)
        except Exception as e:
            print(e)
            # 因为还有部分图片下载打不开,也有可能是下载失败。
            # 所以还需要在抓取到异常的时候移动一下不能打开的图片
            shutil.move(filePath, fileMovePath)
            continue

国内: gitee.com/DLAMDXH/scr… 国外: github.com/DuoLaAMengD…

总结

代码很简单,学习并简单使用了requests,json,re(正则表达式),ThreadPoolExecutor(线程池),imageFile(图片详情)等包。 如果有啥问题,欢迎在评论区讨论哈~