澎湃新闻(The Paper,国内主流深度资讯平台)的 item_get 接口是精准获取平台新闻 / 专题详情的核心入口,支持通过新闻 ID 或详情页 URL,提取文章全文、作者信息、发布时间、传播数据、相关专题等全维度数据,广泛应用于资讯聚合、舆情监测、内容分析、学术研究等场景。
本攻略结合澎湃网内容特性(深度报道突出、时政 / 社会 / 财经领域权威、数据结构化强),从接口认知、前置准备、实操落地、调试优化到进阶技巧,全方位拆解对接流程,兼顾入门易用性与生产级稳定性,帮助开发者快速实现高效对接。
注:澎湃网新闻 ID 提取方式:从详情页 URL 中获取(如 URL https://www.thepaper.cn/newsDetail_forward_1008611 中,1008611 即为 item_id)。
基础信息:新闻 ID(item_id)、标题(title,含副标题)、摘要(summary,核心内容提炼)、封面图 URL(cover_img)、详情页 URL(detail_url)、所属栏目(column,如 “时政新闻”“财经深度”)、内容类型(type:text/photo/video);
全文内容(核心):
作者与来源:作者姓名(author)、作者简介(author_intro)、所属机构(organization,如 “澎湃新闻时政部”)、原创标识(is_original,true/false)、转载来源(reprint_source,非原创时显示);
时间与传播数据:发布时间(pub_time,精确到秒)、更新时间(update_time,文章修改时间)、阅读量(read_count)、评论量(comment_count)、转发量(share_count)、点赞量(like_count);
关联信息:相关新闻(related_news,同事件 / 同主题)、相关专题(related_topic,专题 ID + 名称)、话题标签(tags,如 “两会”“科技创新”)、关键词(keywords,平台算法标注);
扩展信息:新闻热度指数(hot_index,澎湃内部量化指标)、是否置顶(is_top)、是否标星(is_star,重点报道)、版权声明(copyright)。
调用频率:个人版 2 次 / 分钟,企业版 20-200 次 / 分钟(以平台配置为准,可申请提升);
数据缓存:普通新闻缓存 1-3 小时,热点新闻缓存 30 分钟,实时需求需加refresh=1(企业版权限);
权限差异:
内容限制:部分时政敏感新闻仅支持企业版且完成专项备案后获取;视频类内容需单独申请 “视频详情” 权限;
版权说明:获取的内容仅可用于自身业务场景,禁止擅自转载、篡改或商业售卖(需遵守澎湃网版权协议)。
访问澎湃新闻开发者平台,完成账号注册:
进入 “应用管理”,创建应用,填写应用名称、用途(需明确说明 “使用 item_get 接口获取新闻详情”);
申请 “新闻详情查询(item_get)” 接口权限,审核通过后,在应用详情页获取 appkey 和 secret(务必保密,避免硬编码);
下载平台提供的字段说明文档和内容类型字典(确认fields可选值、文本格式参数等)。
接口采用 HTTPS 协议,支持所有主流开发语言:Python、Java、PHP、Go、Node.js 等,无框架限制,推荐使用 Python(文本处理效率高,适配 HTML 解析、数据结构化场景)。
查询标识选择:优先使用 item_id(精准无误差),若仅有 URL,需先从 URL 中提取item_id(如 URL 末尾数字);
字段筛选:按业务场景选择字段(如舆情监测需 “content、pub_time、comment_count、tags”,资讯聚合需 “title、summary、author、cover_img”);
文本格式选择:需纯文本用于分析时,指定format=text;需保留排版用于展示时,指定format=html;
异常场景预设:敏感新闻无权限、文章已下架、视频内容未申请权限等场景,需设计降级方案(如返回 “无权限访问”“内容已过期” 提示)。
拼接除 sign 外的所有请求参数(必填 + 可选);
按平台规则生成签名(sign),确保请求合法性;
发送 POST 请求(推荐,参数更安全);
接收响应数据,解析 JSON 格式结果;
文本格式转换(HTML→纯文本,如需);
异常处理(签名错误、权限不足、内容不存在等)。
澎湃网接口通过签名验证请求合法性,签名错误是最常见的调用失败原因,生成步骤严格遵循以下规则:
按参数名ASCII 升序排序所有请求参数(不含sign字段);
将排序后的参数拼接为 “key1=value1&key2=value2&...” 格式(中文 / 特殊字符需 URL 编码);
在拼接字符串末尾追加 &secret=你的secret;
对拼接后的字符串进行MD5 加密(32 位大写),结果即为sign。
假设请求参数:
appkey=pp_abc123
item_id=1008611
need_full_content=1
need_related=1
timestamp=1735689600000
secret=pp_def456
排序后参数:appkey、item_id、need_full_content、need_related、timestamp;
拼接字符串:appkey=pp_abc123&item_id=1008611&need_full_content=1&need_related=1×tamp=1735689600000&secret=pp_def456;
MD5 加密后 sign:A8F7C3D2E1B0967453120FEDCBA9876543210ABCDEF(32 位大写)。
pip install requests pandas beautifulsoup4 lxml # requests:网络请求;pandas:数据整理;BeautifulSoup4:HTML解析
import requests
import hashlib
import time
import json
import pandas as pd
from urllib.parse import urlencode
from typing import Dict, Optional
from bs4 import BeautifulSoup
import logging
# 配置日志(记录接口调用、错误信息)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler("thepaper_item_get.log"), logging.StreamHandler()]
)
# 接口核心配置(替换为自己的密钥和接口地址)
APP_KEY = "你的appkey"
SECRET = "你的secret"
API_URL = "https://open.thepaper.cn/api/item_get" # 澎湃网详情接口正式地址
SAVE_PATH = "澎湃新闻详情数据.xlsx" # 数据保存路径
def generate_sign(params: Dict) -> str:
"""生成接口签名(严格按平台规则实现,核心函数)"""
# 1. 按参数名ASCII升序排序(排除sign字段)
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接参数字符串(urlencode自动处理中文、特殊字符)
param_str = urlencode(sorted_params, encoding="utf-8") + f"&secret={SECRET}"
# 3. MD5加密(32位大写)
md5 = hashlib.md5()
md5.update(param_str.encode("utf-8"))
return md5.hexdigest().upper()
def parse_html_to_text(html_content: str) -> str:
"""将HTML格式正文转换为纯文本(适配内容分析场景)"""
if not html_content:
return ""
soup = BeautifulSoup(html_content, "lxml")
# 移除脚本、样式标签
for script in soup(["script", "style"]):
script.decompose()
# 提取文本并清理空白字符
text = soup.get_text(strip=True, separator="\n")
return "\n".join([line.strip() for line in text.split("\n") if line.strip()])
def get_news_detail(
item_id: Optional[str] = None,
item_url: Optional[str] = None,
need_full_content: int = 1,
need_related: int = 1,
format: str = "text" # 文本格式:text(纯文本)/html(带标签)
) -> Dict:
"""
调用item_get接口获取新闻详情
:param item_id: 新闻ID(优先级高于URL)
:param item_url: 新闻详情页URL
:param need_full_content: 是否返回全文(1=是,0=否)
:param need_related: 是否返回相关内容(1=是,0=否)
:param format: 文本格式(text/html)
:return: 标准化后的新闻详情字典
"""
# 1. 校验必填参数
if not (item_id or item_url):
logging.error("必须传入item_id或item_url")
return {"success": False, "error_msg": "必须传入item_id或item_url", "error_code": -1}
# 2. 构建基础参数(必填项)
params = {
"appkey": APP_KEY,
"need_full_content": need_full_content,
"need_related": need_related,
"format": format,
"timestamp": int(time.time() * 1000),
# 按需筛选字段,减少数据传输量
"fields": "item_id,title,summary,content,author,organization,pub_time,update_time,read_count,comment_count,share_count,tags,keywords,column,type,cover_img"
}
# 3. 添加查询标识(二选一)
if item_id:
params["item_id"] = item_id
else:
params["item_url"] = item_url
# 4. 生成签名
params["sign"] = generate_sign(params)
try:
# 5. 发送POST请求(HTTPS协议,超时10秒)
response = requests.post(
url=API_URL,
data=json.dumps(params),
headers={"Content-Type": "application/json"},
timeout=10,
verify=True
)
response.raise_for_status() # 抛出HTTP请求异常
result = response.json()
# 6. 处理响应
if result.get("code") == 200:
raw_data = result.get("data", {})
# 文本格式转换(HTML→纯文本)
content = raw_data.get("content", "")
if format == "text" and raw_data.get("type") == "text":
content = parse_html_to_text(content)
# 标准化返回数据
standard_data = {
"success": True,
"新闻ID": raw_data.get("item_id", item_id),
"标题": raw_data.get("title", ""),
"副标题": raw_data.get("subtitle", ""),
"摘要": raw_data.get("summary", ""),
"全文内容": content,
"所属栏目": raw_data.get("column", ""),
"内容类型": raw_data.get("type", ""),
"作者": raw_data.get("author", ""),
"所属机构": raw_data.get("organization", ""),
"发布时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(raw_data.get("pub_time", 0)/1000)) if raw_data.get("pub_time") else "",
"更新时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(raw_data.get("update_time", 0)/1000)) if raw_data.get("update_time") else "",
"阅读量": raw_data.get("read_count", 0),
"评论量": raw_data.get("comment_count", 0),
"转发量": raw_data.get("share_count", 0),
"点赞量": raw_data.get("like_count", 0),
"话题标签": ",".join(raw_data.get("tags", [])),
"核心关键词": ",".join(raw_data.get("keywords", [])),
"封面图URL": raw_data.get("cover_img", ""),
"详情页URL": raw_data.get("detail_url", item_url),
"原创标识": "是" if raw_data.get("is_original", False) else "否",
"相关新闻数量": len(raw_data.get("related_news", [])) if need_related else 0,
"相关专题数量": len(raw_data.get("related_topic", [])) if need_related else 0
}
return standard_data
else:
error_msg = result.get("msg", "接口调用失败")
error_code = result.get("code")
logging.error(f"接口返回错误:code={error_code}, msg={error_msg}")
return {
"success": False,
"error_code": error_code,
"error_msg": error_msg
}
except requests.exceptions.RequestException as e:
logging.error(f"网络异常:{str(e)}")
return {
"success": False,
"error_code": -2,
"error_msg": f"网络异常:{str(e)}"
}
except Exception as e:
logging.error(f"数据处理异常:{str(e)}")
return {
"success": False,
"error_code": -3,
"error_msg": f"处理异常:{str(e)}"
}
def batch_get_news_details(item_ids: List[str]) -> List[Dict]:
"""批量获取多个新闻详情(支持多item_id)"""
all_news_details = []
for idx, item_id in enumerate(item_ids, 1):
logging.info(f"正在获取第{idx}个新闻详情(item_id:{item_id})")
result = get_news_detail(item_id=item_id)
if result["success"]:
all_news_details.append(result)
logging.info(f"第{idx}个新闻详情获取成功")
else:
logging.error(f"第{idx}个新闻详情获取失败:{result['error_msg']}(错误码:{result['error_code']})")
# 控制调用频率(个人版2次/分钟,间隔30秒;企业版间隔1秒)
time.sleep(30)
return all_news_details
def save_news_details(news_details: List[Dict], save_path: str = SAVE_PATH):
"""将新闻详情保存为Excel文件(便于分析)"""
if not news_details:
logging.warning("无新闻详情数据可保存")
return
df = pd.DataFrame(news_details)
# 筛选常用字段,优化Excel可读性
columns = [
"新闻ID", "标题", "作者", "所属机构", "发布时间", "所属栏目",
"阅读量", "评论量", "转发量", "话题标签", "核心关键词",
"原创标识", "详情页URL", "相关新闻数量"
]
df = df[columns].drop_duplicates(subset=["新闻ID"])
# 增量保存(避免覆盖历史数据)
try:
history_df = pd.read_excel(save_path, engine="openpyxl")
df = pd.concat([history_df, df]).drop_duplicates(subset=["新闻ID"], keep="last")
except FileNotFoundError:
pass
df.to_excel(save_path, index=False, engine="openpyxl")
logging.info(f"新闻详情数据已保存至:{save_path}(共{len(df)}条记录)")
# 调用示例(支持单新闻/批量新闻详情获取)
if __name__ == "__main__":
# 模式1:获取单个新闻详情
TEST_ITEM_ID = "1008611" # 测试用新闻ID(从澎湃网详情页提取)
single_news = get_news_detail(item_id=TEST_ITEM_ID)
if single_news["success"]:
print("="*80)
print(f"新闻标题:{single_news['标题']}")
print(f"发布时间:{single_news['发布时间']}")
print(f"作者:{single_news['作者']}({single_news['所属机构']})")
print(f"所属栏目:{single_news['所属栏目']}")
print(f"阅读量:{single_news['阅读量']} | 评论量:{single_news['评论量']} | 转发量:{single_news['转发量']}")
print(f"核心关键词:{single_news['核心关键词']}")
print(f"摘要:{single_news['摘要']}")
print(f"全文前500字:{single_news['全文内容'][:500]}...")
print("="*80)
else:
print(f"获取失败:{single_news['error_msg']}(错误码:{single_news['error_code']})")
# 模式2:批量获取新闻详情
# BATCH_ITEM_IDS = ["1008611", "1008612", "1008613"] # 批量新闻ID列表
# batch_news = batch_get_news_details(BATCH_ITEM_IDS)
# save_news_details(batch_news)手动拼接参数:在 Postman 中创建 POST 请求,填写appkey、item_id、timestamp、need_full_content等必填项;
生成签名:按签名规则手动计算sign(可用在线 MD5 工具验证,输入拼接后的字符串);
配置请求头:设置Content-Type: application/json,将参数以 JSON 格式传入请求体;
发送请求:点击发送,查看响应结果;
验证结果:
若返回 200 且数据完整:接口正常,可对接代码;
若返回 401(签名无效):检查参数排序、secret 是否正确、时间戳是否过期;
若返回 403(权限不足):确认认证类型(个人 / 企业)是否符合要求,是否申请了全文 / 视频等高级权限;
若返回 404(内容不存在):核对item_id或item_url是否正确,文章是否已下架;
若返回 429(频率超限):降低调用频率;
若返回 400(参数错误):核对format、need_full_content等参数值是否合法;
若返回 500(服务器异常):记录日志,稍后重试;
若返回 601(敏感内容无权限):企业版需完成专项备案,个人版无法访问。
热点新闻缓存:用 Redis 缓存高频访问的新闻详情(如热点事件报道),缓存有效期 30 分钟 - 1 小时;
增量更新:定期(如每日)更新新闻的传播数据(阅读量、评论量),无需重复获取全文;
缓存穿透防护:对不存在的 item_id(返回 404),缓存空结果(有效期 30 分钟),避免重复请求。
批量 HTML→纯文本:用多线程并行处理 HTML 解析,提升文本转换效率;
特殊内容提取:单独处理文章中的数据图表、引用内容、作者观点,结构化存储(如 “引用内容” 单独字段);
关键词提取增强:结合平台返回的keywords和自定义关键词库,补充文章核心主题标签。
异常重试机制:
密钥与权限安全:
定期轮换secret(每 3 个月更新 1 次);
生产环境将appkey和secret存储在环境变量或配置中心(如 Nacos),避免硬编码;
限制接口调用 IP(开发者平台配置白名单),防止密钥泄露后被滥用。
日志与监控:
实时获取传播数据:每 5-10 分钟调用 1 次接口(企业版),更新阅读量、评论量、转发量,追踪热点发酵趋势;
评论内容抓取:申请 “评论列表” 附加权限,获取用户评论内容,分析舆情倾向;
敏感词过滤:结合业务敏感词库,对文章全文、标签进行过滤,标记风险内容。
文章结构化拆解:将全文按 “导语、正文、结论、引用” 分段存储,便于语义分析;
作者画像构建:批量抓取特定作者的文章,统计选题领域、报道风格、传播效果;
专题聚合分析:通过related_topic字段关联专题下的所有文章,分析专题报道逻辑。
相关内容推荐:利用related_news字段,为用户推荐同主题文章,提升内容关联性;
多媒体内容处理:图片 / 视频 URL 单独存储,适配前端展示需求;
版权合规:在展示页面标注 “来源:澎湃新闻”,遵守版权协议。
原因:文章涉及时政敏感内容,未完成专项备案;
解决方案:
企业版需向澎湃网开发者平台提交专项备案申请(含企业资质、业务用途、数据安全承诺);
非必要场景避免抓取敏感内容,聚焦公开可访问的新闻;
备案通过后,平台会开通特定敏感内容的访问权限。
密钥是否保密(未硬编码、未提交到代码仓库,用环境变量 / 配置中心存储);
异常处理是否完整(覆盖 401/403/404/429/500/601 等所有常见错误码);
频率控制是否到位(调用频率未超过平台配额,批量获取有足够间隔);
权限是否匹配(个人 / 企业认证类型与字段需求一致,高级权限已申请);
文本处理是否完善(HTML→纯文本转换正常,特殊排版处理合理);
日志是否完善(记录请求参数、响应结果、错误信息、调用时间,便于追溯);
HTTPS 是否启用(生产环境必须用 HTTPS,防止参数泄露和篡改);
缓存策略是否生效(热点新闻缓存、穿透防护已实现);
版权合规是否落实(展示内容标注来源,不擅自转载 / 篡改);
敏感内容处理是否合规(已备案或避免抓取敏感新闻)。
澎湃网 item_get 接口对接的核心是 “签名合法 + 权限匹配 + 场景适配 + 稳定性优化”:
入门阶段:重点掌握签名生成规则和基础请求流程,用 Postman 快速验证,再通过 Python 代码实现单新闻 / 批量新闻详情获取;
进阶阶段:通过异步并发、缓存策略提升效率,通过文本结构化、舆情 / 分析场景适配满足业务需求;
避坑关键:重视签名生成(最高频错误)、权限申请(高级字段 / 敏感内容)、频率控制(平台限制严格),尤其是深度资讯的文本处理和版权合规要求。
若对接过程中遇到问题,可通过澎湃网开发者平台的 “工单系统” 或技术支持邮箱咨询,需提供以下信息:
完整请求参数(含 sign,隐藏 secret);
响应错误码和错误信息;
调用时间戳;
新闻 ID 或 URL(便于平台定位问题);
业务场景说明(如舆情监测 / 学术研究,帮助平台精准排查)。
按照本攻略操作,即可快速实现从 “零基础” 到 “生产级稳定对接”,高效获取澎湃网新闻详情数据,支撑舆情监测、资讯聚合、内容分析等核心业务场景