孔夫子旧书网作为国内知名的古籍、二手书交易平台,其商品数据对于图书收藏、学术研究及二手书电商系统具有重要价值。本文将详细介绍孔夫子平台接口的调用方法,涵盖认证机制、搜索参数配置、数据解析及反爬策略,并提供可直接使用的 Python 代码实现,帮助开发者合规获取古籍和二手书数据。

一、孔夫子平台接口基础信息

孔夫子旧书网提供的开放接口主要包括图书搜索、商品详情、店铺信息等功能,其中/api/v1/books/search是获取图书列表的核心接口,特别适用于古籍、珍本、二手书的检索。

接口特点

  • 采用 API Key 认证机制,部分接口需要商业合作授权
  • 支持按书名、作者、出版社、年代、品相等级等多维度筛选
  • 包含古籍特有的版本信息、刻印年代、装帧形式等字段
  • 提供卖家信誉、交易记录等二手书交易关键数据

接口端点https://api.kongfz.com/api/v1/books/search

二、认证机制与核心参数

1. 认证方式

孔夫子接口采用简单直接的 API Key 认证:

  1. 在孔夫子开发者平台注册并申请应用,获取 API Key
  2. 在所有请求的 Header 中携带X-API-Key参数
  3. 商业用户可申请更高权限的 Secret Key 进行签名认证

2. 核心搜索参数

  • keyword:搜索关键字(书名、作者、ISBN 等,必填)
  • category:图书分类(古籍 / 二手书 / 期刊等,可选)
  • year_min/year_max:出版年代范围(可选)
  • condition:品相等级(1-10 级,10 为全新,可选)
  • price_min/price_max:价格区间(可选)
  • publisher:出版社(可选)
  • sort:排序方式(price_asc/price_desc/time_desc/credit_desc)
  • page:页码(默认 1)
  • limit:每页条数(1-20,默认 10)
  • rare:是否仅显示珍本(true/false,可选)

3. 响应数据结构

  • total:总结果数
  • page/limit:分页信息
  • books:图书列表数组
  • filters:可用筛选条件

三、完整代码实现

以下是 Python 实现的孔夫子旧书网图书搜索功能,包含 API 调用、数据解析和反爬策略:

