当前位置: 首页 > news >正文

孔夫子旧书网开放平台接口实战:古籍图书检索与商铺数据集成方案

孔夫子旧书网作为国内最大的旧书交易平台,其开放接口为古籍爱好者、图书经销商和学术研究机构提供了便捷的图书数据获取渠道。与其他电商平台相比,孔夫子平台接口专注于旧书、古籍、善本等特色商品,具有独特的元数据结构和检索方式。本文将系统讲解孔夫子开放平台核心接口的技术实现,重点解决接口认证、古籍信息解析、商铺数据集成和批量检索优化等关键问题,提供一套可直接应用的完整解决方案。

一、接口基础信息与应用场景

接口核心信息

孔夫子开放平台主要接口的关键技术参数:

  • 接口域名https://open.kongfz.com/api
  • 认证方式:API Key + 数字签名
  • 请求格式:HTTP POST,JSON 格式参数
  • 响应格式:JSON
  • 编码格式:UTF-8
  • 调用限制:单应用 QPS=3,日调用上限 3000 次

核心接口列表

接口名称接口地址功能描述
图书检索/v2/books/search按关键词、作者、年代等检索图书
图书详情/v2/books/detail获取单本图书的详细信息
商铺检索/v2/shops/search检索符合条件的商铺
商铺详情/v2/shops/detail获取商铺的详细信息和在售商品
分类列表/v2/categories获取图书分类体系

典型应用场景

  • 古籍数字化项目:批量获取古籍元数据用于数字化存档
  • 学术研究工具:分析特定时期或作者的著作流传情况
  • 旧书商管理系统:多平台商品同步与价格监控
  • 私人藏书管理:个人藏书与孔网数据比对分析
  • 图书交易平台:集成孔网商品丰富自身平台内容

接口调用流程

plaintext

API Key申请 → 签名生成 → 请求参数构造 → 接口调用 → 响应解析 → 数据存储 → 缓存更新

点击获取key和secret

二、接口认证与参数详解

认证方式说明

孔夫子开放平台采用 API Key + 签名的认证方式:

  1. 开发者在平台注册并获取 API Key
  2. 每次请求时,使用 API Key 和请求参数生成签名
  3. 服务器验证签名有效性后处理请求

签名生成算法

  1. 将所有请求参数(不包括 signature)按参数名 ASCII 码升序排序
  2. 拼接为 "key=value&key=value" 格式的字符串
  3. 在字符串末尾拼接 API Secret
  4. 对拼接后的字符串进行 MD5 加密,得到 32 位小写字符串作为签名

公共请求参数

参数名类型说明
appKeyString应用唯一标识
timestampLong时间戳(毫秒)
signatureString签名结果
formatString响应格式,固定为 json

图书检索核心参数

参数名类型说明是否必须
keywordString搜索关键词
authorString作者
publisherString出版社
categoryIdInteger分类 ID
eraString年代,如 "清代"、"民国"
minPriceFloat最低价格
maxPriceFloat最高价格
bookConditionInteger品相:1 - 全新 2 - 九五品 3 - 九品 ... 8 - 八五品以下
pageInteger页码,默认 1
pageSizeInteger每页条数,1-20
sortString排序方式:price_asc, price_desc, publish_time_desc

响应结果结构

图书检索接口的核心响应字段:

json

{"code": 200,"message": "success","data": {"total": 1250,"page": 1,"pageSize": 20,"totalPage": 63,"items": [{"id": "123456","title": "论语集注","author": "朱熹 注","publisher": "中华书局","publishTime": "1983-05","era": "现代","edition": "第1版","binding": "平装","pages": 320,"price": 58.00,"originalPrice": 68.00,"bookCondition": 2,"bookConditionDesc": "九五品","shopId": "s7890","shopName": "古籍书店","coverImg": "https://img.kongfz.com/books/123456.jpg","description": "本书为论语集注的重印本...","tags": ["儒家", "经典", "哲学"]}]}
}

三、核心技术实现

1. 孔夫子接口认证工具类

python

运行

