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

如何解决EAN码匹配结果存在错误数据的问题?

问题:EAN码网页匹配结果出现大量错误,求代码修复建议

我编写了一段代码,功能为从Excel文件读取EAN码列表,通过请求网页检查是否存在data-offer-ean属性与请求EAN码一致的产品,匹配则加入匹配列表,不匹配则加入不匹配列表。但目前结果中存在大量实际未在页面上的错误代码,附上代码寻求解决建议:

import pandas as pd
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
import openpyxl

df = pd.read_excel('eanBR.xlsx', dtype="int64")
mylist = df['ean'].tolist()
dopasowane = []
niedopasowane = []

def get_ean(symbol):
    response = requests.get(f"https://www.bricomarche.pl/search?query%5Bquerystring%5D={symbol}")
    soup = BeautifulSoup(response.content, "html.parser")
    div = soup.find('div', attrs={'data-offer-ean': True})
    if div:
        ean = div['data-offer-ean']
        if str(ean) == str(symbol):
            dopasowane.append(ean)
        else:
            niedopasowane.append(ean)
    else:
        niedopasowane.append(symbol)
    return ean

bar = tqdm(total=len(mylist), desc='Pobieranie danych', bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [{percent:.1f}% - {remaining}]')

for item in mylist:
    try:
        ean_result = get_ean(item)
        bar.update(1)
    except Exception as e:
        bar.update(1)

bar.close()

wb = openpyxl.Workbook()
ws_dopasowane = wb.active
ws_dopasowane.title = 'Dopasowane'
ws_niedopasowane = wb.create_sheet('Niedopasowane')

for idx, ean in enumerate(dopasowane, start=1):
    ws_dopasowane.cell(row=idx, column=1, value=ean)

for idx, ean in enumerate(niedopasowane, start=1):
    ws_niedopasowane.cell(row=idx, column=1, value=ean)

wb.save('wynik.xlsx')

问题分析与修复建议

1. 仅匹配第一个产品,忽略其他结果

原代码用soup.find()只获取页面中第一个带data-offer-ean的div,但搜索页面可能返回多个产品,第一个不匹配不代表没有匹配项。需要遍历所有匹配元素:

# 替换原div查找逻辑
product_divs = soup.find_all('div', attrs={'data-offer-ean': True})
matched = False
target_ean = str(symbol)
for div in product_divs:
    ean = div['data-offer-ean']
    if ean == target_ean:
        dopasowane.append(target_ean)
        matched = True
        break
if not matched:
    niedopasowane.append(target_ean)

2. 异常处理不完善,存在未定义变量风险

原代码中当div不存在时,return ean会抛出NameError,且异常捕获后未做记录,无法排查请求失败原因。修改后:

def get_ean(symbol):
    target_ean = str(symbol)
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
        }
        # 添加请求头避免被反爬拦截,设置超时
        response = requests.get(f"https://www.bricomarche.pl/search?query%5Bquerystring%5D={target_ean}", headers=headers, timeout=10)
        response.raise_for_status()  # 触发HTTP错误异常
        soup = BeautifulSoup(response.content, "html.parser")
        product_divs = soup.find_all('div', attrs={'data-offer-ean': True})
        matched = False
        for div in product_divs:
            ean = div['data-offer-ean']
            if ean == target_ean:
                dopasowane.append(target_ean)
                matched = True
                break
        if not matched:
            niedopasowane.append(target_ean)
    except Exception as e:
        print(f"处理EAN {target_ean}时出错: {str(e)}")
        niedopasowane.append(target_ean)

3. 未处理反爬机制

频繁无标识请求易被网站拦截,返回空页面或错误内容导致匹配错误。需添加请求头并控制请求频率:

import time

# 在循环中添加延迟
for item in mylist:
    try:
        get_ean(item)
        bar.update(1)
        time.sleep(1)  # 每秒请求一次,降低被拦截概率
    except Exception as e:
        bar.update(1)
        time.sleep(1)

4. EAN格式统一处理

Excel读取整数会丢失前导零,导致和网页返回的字符串格式不匹配,需直接读取为字符串:

# 读取时保留字符串格式
df = pd.read_excel('eanBR.xlsx', dtype=str)
mylist = df['ean'].tolist()

修复后的完整代码

import pandas as pd
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
import openpyxl
import time

# 读取EAN时保留字符串格式,避免前导零丢失
df = pd.read_excel('eanBR.xlsx', dtype=str)
mylist = df['ean'].tolist()
dopasowane = []
niedopasowane = []

def get_ean(symbol):
    target_ean = symbol.strip()  # 去除可能的空格
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
        }
        response = requests.get(
            f"https://www.bricomarche.pl/search?query%5Bquerystring%5D={target_ean}",
            headers=headers,
            timeout=10
        )
        response.raise_for_status()
        soup = BeautifulSoup(response.content, "html.parser")
        # 遍历所有带data-offer-ean的产品
        product_divs = soup.find_all('div', attrs={'data-offer-ean': True})
        matched = False
        for div in product_divs:
            page_ean = div['data-offer-ean'].strip()
            if page_ean == target_ean:
                dopasowane.append(target_ean)
                matched = True
                break
        if not matched:
            niedopasowane.append(target_ean)
    except Exception as e:
        print(f"EAN {target_ean} 处理失败: {str(e)}")
        niedopasowane.append(target_ean)

bar = tqdm(total=len(mylist), desc='Pobieranie danych', bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [{percent:.1f}% - {remaining}]')

for item in mylist:
    get_ean(item)
    bar.update(1)
    time.sleep(1)  # 控制请求频率

bar.close()

# 写入结果
wb = openpyxl.Workbook()
ws_dopasowane = wb.active
ws_dopasowane.title = 'Dopasowane'
ws_niedopasowane = wb.create_sheet('Niedopasowane')

for idx, ean in enumerate(dopasowane, start=1):
    ws_dopasowane.cell(row=idx, column=1, value=ean)

for idx, ean in enumerate(niedopasowane, start=1):
    ws_niedopasowane.cell(row=idx, column=1, value=ean)

wb.save('wynik.xlsx')

内容的提问来源于stack exchange,提问作者Łukasz Tarnowski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:47:16