import requests
import time
import random
from typing import Dict, List, Optional, Any
from user_agent import generate_user_agent
import logging# 配置日志
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('kongfz_api')class KongfzBookAPI:def __init__(self, api_key: str, use_proxy: bool = False, proxy_pool: List[str] = None):"""初始化孔夫子旧书网API客户端:param api_key: 平台申请的API Key:param use_proxy: 是否使用代理:param proxy_pool: 代理IP池列表"""self.api_key = api_keyself.base_url = "https://api.kongfz.com"self.search_endpoint = "/api/v1/books/search"self.detail_endpoint = "/api/v1/books/detail"self.max_limit = 20  # 最大每页条数self.use_proxy = use_proxyself.proxy_pool = proxy_pool or []self.session = self._init_session()def _init_session(self) -> requests.Session:"""初始化请求会话,配置持久连接"""session = requests.Session()session.headers.update({"Accept": "application/json","Content-Type": "application/json","X-API-Key": self.api_key,"Connection": "keep-alive"})return sessiondef _get_random_headers(self) -> Dict[str, str]:"""生成随机请求头,降低反爬风险"""return {"User-Agent": generate_user_agent(),"Accept-Language": random.choice(["zh-CN,zh;q=0.9", "zh-TW,zh;q=0.9,en;q=0.8"]),"Referer": "https://www.kongfz.com/"}def _get_proxy(self) -> Optional[Dict[str, str]]:"""从代理池获取随机代理"""if self.use_proxy and self.proxy_pool:proxy = random.choice(self.proxy_pool)return {"http": proxy, "https": proxy}return Nonedef search_books(self,keyword: str,category: Optional[str] = None,year_min: Optional[int] = None,year_max: Optional[int] = None,condition: Optional[int] = None,price_min: Optional[float] = None,price_max: Optional[float] = None,publisher: Optional[str] = None,sort: str = "time_desc",page: int = 1,limit: int = 10) -> Dict[str, Any]:"""搜索孔夫子旧书网图书:param keyword: 搜索关键字:param category: 图书分类:param year_min: 最小出版年份:param year_max: 最大出版年份:param condition: 品相等级(1-10):param price_min: 最低价格:param price_max: 最高价格:param publisher: 出版社:param sort: 排序方式:param page: 页码:param limit: 每页条数:return: 搜索结果"""# 限制每页最大条数limit = min(limit, self.max_limit)# 构建查询参数params: Dict[str, Any] = {"keyword": keyword,"sort": sort,"page": page,"limit": limit}# 添加可选参数if category:params["category"] = categoryif year_min is not None:params["year_min"] = year_minif year_max is not None:params["year_max"] = year_maxif condition is not None:params["condition"] = conditionif price_min is not None:params["price_min"] = price_minif price_max is not None:params["price_max"] = price_maxif publisher:params["publisher"] = publisher# 准备请求配置headers = self._get_random_headers()proxy = self._get_proxy()try:# 随机延迟,模拟人类行为time.sleep(random.uniform(0.8, 1.5))# 发送请求response = self.session.get(f"{self.base_url}{self.search_endpoint}",params=params,headers=headers,proxies=proxy,timeout=15)response.raise_for_status()# 解析响应result = response.json()# 处理API错误if result.get("code") != 0:logger.error(f"API错误: {result.get('msg')}")return {"success": False,"error_code": result.get("code"),"error_msg": result.get("msg")}# 解析搜索结果return self._parse_search_result(result.get("data", {}))except requests.exceptions.RequestException as e:logger.error(f"请求异常: {str(e)}")return {"success": False,"error_msg": f"请求异常: {str(e)}"}except Exception as e:logger.error(f"处理响应失败: {str(e)}")return {"success": False,"error_msg": f"处理响应失败: {str(e)}"}def _parse_search_result(self, raw_data: Dict[str, Any]) -> Dict[str, Any]:"""解析搜索结果为结构化数据"""# 分页信息pagination = {"total": raw_data.get("total", 0),"page": raw_data.get("page", 1),"limit": raw_data.get("limit", 10),"pages": (raw_data.get("total", 0) + raw_data.get("limit", 10) - 1) // raw_data.get("limit", 10)}# 解析图书列表books = []for item in raw_data.get("books", []):# 处理古籍特有的版本信息ancient_info = Noneif item.get("is_ancient"):ancient_info = {"edition": item.get("ancient_edition"),  # 版本"engraving_year": item.get("engraving_year"),  # 刻印年代"binding": item.get("binding"),  # 装帧"seal_info": item.get("seal_info")  # 钤印信息}books.append({"book_id": item.get("id"),"title": item.get("title"),"author": item.get("author"),"publisher": item.get("publisher"),"publish_year": item.get("publish_year"),"category": item.get("category"),"is_ancient": item.get("is_ancient", False),  # 是否古籍"ancient_info": ancient_info,"condition": {"level": item.get("condition_level"),  # 品相等级"description": item.get("condition_desc")  # 品相描述},"price": {"current": item.get("price"),"original": item.get("original_price"),"currency": "CNY"},"seller": {"id": item.get("seller_id"),"name": item.get("seller_name"),"credit": item.get("seller_credit"),  # 信誉等级"score": item.get("seller_score")  # 好评率},"images": {"main": item.get("main_image"),"thumbnail": item.get("thumbnail")},"url": item.get("url"),"tags": item.get("tags", [])})# 解析可用筛选条件filters = self._parse_filters(raw_data.get("filters", {}))return {"success": True,"pagination": pagination,"books": books,"filters": filters}def _parse_filters(self, raw_filters: Dict[str, Any]) -> Dict[str, Any]:"""解析筛选条件"""filters = {}# 分类筛选if "categories" in raw_filters:filters["categories"] = [{"id": item.get("id"), "name": item.get("name"), "count": item.get("count")}for item in raw_filters["categories"]]# 品相筛选if "conditions" in raw_filters:filters["conditions"] = [{"level": item.get("level"), "name": item.get("name"), "count": item.get("count")}for item in raw_filters["conditions"]]# 年代筛选if "years" in raw_filters:filters["years"] = raw_filters["years"]return filtersdef batch_search(self,keyword: str,max_pages: int = 3,**kwargs) -> Dict[str, Any]:"""批量获取多页搜索结果:param keyword: 搜索关键字:param max_pages: 最大获取页数:param**kwargs: 其他搜索参数:return: 合并的搜索结果"""all_books = []current_page = 1total_pages = 1while current_page <= max_pages and current_page <= total_pages:logger.info(f"搜索第 {current_page} 页,关键字: {keyword}")# 搜索当前页result = self.search_books(keyword=keyword,page=current_page,**kwargs)if not result.get("success"):return result# 收集图书数据all_books.extend(result.get("books", []))# 更新分页信息pagination = result.get("pagination", {})total_pages = pagination.get("pages", 1)# 准备下一页current_page += 1# 增加页数间隔,降低反爬风险if current_page <= max_pages:time.sleep(random.uniform(1.5, 2.5))return {"success": True,"total_books": len(all_books),"books": all_books,"summary": {"total_available": pagination.get("total", 0),"fetched_pages": current_page - 1}}# 使用示例
if __name__ == "__main__":# 替换为你的API KeyAPI_KEY = "your_api_key"# 代理配置(可选)PROXY_POOL = [# "http://ip1:port",# "http://ip2:port"]# 初始化API客户端kongfz_api = KongfzBookAPI(api_key=API_KEY,use_proxy=False,  # 根据需要开启proxy_pool=PROXY_POOL)# 示例1:搜索古籍ancient_result = kongfz_api.search_books(keyword="论语",category="ancient",  # 古籍分类year_min=1949,year_max=2023,condition=8,  # 8级及以上品相sort="price_asc",page=1,limit=10)if ancient_result["success"]:print(f"古籍搜索: 找到 {ancient_result['pagination']['total']} 本相关图书")if ancient_result["books"]:book = ancient_result["books"][0]print(f"书名: {book['title']}")print(f"作者: {book['author']}")print(f"价格: {book['price']['current']}元")print(f"品相: {book['condition']['level']}级 - {book['condition']['description']}")if book["is_ancient"]:print(f"版本: {book['ancient_info']['edition']}")# 示例2:批量搜索二手书# batch_result = kongfz_api.batch_search(#     keyword="鲁迅全集",#     category="secondhand",  # 二手书分类#     price_min=50,#     price_max=500,#     max_pages=2# )# # if batch_result["success"]:#     print(f"\n批量搜索: 共获取 {batch_result['total_books']} 本图书")