import hashlib
import time
import json
from urllib.parse import urlencodeclass KongfzAuthUtil:"""孔夫子开放平台认证工具类"""@staticmethoddef generate_sign(params, app_secret):"""生成签名:param params: 参数字典:param app_secret: 应用密钥:return: 签名字符串"""try:# 1. 过滤空值参数和signature字段valid_params = {k: v for k, v in params.items() if v is not None and v != "" and k != "signature"}# 2. 按参数名ASCII升序排序sorted_params = sorted(valid_params.items(), key=lambda x: x[0])# 3. 拼接为key=value&key=value格式param_str = urlencode(sorted_params)# 4. 拼接appSecret并进行MD5加密sign_str = f"{param_str}{app_secret}"sign = hashlib.md5(sign_str.encode('utf-8')).hexdigest().lower()return signexcept Exception as e:print(f"生成签名失败: {str(e)}")return None@staticmethoddef get_timestamp():"""获取当前时间戳(毫秒)"""return int(time.time() * 1000)

2. 图书检索接口客户端

python

运行

import requests
import time
from threading import Lock
from datetime import datetimeclass KongfzBookClient:"""孔夫子图书接口客户端"""def __init__(self, app_key, app_secret):self.app_key = app_keyself.app_secret = app_secretself.base_url = "https://open.kongfz.com/api"self.timeout = 15  # 超时时间(秒)self.qps_limit = 3  # QPS限制self.last_request_time = 0self.request_lock = Lock()  # 线程锁控制QPSdef _get_common_params(self):"""生成公共请求参数"""return {"appKey": self.app_key,"timestamp": KongfzAuthUtil.get_timestamp(),"format": "json"}def _check_qps(self):"""检查并控制QPS"""with self.request_lock:current_time = time.time()interval = 1.0 / self.qps_limit  # 每次请求最小间隔elapsed = current_time - self.last_request_timeif elapsed < interval:# 需要等待的时间time.sleep(interval - elapsed)self.last_request_time = time.time()def search_books(self,** kwargs):"""搜索图书:param kwargs: 搜索参数:return: 搜索结果字典"""# 检查QPS限制self._check_qps()# 1. 构造请求URLurl = f"{self.base_url}/v2/books/search"# 2. 构建请求参数params = self._get_common_params()# 添加业务参数valid_params = ["keyword", "author", "publisher", "categoryId", "era","minPrice", "maxPrice", "bookCondition", "page", "pageSize", "sort"]for param in valid_params:if param in kwargs and kwargs[param] is not None:params[param] = kwargs[param]# 3. 生成签名params["signature"] = KongfzAuthUtil.generate_sign(params, self.app_secret)# 4. 发送请求try:response = requests.post(url,json=params,headers={"Content-Type": "application/json;charset=utf-8","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"},timeout=self.timeout)# 5. 解析响应result = response.json()# 6. 处理响应结果if result.get("code") == 200:return self._parse_search_result(result.get("data", {}))else:raise Exception(f"搜索图书失败: {result.get('message', '未知错误')} "f"(错误码: {result.get('code', '未知')})")except Exception as e:print(f"图书搜索接口调用异常: {str(e)}")return Nonedef get_book_detail(self, book_id):"""获取图书详情:param book_id: 图书ID:return: 图书详情字典"""# 检查QPS限制self._check_qps()# 1. 构造请求URLurl = f"{self.base_url}/v2/books/detail"# 2. 构建请求参数params = self._get_common_params()params["id"] = book_id# 3. 生成签名params["signature"] = KongfzAuthUtil.generate_sign(params, self.app_secret)# 4. 发送请求try:response = requests.post(url,json=params,headers={"Content-Type": "application/json;charset=utf-8"},timeout=self.timeout)# 5. 解析响应result = response.json()# 6. 处理响应结果if result.get("code") == 200:return self._parse_book_detail(result.get("data", {}))else:raise Exception(f"获取图书详情失败: {result.get('message', '未知错误')} "f"(错误码: {result.get('code', '未知')})")except Exception as e:print(f"图书详情接口调用异常: {str(e)}")return Nonedef _parse_search_result(self, raw_data):"""解析搜索结果"""if not raw_data or "items" not in raw_data:return None# 处理图书列表books = []for item in raw_data["items"]:books.append({"id": item.get("id", ""),"title": item.get("title", ""),"author": item.get("author", ""),"publisher": item.get("publisher", ""),"publish_time": item.get("publishTime", ""),"era": item.get("era", ""),"edition": item.get("edition", ""),"binding": item.get("binding", ""),"pages": item.get("pages", 0),"price": float(item.get("price", 0)),"original_price": float(item.get("originalPrice", 0)),"book_condition": item.get("bookCondition", 0),"book_condition_desc": item.get("bookConditionDesc", ""),"shop_id": item.get("shopId", ""),"shop_name": item.get("shopName", ""),"cover_img": self._complete_image_url(item.get("coverImg", "")),"description": item.get("description", ""),"tags": item.get("tags", []),"fetch_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")})return {"search_info": {"total": raw_data.get("total", 0),"page": raw_data.get("page", 1),"page_size": raw_data.get("pageSize", 20),"total_page": raw_data.get("totalPage", 0)},"books": books}def _parse_book_detail(self, raw_data):"""解析图书详情"""if not raw_data:return None# 处理图书详情信息return {"id": raw_data.get("id", ""),"title": raw_data.get("title", ""),"subtitle": raw_data.get("subtitle", ""),"author": raw_data.get("author", ""),"translator": raw_data.get("translator", ""),"publisher": raw_data.get("publisher", ""),"publish_time": raw_data.get("publishTime", ""),"print_time": raw_data.get("printTime", ""),"era": raw_data.get("era", ""),"edition": raw_data.get("edition", ""),"print": raw_data.get("print", ""),"binding": raw_data.get("binding", ""),"pages": raw_data.get("pages", 0),"word_count": raw_data.get("wordCount", 0),"isbn": raw_data.get("isbn", ""),"price": float(raw_data.get("price", 0)),"original_price": float(raw_data.get("originalPrice", 0)),"book_condition": raw_data.get("bookCondition", 0),"book_condition_desc": raw_data.get("bookConditionDesc", ""),"description": raw_data.get("description", ""),"content_desc": raw_data.get("contentDesc", ""),"author_desc": raw_data.get("authorDesc", ""),"shop_info": {"id": raw_data.get("shopId", ""),"name": raw_data.get("shopName", ""),"score": float(raw_data.get("shopScore", 0)),"sales": raw_data.get("shopSales", 0),"location": raw_data.get("shopLocation", "")},"images": [self._complete_image_url(img) for img in raw_data.get("images", [])],"tags": raw_data.get("tags", []),"category": raw_data.get("category", {}),"fetch_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")}def _complete_image_url(self, url):"""补全图片URL"""if url and not url.startswith(("http://", "https://")):return f"https:{url}" if url.startswith("//") else f"https://img.kongfz.com{url}"return url

