如何为批量下载图片设置带序号命名?解决文件覆盖问题
问题分析与解决思路
问题出在文件名生成逻辑上:当前代码为同一产品的所有图片生成完全相同的文件名(Roco_{reference}.jpg),导致后续下载的图片直接覆盖之前的文件。要实现同一产品编号下图片序号从1开始递增,核心是为每个产品维护独立的计数器。
具体改进步骤
- 新增一个字典
ref_counter,用于记录每个产品编号对应的图片序号,键为产品reference,值为当前要使用的序号 - 遍历每个产品的图片时,先从字典中获取该产品的当前序号(若不存在则默认从1开始)
- 将序号拼接进文件名,完成下载后更新该产品的计数器
修改后的完整代码
import requests from bs4 import BeautifulSoup productlinks = [] for x in range(1, 2): r = requests.get( f'https://www.roco.cc/ren/products/locomotives/steam-locomotives.html?p={x}&verfuegbarkeit_status=41%2C42%2C43%2C45%2C44') soup = BeautifulSoup(r.content, 'lxml') productlist = soup.find_all('li', class_='item product product-item') for item in productlist: for link in item.find_all('a', class_='product-item-link', href=True): productlinks.append(link['href']) wayslist = [] # 初始化产品编号计数器 ref_counter = {} for url in productlinks: r = requests.get(url, allow_redirects=False) soup = BeautifulSoup(r.content, 'html.parser') images = soup.findAll('img') try: reference = soup.find('span', class_='product-head-artNr').get_text().strip() except Exception as e: print(f"获取产品编号失败,链接:{url}") continue # 跳过当前产品的图片下载 # 为当前产品初始化计数器,默认从1开始 current_num = ref_counter.get(reference, 1) for image in images: if 'def' in image['src']: name = 'Roco' ways = image['src'] wayslist.append(ways) # 生成带有序号的文件名 filename = f"{name}_{reference}_{current_num}.jpg" with open(filename, 'wb') as f: im = requests.get(ways) f.write(im.content) print(f'已写入: {filename}') # 更新计数器,下次使用递增后的序号 current_num += 1 ref_counter[reference] = current_num print(f"总计下载图片数量: {len(wayslist)}")
关键改动说明
- 将产品编号的获取逻辑移到图片遍历外层,避免重复解析同一产品的编号,同时简化异常处理
- 新增
ref_counter字典追踪每个产品的图片序号,确保同一产品的图片序号从1开始连续递增 - 文件名改为
Roco_{reference}_{current_num}.jpg格式,彻底解决覆盖问题 - 优化异常处理:获取编号失败时直接跳过当前产品,避免后续代码报错,同时打印具体的错误链接便于排查
内容的提问来源于stack exchange,提问作者Filip Chobodicky
相关产品推荐
相关产品推荐