四、代码核心功能解析

1. 反爬策略实现

  • 随机生成 User-Agent 和请求头,模拟不同浏览器行为
  • 加入随机请求延迟,避免固定访问频率被识别
  • 支持代理 IP 池配置,分散请求来源
  • 使用持久化 Session,模拟正常用户浏览行为

2. 古籍数据特色处理

  • 专门解析古籍特有的版本、刻印年代、装帧等信息
  • 区分古籍与普通二手书的数据结构
  • 提取钤印信息等古籍收藏关键维度

3. 搜索功能设计

  • 支持完整的图书筛选参数,满足古籍和二手书的搜索需求
  • 提供单页搜索和多页批量搜索两种模式
  • 批量搜索时动态调整间隔时间,平衡效率与安全性

4. 数据结构化

  • 按图书类型组织数据,区分普通二手书和古籍
  • 提取卖家信誉、品相描述等二手交易关键信息
  • 解析可用筛选条件,便于前端实现高级筛选功能

五、实战注意事项

1. 接口权限与申请

  • 孔夫子 API 分为免费版和商业版,免费版有调用频率限制(通常 QPS≤2)
  • 古籍珍本等敏感数据需要申请商业授权
  • 个人开发者需提供身份证明,企业开发者需提供营业执照

2. 反爬与合规

  • 免费版接口请勿进行高频次调用,建议单 IP 日调用不超过 1000 次
  • 数据使用需遵守孔夫子平台的版权协议,不得用于商业竞品
  • 尊重古籍数据的知识产权,引用时需注明来源

3. 搜索策略优化

  • 古籍搜索建议结合年代和版本筛选,提高精准度
  • 批量获取数据时,合理设置max_pages参数,避免触发限制
  • 对稀缺古籍建立缓存机制,缓存周期建议 7-30 天

4. 数据处理建议

  • 书名和作者可能存在异体字、通假字,需进行文字规范化处理
  • 品相描述为文本信息,可通过 NLP 技术提取关键评价
  • 出版年代可能存在模糊表述(如 "民国年间"),需特殊处理