3. 商铺接口客户端

python

运行

class KongfzShopClient:"""孔夫子商铺接口客户端"""def __init__(self, app_key, app_secret):self.app_key = app_keyself.app_secret = app_secretself.base_url = "https://open.kongfz.com/api"self.timeout = 15  # 超时时间(秒)self.qps_limit = 3  # QPS限制self.last_request_time = 0self.request_lock = Lock()  # 线程锁控制QPSdef _get_common_params(self):"""生成公共请求参数"""return {"appKey": self.app_key,"timestamp": KongfzAuthUtil.get_timestamp(),"format": "json"}def _check_qps(self):"""检查并控制QPS"""with self.request_lock:current_time = time.time()interval = 1.0 / self.qps_limit  # 每次请求最小间隔elapsed = current_time - self.last_request_timeif elapsed < interval:# 需要等待的时间time.sleep(interval - elapsed)self.last_request_time = time.time()def search_shops(self, **kwargs):"""搜索商铺:param kwargs: 搜索参数:return: 搜索结果字典"""# 检查QPS限制self._check_qps()# 1. 构造请求URLurl = f"{self.base_url}/v2/shops/search"# 2. 构建请求参数params = self._get_common_params()# 添加业务参数valid_params = ["keyword", "categoryId", "location", "minScore", "minSales", "isVip", "page", "pageSize", "sort"]for param in valid_params:if param in kwargs and kwargs[param] is not None:params[param] = kwargs[param]# 3. 生成签名params["signature"] = KongfzAuthUtil.generate_sign(params, self.app_secret)# 4. 发送请求try:response = requests.post(url,json=params,headers={"Content-Type": "application/json;charset=utf-8"},timeout=self.timeout)# 5. 解析响应result = response.json()# 6. 处理响应结果if result.get("code") == 200:return self._parse_shop_search_result(result.get("data", {}))else:raise Exception(f"搜索商铺失败: {result.get('message', '未知错误')} "f"(错误码: {result.get('code', '未知')})")except Exception as e:print(f"商铺搜索接口调用异常: {str(e)}")return Nonedef get_shop_detail(self, shop_id,** kwargs):"""获取商铺详情:param shop_id: 商铺ID:param kwargs: 其他参数,如需要返回的商品数量:return: 商铺详情字典"""# 检查QPS限制self._check_qps()# 1. 构造请求URLurl = f"{self.base_url}/v2/shops/detail"# 2. 构建请求参数params = self._get_common_params()params["id"] = shop_id# 添加其他参数if "goodsCount" in kwargs:params["goodsCount"] = min(20, max(0, int(kwargs["goodsCount"])))# 3. 生成签名params["signature"] = KongfzAuthUtil.generate_sign(params, self.app_secret)# 4. 发送请求try:response = requests.post(url,json=params,headers={"Content-Type": "application/json;charset=utf-8"},timeout=self.timeout)# 5. 解析响应result = response.json()# 6. 处理响应结果if result.get("code") == 200:return self._parse_shop_detail(result.get("data", {}))else:raise Exception(f"获取商铺详情失败: {result.get('message', '未知错误')} "f"(错误码: {result.get('code', '未知')})")except Exception as e:print(f"商铺详情接口调用异常: {str(e)}")return Nonedef _parse_shop_search_result(self, raw_data):"""解析商铺搜索结果"""if not raw_data or "items" not in raw_data:return None# 处理商铺列表shops = []for item in raw_data["items"]:shops.append({"id": item.get("id", ""),"name": item.get("name", ""),"logo": self._complete_image_url(item.get("logo", "")),"location": item.get("location", ""),"score": float(item.get("score", 0)),"sales": item.get("sales", 0),"goods_count": item.get("goodsCount", 0),"is_vip": item.get("isVip", False),"vip_level": item.get("vipLevel", 0),"open_time": item.get("openTime", ""),"description": item.get("description", ""),"main_category": item.get("mainCategory", ""),"fetch_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")})return {"search_info": {"total": raw_data.get("total", 0),"page": raw_data.get("page", 1),"page_size": raw_data.get("pageSize", 20),"total_page": raw_data.get("totalPage", 0)},"shops": shops}def _parse_shop_detail(self, raw_data):"""解析商铺详情"""if not raw_data:return None# 处理商铺商品products = []if "products" in raw_data and isinstance(raw_data["products"], list):for p in raw_data["products"]:products.append({"id": p.get("id", ""),"title": p.get("title", ""),"price": float(p.get("price", 0)),"book_condition": p.get("bookConditionDesc", ""),"cover_img": self._complete_image_url(p.get("coverImg", "")),"publish_time": p.get("publishTime", "")})return {"id": raw_data.get("id", ""),"name": raw_data.get("name", ""),"logo": self._complete_image_url(raw_data.get("logo", "")),"banner": self._complete_image_url(raw_data.get("banner", "")),"location": raw_data.get("location", ""),"score": float(raw_data.get("score", 0)),"score_detail": raw_data.get("scoreDetail", {}),"sales": raw_data.get("sales", 0),"goods_count": raw_data.get("goodsCount", 0),"month_sales": raw_data.get("monthSales", 0),"is_vip": raw_data.get("isVip", False),"vip_level": raw_data.get("vipLevel", 0),"open_time": raw_data.get("openTime", ""),"description": raw_data.get("description", ""),"business_scope": raw_data.get("businessScope", ""),"contact": {"phone": raw_data.get("phone", ""),"wechat": raw_data.get("wechat", ""),"qq": raw_data.get("qq", "")},"categories": raw_data.get("categories", []),"products": products,"fetch_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")}def _complete_image_url(self, url):"""补全图片URL"""if url and not url.startswith(("http://", "https://")):return f"https:{url}" if url.startswith("//") else f"https://img.kongfz.com{url}"return url

