PYTHON爬取图片的准备工作与脚本

发布于 2023-02-02  323 次阅读


强制执行

  • 在爬取过程中程序很容易意外出错而终止运行,运行了一天的爬虫程序,回来查看时才发现刚打开两分钟程序就意外出错,自动退出了,看着空荡的文件夹,心里想必也是空荡的
  • 有的站点设置有访问频数等各种限制,触发限制条件后很多时候不会给返回码,而是直接拒绝访问,或者其他各种原因都可能导致报错退出,这时候就需要忽略报错强制执行了
比如请求这个不存在的站点:
request.get("miaomiao.drinkflower.asia")
并不会返回404,而是直接报错退出
  • 强制执行的方法很多,最简单的可能是
try:
    爬取()
except:
    爬取()
  • 在实际使用过程中,这种方式一般都没有效果,因为当爬虫被拒绝,try中爬取()出错,而执行except中的爬取(),这个时候一般也会出错,使得except也出错,两次出错程序直接退出

  • 也可以使用线程互启,一般多线程爬虫的话加个except:其他线程.start()就行了

  • 这里介绍一种更简单的方法

def 爬虫():
    爬虫代码
if __name__ == '__main__':
    while 1:
        t1 = threading.Thread(target=job)
        t1.start()
        t1.join()
  • 进入程序后,主线程启动t1线程执行爬虫(),爬虫()出错退出回到主线程(t1.join()),主线程的循环再次启动t1线程,如果想要多线程爬虫,将t2.start,t2.join依次往后面加就行了
  • 实际操作过程中,我还遇到了1号线程出错,主线程不断启动新的线程,新线程任然不断出错,都重启到200多号线程了,这种情况就不是强制执行能够解决的,得考虑一下代理ip池和爬取频率的问题了

去重

  • 爬取到的图片一般来说会有很多重复,下面这个脚本可以将a文件夹下的重复图片移动到b文件夹(只移动多余的图片),实现去重的效果,脚本是网上找的,稍微改了一点点
  • 输入需要检查的图片文件夹地址和将重复图片移动到的地址就可以辣,如果只需要检测,不需要移除,在扫描完成输出提示信息后不回车就行了
import shutil
import numpy as np
from PIL import Image
import os

def 比较图片大小(dir_image1, dir_image2):
    with open(dir_image1, "rb") as f1:
        size1 = len(f1.read())
    with open(dir_image2, "rb") as f2:
        size2 = len(f2.read())
    if(size1 == size2):
        result = "大小相同"
    else:
        result = "大小不同"
    return result

def 比较图片尺寸(dir_image1, dir_image2):
    image1 = Image.open(dir_image1)
    image2 = Image.open(dir_image2)
    if(image1.size == image2.size):
        result = "尺寸相同"
    else:
        result = "尺寸不同"
    return result

def 比较图片内容(dir_image1, dir_image2):
    image1 = np.array(Image.open(dir_image1))
    image2 = np.array(Image.open(dir_image2))
    if(np.array_equal(image1, image2)):
        result = "内容相同"
    else:
        result = "内容不同"
    return result

def 比较两张图片是否相同(dir_image1, dir_image2):
    # 比较两张图片是否相同
    # 第一步:比较大小是否相同
    # 第二步:比较长和宽是否相同
    # 第三步:比较每个像素是否相同
    # 如果前一步不相同,则两张图片必不相同
    result = "两张图不同"
    大小 = 比较图片大小(dir_image1, dir_image2)
    if(大小 == "大小相同"):
        尺寸 = 比较图片尺寸(dir_image1, dir_image2)
        if(尺寸 == "尺寸相同"):
            内容 = 比较图片内容(dir_image1, dir_image2)
            if(内容 == "内容相同"):
                result = "两张图相同"
    return result

if __name__ == '__main__':

    load_path = input("输入需要去重图片的文件夹路径:")
    save_path = input("输入重复图片移除后的备份路径:")

    os.makedirs(save_path, exist_ok=True)

    # 获取图片列表 file_map,字典{文件路径filename : 文件大小image_size}
    file_map = {}
    image_size = 0
    # 遍历filePath下的文件、文件夹(包括子目录)
    for parent, dirnames, filenames in os.walk(load_path):
        # for dirname in dirnames:
        # print('parent is %s, dirname is %s' % (parent, dirname))
        for filename in filenames:
            # print('parent is %s, filename is %s' % (parent, filename))
            # print('the full name of the file is %s' % os.path.join(parent, filename))
            image_size = os.path.getsize(os.path.join(parent, filename))
            file_map.setdefault(os.path.join(parent, filename), image_size)

    # 获取的图片列表按 文件大小image_size 排序
    file_map = sorted(file_map.items(), key=lambda d: d[1], reverse=False)
    file_list = []
    for filename, image_size in file_map:
        file_list.append(filename)

    # 取出重复的图片
    file_repeat = []
    for currIndex, filename in enumerate(file_list):
        dir_image1 = file_list[currIndex]
        dir_image2 = file_list[currIndex + 1]
        result = 比较两张图片是否相同(dir_image1, dir_image2)
        if(result == "两张图相同"):
            file_repeat.append(file_list[currIndex + 1])
            print("相同的图片:", file_list[currIndex], file_list[currIndex + 1])
        #else:
            #print('相同的图片:', file_list[currIndex], file_list[currIndex + 1])
        currIndex += 1
        if currIndex >= len(file_list)-1:
            break
    a=input("回车以移除重复照片,不移除关掉程序即可")
    # 将重复的图片移动到新的文件夹,实现对原文件夹降重
    for image in file_repeat:
        shutil.move(image, save_path)
        print("正在移除重复照片:", image)

批量重命名

  • 无论是图片名字本来就乱七八糟还是本来图片名字有序,去重之后导致图片顺序混乱,批量有规律的重命名都是十分必要的
  • 这个脚本可以自定义起始数字,然后依次将起始数字后面的数字命名给文件,比如aa.jpg,bb.jpg,输入1,将被命名为2,jpg,3.jpg.同时这个脚本不仅支持jpg,事实上它是不会改变原有后缀的
import os

def reName(dirname):
    global count
    count=int(count)
    for cur_file in os.listdir(dirname):
        count += 1
        oldDir = os.path.join(dirname, cur_file) 
        filetype = os.path.splitext(cur_file)[1] # 文件类型
        newDir = os.path.join(dirname, str(count) + filetype) # 新文件
        os.rename(oldDir, newDir)
        print(oldDir, newDir)

if __name__ == "__main__":
    global count
    dirname = input("输入路径:")
    count=input("输入起始名(数字):")
    reName(dirname)
届ける言葉を今は育ててる
最后更新于 2024-02-07