用Python扫描图书条形码并构建个人藏书清单

您所在的位置:网站首页 怎么扫描isbn码 用Python扫描图书条形码并构建个人藏书清单

用Python扫描图书条形码并构建个人藏书清单

2024-07-09 01:20:25| 来源: 网络整理| 查看: 265

自己攒了几箱子的书,想着给它们建个数据库,试了知乎上提到的几款软件,要么是软件已经凉了,要么是需要收费。最可恨的是,我用某小程序顺利扫描了七十余本书,最后到处的表格里却出现了一句“说明:未付费书馆仅支持导出10条数据,付费书馆导出数据无限制。”当然了,收费无可厚非,你能不能提前说一声啊!于是我一气之下决定自己写一个Python程序,扫描图书的条形码(ISBN),通过公开的API获取相关信息,并保存图书信息到本地Excel表格中,同时也获取图书封面到本地,构建自己的个人藏书清单。

先看看最终效果。

清单:

封面:

思路 用python OpenCV调用摄像头; 使用zbar库扫描ISBN条形码; 调用查询接口获取图书信息; 将图书信息保存; 调用摄像头

安装python的OpenCV库opencv-python

1pip3 install opencv-python

如果没有安装numpy则会自动安装上去;

主要代码

12345678910111213141516171819202122import cv2cap = cv2.VideoCapture(0)if not cap.isOpened(): print("Cannot open camera") exit(0)while True: ret, frame = cap.read() if not ret: print("Failed to capture image") continue cv2.imshow('frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): breakcap.release()cv2.destroyAllWindows() 扫描条形码

安装python的zbar库pyzbar

1pip3 install pyzbar

解决错误Unable to find zbar shared library(Ubuntu)

1sudo apt-get install libzbar-dev

扫描条形码

123456789101112131415161718192021222324252627import cv2from pyzbar.pyzbar import decodecap = cv2.VideoCapture(0)if not cap.isOpened(): print("Cannot open camera") exit(0)while True: ret, frame = cap.read() if not ret: print("Failed to capture image") continue cv2.imshow('frame', frame) barcodes = decode(frame) for barcode in barcodes: print("barcode = ", barcode.data) if cv2.waitKey(1) & 0xFF == ord('q'): breakcap.release()cv2.destroyAllWindows() 检索ISBN数据

首先找到一个公开的ISBN接口,这里我用的是中文ISBN公开信息查询接口 | 极客分享 (jike.xyz),用法如下(需要申请apikey,鼓励大家给API提供者捐赠项目维持经费):

12345678910111213import requestsurl = "https://api.jike.xyz/situ/book/isbn/"isbn = "9787020024759"apikey = "替换为申请的apikey"full_url = url + isbn + "?apikey=" + apikeyresponse = requests.request("GET", full_url)print(response.text)

安装依赖

1pip3 install requests

整合思路

扫描到一个ISBN后暂停捕获画面; 通过API获取该ISBN对应的书籍数据; 处理该数据(保存或不保存); 继续扫描;

实现

123456789101112131415161718192021222324252627282930313233343536373839from time import sleepimport cv2from pyzbar.pyzbar import decodeimport requestsurl = "https://api.jike.xyz/situ/book/isbn/"isbn = "9787020024759"apikey = "替换为申请的apikey"cap = cv2.VideoCapture(0)if not cap.isOpened(): print("Cannot open camera") exit(0)while True: ret, frame = cap.read() if not ret: print("Failed to capture image") continue cv2.imshow('frame', frame) barcodes = decode(frame) for barcode in barcodes: isbn = barcode.data.decode("utf-8") full_url = url + isbn + "?apikey=" + apikey response = requests.request("GET", full_url) print(response.text) sleep(3) if cv2.waitKey(1) & 0xFF == ord('q'): breakcap.release()cv2.destroyAllWindows() 图书信息数据的解析与保存

返回的数据为json格式,需要解析出具体的字段,提供API的网站给出了返回参数的说明,其实远远不止这些,可以print出来看一下:

名称 类型 说明 subname string 书名 author string 作者 authorIntro string 作者简介 photoUrl string 图片封面 publishing string 出版社 published string 出版时间 description string 图书简介 doubanScore string 豆瓣评分

这里使用json.loads()函数来解析:

123456789101112json_data = json.loads(response.text)ret = json_data["ret"]msg = json_data["msg"]data = json_data["data"]print("返回信息: " + msg + "(ISBN" + isbn + ")")if ret == 0 and data != None: is_save = input("是否保存?(y/n)") if is_save == 'y' or is_save == 'Y': save_book(data)else: print("未找到该书籍")sleep(1)

可以将数据保存到excel,可以使用pandas库来实现,操作比较方便,首先安装依赖:

1pip3 install openpyxl, pandas

具体保存的思路就是,如果没有文件先创建文件,设置列首,如果已经有了那就追加数据,方法是先把数据读出来,然后再追加,然后写回去:

123456789101112def save_book(data): file_path = os.path.join(os.path.dirname(__file__), 'books.xlsx') if not os.path.exists(file_path): df = pd.DataFrame(columns=['id', 'name', 'author', 'subname', 'translator', 'publishing', 'designed', 'code', 'douban', 'doubanScore', 'brand', 'weight', 'size', 'pages', 'photoUrl', 'localPhotoUrl', 'price', 'froms', 'num', 'createTime', 'uptime', 'authorIntro', 'description', 'reviews', 'tags'], dtype=str) df.to_excel(file_path, index=False) df = pd.read_excel(file_path, dtype=str) for key in data.keys(): data[key] = str(data[key]) df = df.append(data, ignore_index=True) df.to_excel(file_path, index=False)

还有就是发现有一个数据项为photoUrl,这是书籍封面的URL,同样可以抓取了保存下来,实现如下:

1234567891011photoUrl = data['photoUrl']if photoUrl != "": print("save photo from" + photoUrl) try: r = requests.request("GET", photoUrl) save_path = "./photo/" +str(data["code"]) + "." + photoUrl.split('.')[-1] print(save_path) with open(save_path, 'wb') as f: f.write(r.content) except: print("save photo failed") 最终实现

整理以上代码,最终完整实现如下:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121import jsonimport osfrom time import sleepimport cv2from pyzbar.pyzbar import decodeimport requestsimport pandas as pd# 将图书数据和封面图片保存到本地def save_book(data): # 书籍列表存放的文件 file_path = os.path.join(os.path.dirname(__file__), 'books.xlsx') print(file_path) # 如果文件不存在,则创建文件并添加表头 if not os.path.exists(file_path): # 表头 df = pd.DataFrame(columns=['id', 'name', 'author', 'subname', 'translator', 'publishing', 'designed', 'code', 'douban', 'doubanScore', 'brand', 'weight', 'size', 'pages', 'photoUrl', 'localPhotoUrl', 'price', 'froms', 'num', 'createTime', 'uptime', 'authorIntro', 'description', 'reviews', 'tags'], dtype=str) # 保存到本地 df.to_excel(file_path, index=False) # 如果文件存在,则读取文件并追加数据 # 读取数据到dataframe中,数据类型为str防止格式错误 df = pd.read_excel(file_path, dtype=str) # 把数据都转换为字符串 for key in data.keys(): data[key] = str(data[key]) if data[key] is not None else '' # 追加数据到dataframe中 df = df.append(data, ignore_index=True) # 保存到本地 df.to_excel(file_path, index=False) # 将图书封面保存到本地 # 图书封面的url photoUrl = data['photoUrl'] if photoUrl != "": print("从此URL抓取封面: " + photoUrl) try: # 请求图书封面 r = requests.request("GET", photoUrl) # 图书封面的本地路径 save_path = os.path.join(os.path.dirname(__file__), "photo") print(save_path) if not os.path.exists(save_path): os.makedirs(save_path) save_path = os.path.join(save_path, str(data["code"]) + "." + photoUrl.split('.')[-1]) # 保存图书封面到本地 with open(save_path, 'wb') as f: f.write(r.content) print("保存封面成功") except: print("保存封面失败")if __name__ == '__main__': # 抓取数据用的API和apikey url = "https://api.jike.xyz/situ/book/isbn/" apikey = "替换为申请的apikey" # 获取并打开摄像头 cap = cv2.VideoCapture(0) # 测试摄像头是否打开 if not cap.isOpened(): print("无法打开摄像头") exit(0) # 对摄像头获取到的每一帧进行处理 while True: # 获取一帧 ret, frame = cap.read() # 判断是否成功抓取到了图像 if not ret: print("抓取图片失败") continue # 显示捕获到的帧 cv2.imshow('摄像头', frame) # 按下q键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break # 尝试解析帧中的条形码 barcodes = decode(frame) # 如果没有解析到条形码,则继续下一次循环 if len(barcodes) == 0: continue # 如果解析到了条形码,则解析条形码中的ISBN数据并抓取图书数据 for barcode in barcodes: # 获取ISBN数据 isbn = barcode.data.decode("utf-8") # 拼接完整的API请求URL full_url = url + isbn + "?apikey=" + apikey # 发送API请求 response = requests.request("GET", full_url) # 解析响应内容 json_data = json.loads(response.text) # 解析响应内容判断是否成功 ret = json_data["ret"] msg = json_data["msg"] data = json_data["data"] # 提示相应信息 print("返回信息: " + msg + "( ISBN=" + isbn + " )") # 如果成功获取到了图书数据,则可以选择是否保存图书数据 if ret == 0 and data != None: is_save = input("是否保存?(Y/n)") if is_save == 'y' or is_save == 'Y' or is_save == '': save_book(data) # 如果获取图书数据失败,则提示并继续下一次循环 else: print("未找到该书籍") sleep(1) # 释放摄像头 cap.release() # 关闭所有窗口 cv2.destroyAllWindows()


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