4. 数据管理器(缓存与批量处理)

python

运行

import os
import json
import sqlite3
from datetime import datetime, timedelta
import timeclass KongfzDataManager:"""孔夫子数据管理器,支持缓存与批量处理"""def __init__(self, app_key, app_secret, cache_dir="./kongfz_cache"):self.book_client = KongfzBookClient(app_key, app_secret)self.shop_client = KongfzShopClient(app_key, app_secret)self.cache_dir = cache_dirself.db_path = os.path.join(cache_dir, "kongfz_cache.db")self._init_cache()def _init_cache(self):"""初始化缓存数据库"""if not os.path.exists(self.cache_dir):os.makedirs(self.cache_dir)# 连接数据库conn = sqlite3.connect(self.db_path)cursor = conn.cursor()# 创建图书缓存表cursor.execute('''CREATE TABLE IF NOT EXISTS book_cache (book_id TEXT PRIMARY KEY,data TEXT,fetch_time TEXT)''')# 创建搜索缓存表cursor.execute('''CREATE TABLE IF NOT EXISTS search_cache (cache_key TEXT PRIMARY KEY,data TEXT,fetch_time TEXT,keyword TEXT)''')# 创建商铺缓存表cursor.execute('''CREATE TABLE IF NOT EXISTS shop_cache (shop_id TEXT PRIMARY KEY,data TEXT,fetch_time TEXT)''')conn.commit()conn.close()def search_books(self, keyword, use_cache=True, cache_ttl=3600, **kwargs):"""搜索图书,支持缓存:param keyword: 搜索关键词:param use_cache: 是否使用缓存:param cache_ttl: 缓存有效期(秒):param kwargs: 其他搜索参数:return: 搜索结果"""# 生成缓存键cache_key = self._generate_cache_key("book", keyword,** kwargs)# 尝试从缓存获取if use_cache:cached_data = self._get_cached_data("search_cache", cache_key, cache_ttl)if cached_data:print(f"使用缓存数据,关键词: {keyword},页码: {kwargs.get('page', 1)}")return cached_data# 从接口获取print(f"调用接口搜索,关键词: {keyword},页码: {kwargs.get('page', 1)}")result = self.book_client.search_books(keyword=keyword, **kwargs)# 更新缓存if result:self._update_cache("search_cache", cache_key, result, keyword)return resultdef get_book_detail(self, book_id, use_cache=True, cache_ttl=86400):"""获取图书详情,支持缓存:param book_id: 图书ID:param use_cache: 是否使用缓存:param cache_ttl: 缓存有效期(秒):return: 图书详情"""# 尝试从缓存获取if use_cache:cached_data = self._get_cached_data("book_cache", book_id, cache_ttl)if cached_data:print(f"使用缓存数据,图书ID: {book_id}")return cached_data# 从接口获取print(f"调用接口获取图书详情,ID: {book_id}")result = self.book_client.get_book_detail(book_id)# 更新缓存if result:self._update_cache("book_cache", book_id, result)return resultdef search_shops(self, keyword, use_cache=True, cache_ttl=3600,** kwargs):"""搜索商铺,支持缓存"""# 生成缓存键cache_key = self._generate_cache_key("shop", keyword, **kwargs)# 尝试从缓存获取if use_cache:cached_data = self._get_cached_data("search_cache", cache_key, cache_ttl)if cached_data:print(f"使用缓存数据,商铺搜索关键词: {keyword}")return cached_data# 从接口获取print(f"调用接口搜索商铺,关键词: {keyword}")result = self.shop_client.search_shops(keyword=keyword,** kwargs)# 更新缓存if result:self._update_cache("search_cache", cache_key, result, keyword)return resultdef get_shop_detail(self, shop_id, use_cache=True, cache_ttl=86400, **kwargs):"""获取商铺详情,支持缓存"""# 尝试从缓存获取if use_cache:cached_data = self._get_cached_data("shop_cache", shop_id, cache_ttl)if cached_data:print(f"使用缓存数据,商铺ID: {shop_id}")return cached_data# 从接口获取print(f"调用接口获取商铺详情,ID: {shop_id}")result = self.shop_client.get_shop_detail(shop_id,** kwargs)# 更新缓存if result:self._update_cache("shop_cache", shop_id, result)return resultdef batch_get_book_details(self, book_ids, use_cache=True, cache_ttl=86400):"""批量获取图书详情"""details = []for book_id in book_ids:detail = self.get_book_detail(book_id, use_cache, cache_ttl)if detail:details.append(detail)# 避免触发QPS限制,主动添加延迟time.sleep(0.5)return detailsdef _generate_cache_key(self, type_, keyword, **params):"""生成缓存键"""sorted_params = sorted(params.items(), key=lambda x: x[0])params_str = "&".join([f"{k}={v}" for k, v in sorted_params])return hashlib.md5(f"{type_}_{keyword}_{params_str}".encode()).hexdigest()def _get_cached_data(self, table, key, ttl):"""从缓存获取数据"""conn = sqlite3.connect(self.db_path)cursor = conn.cursor()cursor.execute(f"SELECT data, fetch_time FROM {table} WHERE {table[:-6]}_id = ?",(key,))result = cursor.fetchone()conn.close()if result:data_str, fetch_time = result# 检查缓存是否过期fetch_time_obj = datetime.strptime(fetch_time, "%Y-%m-%d %H:%M:%S")if (datetime.now() - fetch_time_obj).total_seconds() <= ttl:try:return json.loads(data_str)except:return Nonereturn Nonedef _update_cache(self, table, key, data, keyword=None):"""更新缓存"""if not data:returnconn = sqlite3.connect(self.db_path)cursor = conn.cursor()data_str = json.dumps(data, ensure_ascii=False)fetch_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")if table == "search_cache":# 搜索缓存有额外的keyword字段cursor.execute('''INSERT OR REPLACE INTO search_cache (cache_key, data, fetch_time, keyword)VALUES (?, ?, ?, ?)''', (key, data_str, fetch_time, keyword or ""))else:# 图书和商铺缓存cursor.execute(f'''INSERT OR REPLACE INTO {table} ({table[:-6]}_id, data, fetch_time)VALUES (?, ?, ?)''',(key, data_str, fetch_time))conn.commit()conn.close()def clean_expired_cache(self, max_age=86400 * 7):"""清理过期缓存,默认保留7天内的数据"""conn = sqlite3.connect(self.db_path)cursor = conn.cursor()# 计算过期时间expire_time = (datetime.now() - timedelta(seconds=max_age)).strftime("%Y-%m-%d %H:%M:%S")# 清理图书缓存cursor.execute("DELETE FROM book_cache WHERE fetch_time < ?", (expire_time,))deleted_books = cursor.rowcount# 清理搜索缓存cursor.execute("DELETE FROM search_cache WHERE fetch_time < ?", (expire_time,))deleted_searches = cursor.rowcount# 清理商铺缓存cursor.execute("DELETE FROM shop_cache WHERE fetch_time < ?", (expire_time,))deleted_shops = cursor.rowcountconn.commit()conn.close()print(f"清理过期缓存完成,删除图书缓存 {deleted_books} 条,搜索缓存 {deleted_searches} 条,商铺缓存 {deleted_shops} 条")return {"deleted_books": deleted_books,"deleted_searches": deleted_searches,"deleted_shops": deleted_shops}