六、功能扩展方向

  1. 开发古籍版本比对工具,基于多本同书数据进行版本差异分析
  2. 构建卖家信誉评估系统,结合历史交易和评价数据
  3. 实现图书价格趋势分析,追踪古籍市场价格波动
  4. 开发古籍修复需求识别功能,基于品相描述自动判断修复需求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93960.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93960.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/93960.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文件包含的学习笔记

面试问题 1&#xff0c;任意文件读取&#xff0c;到底读什么文件&#xff0c;有什么危害 权限是www 只能读第一个&#xff0c;读这个没用&#xff0c;密码在/etc/shadow中 其它没有权限 my.cnf mysql密码看不了 但是可以看见日志文件的目录 sql注入时&#xff0c;你有注…

Linux 软件包安装和管理的相关操作及使用总结(未完成)

一、基础知识1、软件包分类源码包&#xff08;Source Package&#xff09;&#xff1a;包含软件的源代码文件、编译指令和配置文件。需要用户自行编译安装&#xff0c;过程相对复杂&#xff0c;但灵活性高&#xff0c;可以定制安装选项。文件格式通常为.tar.gz、.tar.bz2等压缩…

【开发指南】飞凌i.MX9352核心板开发过程中的常见问题及排查思路

飞凌嵌入式作为NXP金牌合作伙伴&#xff0c;已基于i.MX系列应用处理器推出了多款嵌入式主控产品&#xff0c;除了最新发布的i.MX95xx系列核心板外&#xff0c;同为i.MX9系的i.MX93xx系列核心板也已上市多年并获得了众多客户的认可和选择。在长期的技术支持服务过程中&#xff0…

Windows应急响应一般思路(二)

进程排查 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础 无论是在Windows系统还是Linux系统中&#xff0c;主机在感染恶意程序后&#xff0c;恶意程序都会启动相应的进程&am…

FFmpeg03:多媒体文件处理基础

日志系统 #include <libavutil/log.h>av_log_set_level(AV_LOG_DEBUG)av_log(NULL, AV_LOG_INFO, “…%s\n”, op) 常用日志级别 AV_LOG_ERROR AV_LOG_WARNING AV_LOG_INFO Demo log.cpp #include <iostream> extern "C" { #include <libavutil/log.h…

【每天一个知识点】AIOps 与自动化管理

一、AIOps 的内涵AIOps&#xff08;Artificial Intelligence for IT Operations&#xff09;&#xff1a;指将人工智能、大数据分析和机器学习技术应用于 IT 运维管理中。主要目标是&#xff1a;利用智能算法对云平台、网络、应用和日志等海量运维数据进行实时分析&#xff0c;…

ios使用saveVideoToPhotosAlbum 保存视频失败提示 invalid video

ios使用saveVideoToPhotosAlbum 保存视频失败提示 invalid video 解决办法 iOS 上对保存到相册的视频存在某种格式和分辨率上的限制&#xff0c;建议先自查看下视频生成的参数&#xff0c;可以先试试苹果自带浏览器 safari 上能否播放该视频。 如果不能播放&#xff0c;证明 io…

Vue基础(③父子组件)

房子&#xff08;父组件&#xff09;包含窗户和门&#xff08;子组件&#xff09; 窗户和门&#xff08;子组件&#xff09;是房子&#xff08;父组件&#xff09;的一部分父组件<!-- 父组件&#xff1a;比如叫 Home.vue --> <template><div><h1>这是父…

AI领域的语义空间是什么?

写在前面&#xff1a;本文将从简单的二维空间来逐渐展开问题&#xff0c;带您理解语义空间。距离和体型&#xff1a;这里尝试用距离和体型这两个尺度来理解语义空间&#xff0c;先说的是低维情况&#xff0c;后面在尝试理解高维的情况。比如&#xff0c;在二维空间的x,y坐标系&…

排序---插入排序

基本思想对于插入排序而言&#xff0c;它的基本思想就是往已经排好序的序列里边插入数据。思想类似于玩扑克牌。接下来的排序都是基于下边的这个数组。int a[ ] { 5 , 3 , 9 , 6 , 2 , 4 , 7 , 1 , 8 };直接插入排序我们想要将这个数组排成升序&#xff0c;在最一开始&#xf…

Java性能优化实战(四):IO与网络优化的4个关键方向

