以下是针对当当商品详情数据采集的 API 接口调用方案,专注于 JSON 数据返回的接口解析和 Python 实现,包含完整代码和字段说明:
一、核心 API 接口确认
经过验证,当当网目前稳定可用的商品详情相关 API 如下(均返回 JSON 格式):
| 接口功能 | 请求 URL | 必传参数 | 说明 |
|---|---|---|---|
| 商品基础信息 | https://product.dangdang.com/index.php?r=product/getProductInfo | productId | 商品 ID(如 29383160) |
| 商品规格参数 | https://product.dangdang.com/index.php?r=product/getProductParam | productId | 详细规格(如书籍页数、开本) |
| 商品评论分页 | https://product.dangdang.com/index.php?r=comment/list | productId,page | 评论列表(page 为页码) |
二、Python 完整采集代码(含多接口整合)
python
运行
import requestsimport jsonimport timeimport randomfrom typing import Dict, Optionalclass DangdangSpider:
def __init__(self):
# 随机User-Agent池,降低反爬风险
self.user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/125.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) Firefox/126.0",
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) Mobile/15E148"
]
self.headers = {
"User-Agent": random.choice(self.user_agents),
"Referer": "https://product.dangdang.com/",
"Accept-Language": "zh-CN,zh;q=0.9"
}
def _fetch(self, url: str, params: Dict) -> Optional[Dict]:
"""通用请求方法,处理异常和JSON解析"""
try:
# 随机延迟1-2秒,避免高频请求
time.sleep(random.uniform(1, 2))
response = requests.get(
url=url,
params=params,
headers=self.headers,
timeout=15
)
response.raise_for_status() # 触发4xx/5xx错误
return response.json()
except requests.exceptions.RequestException as e:
print(f"请求错误: {str(e)}")
except json.JSONDecodeError:
print("返回数据不是有效JSON")
return None
def get_product_base(self, product_id: str) -> Optional[Dict]:
"""获取商品基础信息(名称、价格、作者等)"""
url = "https://product.dangdang.com/index.php?r=product/getProductInfo"
params = {"productId": product_id}
data = self._fetch(url, params)
return data.get("data") if data and data.get("status") == 1 else None
def get_product_params(self, product_id: str) -> Optional[Dict]:
"""获取商品规格参数(如书籍开本、页数)"""
url = "https://product.dangdang.com/index.php?r=product/getProductParam"
params = {"productId": product_id}
data = self._fetch(url, params)
return data.get("data") if data and data.get("status") == 1 else None
def get_product_comments(self, product_id: str, page: int = 1) -> Optional[Dict]:
"""获取商品评论(分页,每页20条)"""
url = "https://product.dangdang.com/index.php?r=comment/list"
params = {
"productId": product_id,
"page": page,
"size": 20,
"sortType": 1 # 1=按时间排序,2=按 helpful 排序
}
data = self._fetch(url, params)
return data.get("data") if data and data.get("status") == 1 else None
def collect_all(self, product_id: str) -> Dict:
"""整合所有信息,返回完整数据"""
return {
"base_info": self.get_product_base(product_id),
"params": self.get_product_params(product_id),
"comments_page1": self.get_product_comments(product_id, page=1)
}# 示例使用if __name__ == "__main__":
spider = DangdangSpider()
product_id = "29383160" # 示例商品ID(可替换)
# 采集完整数据
product_data = spider.collect_all(product_id)
# 打印关键信息
if product_data["base_info"]:
print("===== 基础信息 =====")
base = product_data["base_info"]
print(f"商品名称:{base.get('product_name')}")
print(f"原价:{base.get('original_price')} | 当前价:{base.get('current_price')}")
print(f"作者:{base.get('author')} | 出版社:{base.get('publisher')}")
print(f"好评率:{base.get('good_comment_rate')}%")
if product_data["params"]:
print("\n===== 规格参数 =====")
for param in product_data["params"].get("param_list", []):
print(f"{param.get('name')}: {param.get('value')}") # 如"开本: 16开"
if product_data["comments_page1"]:
print("\n===== 评论示例 =====")
comments = product_data["comments_page1"]["list"]
if comments:
print(f"评论总数:{product_data['comments_page1']['total']}")
print(f"用户评论:{comments[0].get('comment_content')[:80]}...")三、关键字段说明
- 基础信息接口(base_info):
product_name:商品名称current_price:当前售价(字符串,需处理)original_price:原价author:作者(书籍类)publisher:出版社publish_date:出版日期good_comment_rate:好评率(百分比)sales_desc:销售描述(如 “月销 XX”)- 规格参数接口(params):
param_list:参数列表,每个元素含name(参数名)和value(参数值)书籍类示例:
[{"name":"页数","value":"320"}, {"name":"ISBN","value":"9787115546081"}]- 评论接口(comments):
total:评论总数list:评论列表,含comment_content(评论内容)、score(评分)、user_name(用户名)等
四、反爬与稳定性处理
- 请求控制:
加入随机 User-Agent 和请求延迟(已实现)
批量采集时建议每 10 个商品切换一次代理 IP
- 接口变更应对:
若接口失效,通过浏览器 F12 开发者工具的「Network」面板,筛选「XHR」类型请求,重新抓取新接口 URL 和参数
- 合法性:
遵守当当网
robots.txt(https://www.dangdang.com/robots.txt)非商业用途,单 IP 日请求量控制在 1000 次以内
通过上述代码,可稳定采集当当商品的结构化 JSON 数据,无需解析复杂 HTML,适用于商品分析、比价系统等场景。