四、完整使用示例

1. 古籍图书检索与详情获取

python

运行

def ancient_book_search_demo():# 替换为实际的应用信息APP_KEY = "your_app_key"APP_SECRET = "your_app_secret"# 初始化数据管理器data_manager = KongfzDataManager(APP_KEY, APP_SECRET)# 搜索参数:查找清代古籍search_params = {"keyword": "古籍","era": "清代","bookCondition": 3,  # 九品"minPrice": 100,"maxPrice": 5000,"page": 1,"pageSize": 10,"sort": "price_asc"  # 价格从低到高}# 执行搜索result = data_manager.search_books(**search_params,use_cache=True,cache_ttl=3600  # 缓存1小时)if result:print(f"===== 古籍搜索结果: {search_params['keyword']} =====")print(f"共搜索到 {result['search_info']['total']} 本图书,第 {result['search_info']['page']}/{result['search_info']['total_page']} 页")# 打印搜索结果for i, book in enumerate(result["books"], 1):print(f"\n{i}. {book['title']}")print(f"作者: {book['author']}")print(f"年代: {book['era']}")print(f"品相: {book['book_condition_desc']}")print(f"价格: ¥{book['price']}")print(f"商家: {book['shop_name']}")# 获取第一本图书的详细信息if result["books"]:first_book_id = result["books"][0]["id"]book_detail = data_manager.get_book_detail(first_book_id)if book_detail:print(f"\n===== 图书详情: {book_detail['title']} =====")print(f"详细描述: {book_detail['description'][:200]}...")print(f"出版信息: {book_detail['publisher']} {book_detail['publish_time']}")print(f"页数: {book_detail['pages']}页")print(f"商家信息: {book_detail['shop_info']['name']} (评分: {book_detail['shop_info']['score']})")print(f"图书图片: {book_detail['images'][0] if book_detail['images'] else '无'}")# 清理过期缓存data_manager.clean_expired_cache()if __name__ == "__main__":ancient_book_search_demo()

