0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

孔夫子旧书网 API 实战:古籍与二手书数据获取及接口调用方案

邓林 来源:jf_63013664 作者:jf_63013664 2025-08-26 09:35 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

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

wKgZO2itD1aAa3KRAAtexaV4-PQ432.pngpoYBAGDYdXCAWkKMAAAAK8RNs4s030.pngwKgZO2idiI-AWRVrAAtexaV4-PQ400.png


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

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

接口特点:

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

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


二、认证机制与核心参数

1. 认证方式

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

在孔夫子开发者平台注册并申请应用,获取 API Key
在所有请求的 Header 中携带X-API-Key参数
商业用户可申请更高权限的 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_key
self.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_proxy
self.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 session

def _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 None

def 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"] = category
if year_min is not None:
params["year_min"] = year_min
if year_max is not None:
params["year_max"] = year_max
if condition is not None:
params["condition"] = condition
if price_min is not None:
params["price_min"] = price_min
if price_max is not None:
params["price_max"] = price_max
if 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 = None
if 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 filters

def 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 = 1
total_pages = 1

while 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 Key
API_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 技术提取关键评价
出版年代可能存在模糊表述(如 "民国年间"),需特殊处理

六、功能扩展方向

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


审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    9444

    浏览量

    156136
  • API
    API
    +关注

    关注

    2

    文章

    2147

    浏览量

    66226
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    ​​​​​​​闲鱼平台根据商品ID获取商品详情的API接口实现

      引言在二手交易平台的数据分析、价格监控或商品信息聚合等应用场景中,通过商品ID(item_id)精准获取商品的详细信息是基础且关键的一步。闲鱼作为国内领先的C2C二手交易平台,提供
    的头像 发表于 11-19 15:27 406次阅读
    ​​​​​​​闲鱼平台根据商品ID<b class='flag-5'>获取</b>商品详情的<b class='flag-5'>API</b><b class='flag-5'>接口</b>实现

    爱回收平台根据关键词获取品牌ID的API接口详解

    ​  爱回收平台(Aihuishou)是一个专注于二手电子产品回收的服务平台,提供了丰富的API接口以支持开发者集成其功能。其中,“根据关键词获取品牌ID”的
    的头像 发表于 11-19 14:42 173次阅读
    爱回收平台根据关键词<b class='flag-5'>获取</b>品牌ID的<b class='flag-5'>API</b><b class='flag-5'>接口</b>详解

    小红获取笔记正文和点赞数的API接口

    ​  小红(RED)是一个流行的社交平台,用户分享笔记(类似博客文章)。开发者和数据分析师常需要通过API接口获取笔记正文和点赞数,用于内
    的头像 发表于 11-18 16:27 594次阅读
    小红<b class='flag-5'>书</b><b class='flag-5'>获取</b>笔记正文和点赞数的<b class='flag-5'>API</b><b class='flag-5'>接口</b>

    京东平台获取商品详情原数据API接口技术解析

    ​  在电商系统开发、价格监控、竞品分析等场景中,获取商品的原始详情数据是基础且关键的一环。京东作为国内领先的电商平台,提供了相应的API接口供开发者
    的头像 发表于 11-13 14:35 279次阅读
    京东平台<b class='flag-5'>获取</b>商品详情原<b class='flag-5'>数据</b><b class='flag-5'>API</b><b class='flag-5'>接口</b>技术解析

    调用拼多多开放平台 API 获取店铺列表

    ​  在电商平台生态开发中,获取店铺信息是常见的需求。本文将介绍如何通过拼多多开放平台的 API 接口获取店铺列表,包括接口概述、
    的头像 发表于 11-10 15:30 195次阅读
    <b class='flag-5'>调用</b>拼多多开放平台 <b class='flag-5'>API</b> <b class='flag-5'>获取</b>店铺列表

    淘宝平台获取商品视频 API 接口技术指南

    ​  本文将详细介绍如何通过淘宝开放平台的 API 接口获取商品的视频信息。淘宝作为大型电商平台,提供了丰富的 API 服务,允许开发者访问商品数据
    的头像 发表于 11-07 14:01 263次阅读
    淘宝平台<b class='flag-5'>获取</b>商品视频 <b class='flag-5'>API</b> <b class='flag-5'>接口</b>技术指南

    淘宝商品详情API接口技术解析与实战应用

    随着电商行业的快速发展,数据驱动的决策模式已成为企业核心竞争力的重要组成部分。淘宝作为国内领先的电商平台,其开放平台提供的商品详情API接口为开发者提供了获取商品全维度
    的头像 发表于 11-04 09:50 124次阅读

    教你如何使用API接口获取数据

    一、了解API API(Application Programming Interface)即应用程序编程接口,是一种使不同的应用程序能共享数据和功能的软件工具。
    的头像 发表于 11-03 09:14 330次阅读

    闲鱼平台获取商品详情API接口

    ​  闲鱼是阿里巴巴旗下的二手交易平台,为开发者提供了丰富的API接口,方便获取商品数据。本文将详细介绍如何通过
    的头像 发表于 10-27 16:01 597次阅读
    闲鱼平台<b class='flag-5'>获取</b>商品详情<b class='flag-5'>API</b><b class='flag-5'>接口</b>

    API接口使用全指南:从基础调用实战技巧

    一、API接口的基本认知 API接口本质上是一组预先定义的规则,规定了不同系统之间如何传递数据。常见的A
    的头像 发表于 10-08 09:25 393次阅读

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

    本文详解孔夫子旧书古籍数据接口实战
    的头像 发表于 09-23 13:59 343次阅读

    亚马逊 MWS API 实战:商品详情精准获取与跨境电商数据整合方案

    深入拆解API调用全流程,提供签名工具类、多站点客户端等可复用代码。针对跨境业务场景,文章还给出数据整合工具实现方案,支持缓存、批量处理等功能。最后通过
    的头像 发表于 09-22 10:05 406次阅读
    亚马逊 MWS <b class='flag-5'>API</b> <b class='flag-5'>实战</b>:商品详情精准<b class='flag-5'>获取</b>与跨境电商<b class='flag-5'>数据</b>整合<b class='flag-5'>方案</b>

    产品评论获取API接口

      在当今电商和数据分析领域,产品评论是宝贵的用户反馈来源。手动收集评论耗时且易出错,而通过API接口自动化获取评论,能显著提升效率。本文将逐步介绍如何利用
    的头像 发表于 07-25 14:26 323次阅读
    产品评论<b class='flag-5'>获取</b><b class='flag-5'>API</b><b class='flag-5'>接口</b>

    产品列表获取API接口详解

    ​ 在现代软件开发中,API(应用程序编程接口)是获取产品列表的核心工具,它允许开发者从远程服务器高效地检索数据。本文将逐步介绍如何设计和使用产品列表
    的头像 发表于 07-24 14:29 466次阅读
    产品列表<b class='flag-5'>获取</b><b class='flag-5'>API</b><b class='flag-5'>接口</b>详解

    小红电商 API 接口,种草效果评估实用秘籍!

    小红电商 API 接口,高效评估种草效果,并提供实用秘籍,助你轻松优化策略。文章结构清晰,从基础概念到实战应用,确保你学以致用。 一、小红
    的头像 发表于 07-07 14:27 602次阅读
    小红<b class='flag-5'>书</b>电商 <b class='flag-5'>API</b> <b class='flag-5'>接口</b>,种草效果评估实用秘籍!