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

使用BeautifulSoup爬取商品数据出现重复问题求助

商品数据重复问题排查与解决

问题根源分析

代码里存在以下核心问题导致数据重复及异常:

  1. productlink列表未重置:若后续爬取多页,每次循环会持续追加新链接,旧链接不会被清空,引发重复爬取同一商品
  2. 品牌数据处理逻辑错误:品牌信息获取放在商品详情页爬取之后,且每添加一个品牌就写入CSV,造成重复写入
  3. CSV写入时机错误:写入操作嵌套在品牌遍历循环内,每处理一个品牌就写一次文件,导致数据反复覆盖或重复追加
  4. 异常处理不完整:部分try块仅捕获异常但未给对应列表添加默认值,导致各列表长度不一致,最终数据错位
  5. offers数据格式错误:直接将BeautifulSoup对象加入列表,未提取文本,且异常分支未添加默认值

具体修复步骤

  • 每次爬取新页面时,清空productlink列表,避免积累旧链接
  • 调整品牌信息获取逻辑,在遍历商品列表时同步收集品牌,确保品牌与商品一一对应
  • 将CSV写入操作移到所有数据爬取完成之后,仅执行一次
  • 修复offers的获取逻辑,提取文本内容,并在异常时添加默认值
  • 完善所有try-except块,确保每个异常分支都往对应列表追加默认值,保证各列表长度一致

修正后的完整代码

import requests
from bs4 import BeautifulSoup
import csv
from itertools import zip_longest

base_url = 'https://niceonesa.com/ar/'

headers = {
    'User-Argent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
}

# 每页爬取前初始化所有数据列表,避免残留旧数据
for x in range(1, 2):
    productlink = []
    titles = []
    brands = []
    prices = []
    offers = []
    rates = []
    rate_starts = []

    # 获取商品列表页
    r = requests.get(f'{base_url}appcomponent--best-sales/?page={x}')
    soup = BeautifulSoup(r.content, 'lxml')
    productlist = soup.find_all('div', class_='product-container bg-white rounded-lg')

    # 同步收集商品链接和品牌信息
    for item in productlist:
        # 每个商品只取第一个有效链接,避免重复
        link = item.find('a', href=True)
        if link:
            productlink.append(base_url + link['href'])
        
        # 收集品牌信息
        try:
            brand = item.find('h3', class_='brand-product mb-1').text.strip()
            brands.append(brand)
        except:
            brands.append('non')

    # 遍历商品链接爬取详情页
    for link in productlink:
        r = requests.get(link, headers=headers)
        soup = BeautifulSoup(r.content, 'lxml')

        # 商品标题
        try:
            title = soup.find('h1', class_='title').text.strip()
            titles.append(title)
        except:
            titles.append('non')

        # 原价
        try:
            price = soup.find('h3', class_='preReductionPrice mb-2').text.strip()
            prices.append(price)
        except:
            prices.append('non')

        # 优惠价
        try:
            offer = soup.find('h3', class_='sellingPrice text-nowrap').text.strip()
            offers.append(offer)
        except:
            offers.append('non')

        # 评分
        try:
            rate = soup.find('span', class_='num-rating align-review').text.strip()
            rates.append(rate)
        except:
            rates.append('non')

        # 评分星级(修正原可能错误的选择器)
        try:
            rate_start = soup.find('div', class_='stars-rating').text.strip()
            rate_starts.append(rate_start)
        except:
            rate_starts.append('non')

    # 所有数据收集完成后,一次性写入CSV
    filelist = [titles, brands, prices, offers, rates, rate_starts, productlink]
    exported = zip_longest(*filelist)
    with open('oo.csv', 'w', encoding='utf-8-sig', newline='') as filecsv:
        wr = csv.writer(filecsv)
        wr.writerow(['title','brands','price','offer','rate','rate_starts','productlink'])
        wr.writerows(exported)

额外说明

  • 原代码中rate_start的选择器num-rating start可能有误,这里修正为更合理的stars-rating,可根据实际页面结构调整
  • 商品链接收集时改为只取每个商品的第一个链接,避免同一商品多个链接导致重复爬取
  • 所有数据列表在每页爬取前重新初始化,确保多页爬取时数据不会交叉污染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:30:42