2. 商铺搜索与数据集成

python

运行

def shop_search_demo():# 替换为实际的应用信息APP_KEY = "your_app_key"APP_SECRET = "your_app_secret"# 初始化数据管理器data_manager = KongfzDataManager(APP_KEY, APP_SECRET)# 搜索古籍商铺shop_search_params = {"keyword": "古籍","location": "北京","minScore": 4.5,"minSales": 1000,"isVip": 1,"page": 1,"pageSize": 5,"sort": "sales_desc"  # 按销量排序}# 执行商铺搜索shop_result = data_manager.search_shops(** shop_search_params)if shop_result:print(f"===== 商铺搜索结果: {shop_search_params['keyword']} =====")print(f"共搜索到 {shop_result['search_info']['total']} 家商铺")# 打印商铺信息for i, shop in enumerate(shop_result["shops"], 1):print(f"\n{i}. {shop['name']}")print(f"位置: {shop['location']}")print(f"评分: {shop['score']} 分")print(f"销量: {shop['sales']} 单")print(f"在售图书: {shop['goods_count']} 本")print(f"开店时间: {shop['open_time']}")# 获取第一个商铺的详细信息if shop_result["shops"]:first_shop_id = shop_result["shops"][0]["id"]shop_detail = data_manager.get_shop_detail(first_shop_id,goodsCount=5  # 获取5件商品)if shop_detail:print(f"\n===== 商铺详情: {shop_detail['name']} =====")print(f"经营范围: {shop_detail['business_scope']}")print(f"联系方式: {shop_detail['contact']['phone']}")print(f"本月销量: {shop_detail['month_sales']} 单")# 打印商铺的热门商品if shop_detail["products"]:print("\n热门商品:")for i, product in enumerate(shop_detail["products"], 1):print(f"{i}. {product['title']} - ¥{product['price']} ({product['book_condition']})")if __name__ == "__main__":shop_search_demo()

