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

基于Selenium的网页图片爬取:解决重复下载与漏存问题

解决网页图片重复下载与遗漏问题的方案

从你的代码来看,导致重复保存和图片遗漏的核心问题有这几个:

  • 错误选中非图片元素:第一个XPath定位到的是轮播的「下一页按钮」(swiper-button-next),不是目标图片轮播项,这会把按钮的背景图混入列表,完全偏离需求。
  • 重复选择同一图片:后两个XPath的选择范围有重叠(比如swiper-slide-active同时属于swiper-slide-visible),导致同一个图片URL被多次添加到links列表。
  • 遍历逻辑无依据:len(links)//2 +1这种写法没有合理逻辑,会导致部分图片被跳过或重复下载。
  • 缺少去重处理:即使重复添加了URL,也没有做去重操作,自然会出现重复保存的情况。

修复步骤与优化后的代码

1. 修正图片元素定位

首先把所有定位调整为只针对轮播图片项,避免选中按钮或重复元素。用更精准的XPath,只选择包含背景图的轮播slide;同时用visibility_of_all_elements_located替代presence_of_all_elements_located,确保元素已可见(图片加载完成),避免遗漏未渲染的图片:

# 只选择带有background-image属性的swiper-slide元素
all_images = wait.until(
    EC.visibility_of_all_elements_located((By.XPATH, "//div[contains(@class,'swiper-slide') and contains(@style,'background-image')]"))
)

2. 提取URL并自动去重

提取图片URL后,用集合(set)自动去重,再转回列表处理:

links = set()
for image in all_images:
    style_attr = image.get_attribute('style')
    # 兼容单引号/双引号的URL格式
    img_url = style_attr.split("(")[1].split(")")[0].replace('"', '').replace("'", "")
    links.add(img_url)  # 集合自动去重
# 转成列表方便后续遍历
unique_links = list(links)

3. 正确遍历下载所有图片

直接遍历去重后的列表,加入异常处理避免单个图片下载失败中断程序:

index = 1
for img_url in unique_links:
    try:
        response = requests.get(img_url, timeout=10)
        response.raise_for_status()  # 检查请求是否成功
        filename = f"{title.replace(' ', '-')}_{index}.jpg"
        with open(filename, 'wb') as file:
            file.write(response.content)
        print(f"Saving image.. {title} {index}")
        index += 1
    except requests.exceptions.RequestException as e:
        print(f"Failed to download {img_url}: {str(e)}")

完整修复后的代码

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import requests

# 假设driver和title变量已提前定义
links = set()
wait = WebDriverWait(driver, 10)  # 适当延长等待时间,确保图片完全加载

# 定位所有包含背景图的轮播slide
all_images = wait.until(
    EC.visibility_of_all_elements_located((By.XPATH, "//div[contains(@class,'swiper-slide') and contains(@style,'background-image')]"))
)

# 提取URL并去重
for image in all_images:
    style_attr = image.get_attribute('style')
    img_url = style_attr.split("(")[1].split(")")[0].replace('"', '').replace("'", "")
    links.add(img_url)

# 下载所有去重后的图片
index = 1
for img_url in links:
    try:
        response = requests.get(img_url, timeout=10)
        response.raise_for_status()
        filename = f"{title.replace(' ', '-')}_{index}.jpg"
        with open(filename, 'wb') as file:
            file.write(response.content)
        print(f"Saving image.. {title} {index}")
        index += 1
    except requests.exceptions.RequestException as e:
        print(f"Error downloading {img_url}: {e}")

额外优化(针对动态加载的轮播图)

如果你的目标页面是点击「下一页」才加载新图片的动态轮播,需要模拟点击按钮直到没有更多图片,避免遗漏未加载的内容:

# 模拟点击下一页按钮,收集所有动态加载的图片
while True:
    try:
        next_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(@class,'swiper-button-next')]")))
        next_btn.click()
        # 等待新图片加载完成(通过判断旧元素失效)
        wait.until(EC.staleness_of(all_images[0]))
        # 重新获取所有图片元素
        all_images = wait.until(
            EC.visibility_of_all_elements_located((By.XPATH, "//div[contains(@class,'swiper-slide') and contains(@style,'background-image')]"))
        )
        # 更新URL集合
        for image in all_images:
            style_attr = image.get_attribute('style')
            img_url = style_attr.split("(")[1].split(")")[0].replace('"', '').replace("'", "")
            links.add(img_url)
    except:
        # 按钮不可点击,说明没有更多图片
        break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:47:50