最近需要通过条形码获取商品信息并整理一个商品信息数据表。直接手动录入商品信息太慢了,聪明如我一样的it人员是不会干这么多重复低效率的事情的,于是想到写个python程序来处理这个工作。首先想到的是把包含商品条形码图片中的条形码自动读取出来,然后通过条形码在一个数据库中查询这个商品信息。好了整体思路就两条:

一、识别商品图片中的条形码。这个采用opencv来解决

二、在一个数据库中查询条形码包含的商品信息。这个比第一个稍微麻烦些。因为本地没有这么一个数据库,网上找了好几个通过条形码查找商品信息的网站都不是太好用或收费。最后在多次查找后找到一个免费还比较好用条形码查询网站:https://68api.com/barcode  

上面两个主要问题的资源都找到了,下面就是怎么通过程序把这些整合起来自动获取我想要的信息并保存到excel,下面就直接上完整代码(本项目以查询药品为例):

import requests
import cv2
import os, sys
from pyzbar import pyzbar
from bs4 import BeautifulSoup
import openpyxl
from openpyxl import load_workbook
from openpyxl.styles import Font

pathexist = os.path.exists
pathjoin = os.path.join


# https://68api.com/barcode/6943116401245
# C:\Users\issuser\AppData\Local\Temp\_MEI69042\pyzbar\libiconv.dll
def writexls(itms, datas, fxls, sr=1, sc=1, title=' ', is_sv_fmt=True):
    def save_with_format(filename):
        # 加载刚刚创建的工作簿
        wb = load_workbook(filename)
        ws = wb.active
        # 设置默认字体和行高
        default_font = Font(name='Arial', size=10)
        for row in ws.iter_rows():
            for cell in row:
                cell.font = default_font
            # 设置行高(根据字体大小调整,15-20之间比较合适)
            ws.row_dimensions[row[0].row].height = 20
        # 自动调整列宽
        for column in ws.columns:
            max_length = 0
            column_letter = column[0].column_letter  # 获取列字母(如A, B, C)
            # 找到该列中最长的内容
            for cell in column:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            # 设置列宽,预留一些额外空间(1.2倍长度)
            adjusted_width = (max_length + 2) * 1.2
            # 限制最大宽度,避免过宽
            adjusted_width = min(adjusted_width, 400)
            # 设置最小宽度
            adjusted_width = max(adjusted_width, 10)
            ws.column_dimensions[column_letter].width = adjusted_width
        # 保存修改
        wb.save(filename)
        print(f"Excel文件已保存至 {filename},并自动调整了单元格宽高")

    sr = max(sr, 1)
    sc = max(sc, 1)
    # 创建Workbook对象
    workbook = openpyxl.Workbook()
    # 获取当前活动的Worksheet
    sheet = workbook.active
    # 设置Worksheet的标题
    sheet.title = title
    # 准备要写入的数据
    tdatas = [itms]
    tdatas.extend(datas)
    # 将数据写入单元格
    for i, r_data in enumerate(tdatas):
        for j, val in enumerate(r_data):
            sheet.cell(row=sr + i, column=sc + j, value=val)
    # 保存Workbook对象,创建Excel文件
    workbook.save(fxls)
    print('写入成功')
    if is_sv_fmt:
        save_with_format(fxls)

#opencv 识别条形码
def scan_barcode(image_path):
    """扫描图片中的条形码,返回编码"""
    print(image_path)
    image = cv2.imread(image_path)
    barcodes = pyzbar.decode(image)
    if barcodes:
        return barcodes[0].data.decode("utf-8")  # 返回第一个条形码的编码
    return None

#通过条形码网站爬取商品信息
def get_prod_infos(url):
    html = requests.get(url)
    html.encoding = 'utf-8'
    soup = BeautifulSoup(html.text, 'lxml')
    bar_1_right = soup.find('div', class_='bar-1-right')
    strong = bar_1_right.find('strong')
    trade_name = strong.text
    bar_1_list = soup.find('div', class_='bar-1-list')
    infos = {'药名': trade_name}
    for child in bar_1_list.children:
        text = child.text
        texts = text.strip().split('\n')
        if texts[0]:
            infos[texts[0]] = texts[1]
    bar_2_2_2_1 = soup.find('div', class_='bar-2-2-2-1')
    company = bar_2_2_2_1.text
    infos['公司名'] = company
    print(infos)
    return infos

#商品信息保存到excel中
def save_to_excel(xlsfile, infos):
    itms = list(infos[0].keys())
    datas = []
    for info in infos:
        data = [info[itm] for itm in itms]
        datas.append(data)
    writexls(itms, datas, xlsfile, sr=1, sc=1, title=' ')

#通过包含条形码的图片获取商品信息
def bar_code2prod_info(dtdir):
    Ainfos = []
    imnames = os.listdir(dtdir)
    for imname in imnames:
        imfile = pathjoin(dtdir, imname)
        bar_code = scan_barcode(imfile)
        url = f'https://68api.com/barcode/{bar_code}'
        infos = get_prod_infos(url)
        Ainfos.append(infos)
    resdir, dirname = os.path.split(dtdir)
    xlsname = f'{dirname}.xlsx'
    xlsfile = pathjoin(resdir, xlsname)
    save_to_excel(xlsfile, Ainfos)

# url = 'https://68api.com/barcode/6919108100090'

#程序打包为exe
def tmp():
    if getattr(sys, 'frozen', False):  # 判断是否为打包后的程序
        mdir = os.path.dirname(sys.executable)  # 可执行文件所在目录
    else:
        mdir = os.path.dirname(__file__)  # 脚本所在目录
    print(mdir)
    dtdir = pathjoin(mdir, 'bar_code')
    bar_code2prod_info(dtdir)


if __name__ == "__main__":
    tmp()

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