五、常见问题与优化建议

1. 常见错误码及解决方案

错误码说明解决方案
200成功-
400参数错误检查必填参数是否齐全,参数格式是否正确
401认证失败检查 appKey 是否正确,签名是否有效,时间戳是否过期
403权限不足检查应用是否已申请该接口权限
429频率超限降低调用频率,确保不超过 QPS 限制
500服务器错误记录错误信息,稍后重试
503服务维护等待服务恢复后再调用

2. 数据获取优化策略

  • 精准检索:利用 era、bookCondition 等特有参数缩小搜索范围,提高结果相关性
  • 缓存分层:图书详情等变动少的数据设置较长缓存(24 小时),搜索结果设置较短缓存(1-6 小时)
  • 批量处理:批量获取图书详情时控制并发数,避免触发 QPS 限制
  • 增量更新:定期检查热门数据,只更新有变动的内容
  • 数据过滤:根据业务需求筛选必要字段,减少数据传输量

3. 古籍数据特色处理

  • 年代识别:针对古籍特有的 "清代"、"民国" 等年代信息建立专门的解析逻辑
  • 品相处理:将 bookCondition 转换为更易理解的描述(如 "九品" 对应 "保存完好,略有磨损")
  • 多卷处理:对 "全 X 册" 等多卷本图书进行特殊标记和处理
  • 版本区分:特别关注古籍的 "刻本"、"活字本"、"抄本" 等版本信息
  • 描述解析:对图书描述中的古籍专有术语进行提取和标准化


