You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python按Excel列表提取图片异常:匹配成功却写入错误日志

问题:匹配到图片名称却仍写入错误日志

我正在学习Python,当前任务是根据Excel列表中的图片名称,从本地硬盘文件夹提取对应图片。但代码仅对特定Excel列表有效,测试时明明匹配到了目标图片名称,却仍将其写入错误日志。

测试用Excel文件Mappe1.xlsx包含两个条目:4004764000364、4004764000517,二者均存在于图片文件夹中,控制台输出显示已匹配,但错误日志仍记录这两个编号为未找到。

原代码

import os
import shutil
#Variablen:
errorlog = []
gtins_from_excel = []
gtins_from_pictures = []
list = []
dir = os.listdir("/Users/user1/Downloads/latest") #import "pictures" to python
print(len(dir))
for i in dir:
    try:
        gtins_from_pictures.append((i.split(".")[0])) #converting picture names to same format       #                                                      as excel list 
    except:
        pass
# importing openpyxl module
import openpyxl
# Give the location of the file
path = "/Users/user1/Downloads/Mappe1.xlsx"
# workbook object is created
wb_obj = openpyxl.load_workbook(path)
sheet_obj = wb_obj.active
m_row = sheet_obj.max_row
# Loop will print all values
# of first column
for i in range(1, m_row + 1):
    cell_obj = sheet_obj.cell(row=i, column=1)
    gtins_from_excel.append(cell_obj.value)
#print((gtins_from_excel))
#print(len(gtins_from_pictures))
#print(len(dir))
errorlog = []
for i in range(0, len(gtins_from_excel)):
    flag = 0
    for j in range(0, len(gtins_from_pictures)):
        print(gtins_from_excel[i], "<>", gtins_from_pictures[j])
        try:
            if gtins_from_excel[i] == gtins_from_pictures[j]:
                flag = 1
                copy = shutil.copy2("/Users/user1/Downloads/latest/" + dir[j], "/Users/user1/Downloads/requests/" + dir[j])
        except:
            pass
    #print(flag, " ", gtins_from_excel[i])
    if flag == 0:
        errorlog.append(gtins_from_excel[i])
print("Errorlog:", errorlog)

问题根源

  1. 类型不匹配:从Excel读取的GTIN是整数类型,而图片文件名提取的是字符串类型,直接用==比较会返回False,导致flag始终为0,最终被写入错误日志。
  2. 异常捕获过于宽泛:外层try-except会掩盖所有错误,包括匹配逻辑的问题,你看不到类型不匹配的报错。
  3. 嵌套循环冗余:双层循环遍历两个列表效率低,且容易因为类型问题遗漏匹配。

修复方案

1. 统一数据类型

将Excel读取的单元格值转为字符串,确保和图片文件名的字符串类型一致:

gtins_from_excel.append(str(cell_obj.value))

注意:如果Excel有空单元格,先判断cell_obj.value是否为None,避免报错。

2. 用集合优化匹配效率

集合的查找操作是O(1),比嵌套循环高效得多,还能避免重复匹配:

gtins_pic_set = set(gtins_from_pictures)

3. 细化异常处理

只捕获文件操作相关的异常,不要掩盖匹配逻辑的错误,方便排查问题。

修复后的完整代码

import os
import shutil
import openpyxl

# 初始化变量
errorlog = []
gtins_from_excel = []
gtins_from_pictures = []

# 读取图片文件夹,提取GTIN
pic_dir = "/Users/user1/Downloads/latest"
dir_contents = os.listdir(pic_dir)
print(f"图片文件夹共 {len(dir_contents)} 个文件")

for filename in dir_contents:
    try:
        gtin = filename.split(".")[0]
        gtins_from_pictures.append(gtin)
    except IndexError:
        errorlog.append(f"无效文件名:{filename}")

# 读取Excel中的GTIN,统一转为字符串
excel_path = "/Users/user1/Downloads/Mappe1.xlsx"
wb_obj = openpyxl.load_workbook(excel_path)
sheet_obj = wb_obj.active
max_row = sheet_obj.max_row

for row in range(1, max_row + 1):
    cell_value = sheet_obj.cell(row=row, column=1).value
    if cell_value is not None:
        gtins_from_excel.append(str(cell_value))
    else:
        errorlog.append(f"第 {row} 行单元格为空")

# 用集合快速匹配
gtins_pic_set = set(gtins_from_pictures)
target_dir = "/Users/user1/Downloads/requests"

# 确保目标文件夹存在,避免创建失败
os.makedirs(target_dir, exist_ok=True)

# 遍历Excel GTIN,复制对应图片
for gtin in gtins_from_excel:
    if gtin in gtins_pic_set:
        # 找到对应文件名
        for filename in dir_contents:
            if filename.startswith(f"{gtin}."):
                src_path = os.path.join(pic_dir, filename)
                dest_path = os.path.join(target_dir, filename)
                try:
                    shutil.copy2(src_path, dest_path)
                    print(f"已复制:{filename}")
                except Exception as e:
                    errorlog.append(f"复制 {filename} 失败:{str(e)}")
                break
    else:
        errorlog.append(f"未找到匹配图片:{gtin}")

print("错误日志:", errorlog)

内容的提问来源于stack exchange,提问作者roglen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 03:28:18