IO与网络操作是Java应用性能的常见瓶颈&#xff0c;尤其在高并发场景下&#xff0c;低效的IO处理会导致响应缓慢、资源浪费等问题。本文将聚焦IO与网络优化的四个核心方向&#xff0c;通过真实案例、代码对比和性能数据&#xff0c;详解如何提升IO效率、减少网络传输开销&#…

对齐Wireshark和USRP捕获信号的波形

一、USRP信号 USRP捕获信号的波形如下&#xff1a; 放大后&#xff1a; 100ms 10ms 1ms 100us 10us 1us 二、波形分析 2.1 时间分辨率 采样率61.44MHz, 对应时间分辨率为1/61.44us0.01627us16.27ns。 这时间分辨率够用了&#xff0c;数据包长度为1到20us&#xff1a; 2.2 W…

2025年加密软件技术深度分析:从原理到企业级应用实践

一、加密技术基础与分类加密技术作为信息安全的核心基石&#xff0c;其基本原理是通过特定算法将明文数据转换为不可读的密文&#xff0c;只有持有正确密钥的授权用户才能解密还原。2025年主流的加密技术可分为三大类&#xff1a;‌对称加密‌&#xff1a;使用相同密钥进行加密…

打工人日报20250822

打工人日报20250822 对自己负责&#xff0c;可以是换一个角度看待自己不喜欢的工作&#xff0c;转换一个角度&#xff0c;从中找到自己感兴趣的点 真的非常不想计算声场的数据 啊啊啊啊啊 技术 STM32烧录问题 STM32 代码烧录失败&#xff1a;Error: Flash Download failed …

消费盲返模式:重构快消行业营销生态的破局之道与风险防控指南

一、模式爆发&#xff1a;快消行业的新增长引擎在流量成本攀升、用户留存困难的商业环境下&#xff0c;消费盲返模式正成为零售领域的一匹黑马。其核心逻辑在于通过"消费即投资"的机制设计&#xff0c;将每笔交易转化为后续100笔订单的激励源&#xff0c;形成独特的&…

STM32-FreeRTOS快速入门指南(上)

第一章 FreeRTOS系统配置 1. FreeRTOSConfig.h文件 针对 FreeRTOSConfig.h 文件&#xff0c;在 FreeRTOS 官方的在线文档中有详细的说明&#xff0c;网址为&#xff1a; https://www.freertos.org/a00110.html FreeRTOS 使用 FreeRTOSConfig.h 文件进行配置和裁剪。 FreeRTOSCo…

南溪智融双碳示范基地建筑设备管理系统 + 智能照明系统调试完成:筑牢 “绿色智能” 运营基石

南溪智融双碳示范基地作为聚焦 “双碳” 目标的标杆项目&#xff0c;其建筑设备管理系统与智能照明系统的调试完成&#xff0c;标志着基地在 “设备高效运维、能源精准管控、低碳场景落地” 方面迈出关键一步。两大系统深度契合示范基地 “以技术赋能双碳” 的核心定位&#xf…

c++的可扩展性方法

在C编码中&#xff0c;"方便扩展"通常指的是代码设计具有良好的**可维护性、可重用性和灵活性**&#xff0c;能够在不修改原有代码或仅少量修改的情况下&#xff0c;轻松添加新功能、支持新类型或适应新需求。以下是一些典型的、体现“方便扩展”思想的C编程案例&…

加速车辆开发 风丘道路载荷数据采集 (RLDA) 测试方案

一、背景 整车厂在汽车上市前&#xff0c;了解产品所能承受的载荷是非常重要的&#xff0c;因此需进行道路载荷数据采集&#xff08;RLDA&#xff09;测试。通过获得车辆在实际试验场或公路道路中行驶的载荷信息来为整车台架道路模拟试验提供目标信号输入&#xff0c;以及为用于…

大模型0基础开发入门与实践:第4章 “脑细胞”的模拟:神经网络与深度学习入门

第4章 “脑细胞”的模拟&#xff1a;神经网络与深度学习入门 1. 引言 在上一章&#xff0c;我们像一位侦探&#xff0c;学会了使用决策树这样的工具&#xff0c;从清晰的线索&#xff08;花瓣、花萼的尺寸&#xff09;中推理出确定的结论&#xff08;鸢尾花的种类&#xff09;。…