文章转载自:

http://FHGExdo6.bpkqd.cn
http://5Mj4jScB.bpkqd.cn
http://PgliFEyU.bpkqd.cn
http://GmaWoKYw.bpkqd.cn
http://hy61jOJ1.bpkqd.cn
http://nI2DOuWE.bpkqd.cn
http://EP7TAEV1.bpkqd.cn
http://LalSxNpx.bpkqd.cn
http://T8J38kVi.bpkqd.cn
http://KKz08mV1.bpkqd.cn
http://9JGFBtuk.bpkqd.cn
http://0wjLTt0q.bpkqd.cn
http://fOqmz55b.bpkqd.cn
http://IWSiAUBQ.bpkqd.cn
http://zTQZTYp5.bpkqd.cn
http://EvpW3oKK.bpkqd.cn
http://X0GxSxPu.bpkqd.cn
http://0YomPeAK.bpkqd.cn
http://GQrHywvQ.bpkqd.cn
http://I5jEhZP2.bpkqd.cn
http://4DvTPKjE.bpkqd.cn
http://f5vIqYGr.bpkqd.cn
http://QMk2hRB7.bpkqd.cn
http://qyqpkhvg.bpkqd.cn
http://s4Dn4WSO.bpkqd.cn
http://w5LT29kt.bpkqd.cn
http://hXaY1YbU.bpkqd.cn
http://oLo7fnLt.bpkqd.cn
http://tHnjgAOX.bpkqd.cn
http://e5zx5GJ4.bpkqd.cn
http://www.dtcms.com/a/387973.html

相关文章:

  • 中农农业机器人具身导航最新突破!T-araVLN:农业机器人视觉语言导航的指令翻译器
  • CoaXPress Device HOST设备发现-速率匹配
  • c++中的继承和多态
  • GPTZero:在线AI内容检测工具
  • Ubuntu 磁盘扩容与扩容失败问题解决( df -h 与 GParted 显示空间不一致的问题 -LVM)
  • pytorch图像识别,入门深度学习第一个项目
  • Ubuntu 22.04 使用 Docker 部署 Redis 6.2(带密码与持久化)
  • Termux 安装 Trilium 笔记,全平台同步的好用开源 Markdow 笔记,超大型双链接笔记
  • CVAT工具的详细使用教程(视频标注)
  • 【一周AI资讯】Claude自动抓取网页;美团发布生活Agent;阿里通义发布双模型
  • [视图功能4] 视图共享与外部链接权限管理:安全又灵活的数据展示
  • 20250917在荣品RD-RK3588-MID开发板的Android13系统下使用tinyplay播放wav格式的音频
  • PAT 1013 Battle Over Cities
  • 自动驾驶车辆的网络安全威胁及防护技术
  • 《基于uni-app构建鸿蒙原生体验:HarmonyOS NEXT跨平台开发实战指南》
  • 数学_向量投影相关
  • 【完整源码+数据集+部署教程】传统韩文化元素分割系统: yolov8-seg-GFPN
  • hybrid实验
  • Prompt Engineering 技术文档
  • 《我看见的世界》- 李飞飞自传
  • TPS54302开关电源启动 1s 后输出电压掉电排查笔记 — TPS54302 5V→2.8V 案例
  • 具身智能数据采集方案,如何为机器人打造“数据燃料库”?
  • Prism模块化和对话服务
  • nas怎么提供给k8s容器使用
  • 【第五章:计算机视觉-项目实战之图像分类实战】1.经典卷积神经网络模型Backbone与图像-(8)多标签图像分类理论
  • 认知语义学中的意象图式对人工智能自然语言处理深层语义分析的影响与启示
  • [ffmpeg] 时间基总结
  • 数据结构排序入门(3):核心排序(归并排序,归并非递归排序,计数排序及排序扫尾复杂度分析)+八大排序源码汇总
  • 计算机网络七层模型理解
  • 同步与互斥学习笔记