Pro 和 Max 均支持通过 API 导出数据,方便用户接入其他系统。
- 服务地址:
http://localhost:5001 - 鉴权:无需 token 或额外 headers
- 示例语言:Python +
requests - 超时:示例中为 10~120s,可按需调整
- 说明:导出类接口会在运行 wcplusPro 的本机生成文件;读取类接口返回 JSON,用户可在自己的 Python 脚本中保存为 CSV、TXT 或 Markdown。
环境准备
pip install requests
import csv
import json
from pathlib import Path
import requests
BASE_URL = "http://localhost:5001"
接口总览
| # | 场景 | Method & Path | 关键入参 | 典型结果 |
|---|---|---|---|---|
| 1 | 导出公众号清单 | GET /api/gzh/list | offset, num, sort, direction | Gzhs[], Total, Articles |
| 2 | 导出某个公众号文章清单 | GET /api/report/gzh_articles | biz, offset, num, sort, direction | Articles[], Total, Gzh |
| 3 | 导出单篇文章内容 | GET /api/article/content | nickname, id | Content |
| 4 | 批量导出公众号 TXT 文本 | GET /api/article/export_text | biz, nickname, only_main, need_img, open_dir | 导出数量 |
| 5 | 批量导出公众号 CSV/XLSX | GET /api/gzh/export_csv | biz, nickname, open_dir | 导出行数 |
| 6 | 导出全库文章 XLSX | POST /api/article/all_articles/export_xlsx | range_mode, fields 等 | XLSX 文件下载 |
1. 导出公众号清单
GET /api/gzh/list
用途:分页读取已导入的公众号清单,可保存为 CSV,用于后续批量导出文章列表、正文或统计数据。
参数(Query):
| 名称 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
offset | int | 否 | 0 | 分页偏移 |
num | int | 是 | - | 每页数量 |
sort | str | 否 | updated_at | 排序字段,可用 nickname、created_at、updated_at、total_article_num、main_article_num、reading_data_article_num、local_article_num |
direction | str | 否 | desc | asc 或 desc |
返回要点:Gzhs 为公众号列表;常用字段包括 Biz、Nickname、Img、Status、TotalArticleNum 等;Total 为公众号总数,Articles 为文章总数。
示例:分页读取全部公众号并保存为 CSV。
import csv
import requests
BASE_URL = "http://localhost:5001"
def fetch_all_gzhs(page_size=100):
offset = 0
rows = []
while True:
resp = requests.get(
f"{BASE_URL}/api/gzh/list",
params={
"offset": offset,
"num": page_size,
"sort": "updated_at",
"direction": "desc",
},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
batch = data.get("Gzhs", [])
rows.extend(batch)
if offset + len(batch) >= data.get("Total", 0) or not batch:
break
offset += len(batch)
return rows
gzhs = fetch_all_gzhs()
with open("gzh_list.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=["Biz", "Nickname", "Status", "TotalArticleNum"])
writer.writeheader()
for gzh in gzhs:
writer.writerow({
"Biz": gzh.get("Biz", ""),
"Nickname": gzh.get("Nickname", ""),
"Status": gzh.get("Status", ""),
"TotalArticleNum": gzh.get("TotalArticleNum", ""),
})
2. 导出某个公众号文章清单
GET /api/report/gzh_articles
用途:读取某个公众号的文章列表,适合导出标题、发布时间、阅读量、点赞、链接等结构化数据。
参数(Query):
| 名称 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
biz | str | 是 | - | 公众号 Biz |
offset | int | 否 | 0 | 分页偏移 |
num | int | 否 | 20 | 每页数量 |
sort | str | 否 | p_date | 排序字段,常用 p_date、read_num、like_num、comment_num、share_num、mov |
direction | str | 否 | desc | asc 或 desc |
返回要点:Articles[] 为文章列表;常用字段包括 ID、Title、Author、PDate、ReadNum、LikeNum、CommentNum、Mov、ContentURL、SourceURL 等;Total 为该公众号文章总数。
示例:导出某个公众号全部文章清单为 CSV。
import csv
import time
import requests
BASE_URL = "http://localhost:5001"
def fetch_all_articles(biz, page_size=100):
offset = 0
rows = []
while True:
resp = requests.get(
f"{BASE_URL}/api/report/gzh_articles",
params={
"biz": biz,
"offset": offset,
"num": page_size,
"sort": "p_date",
"direction": "desc",
},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
batch = data.get("Articles", [])
rows.extend(batch)
if offset + len(batch) >= data.get("Total", 0) or not batch:
break
offset += len(batch)
return rows
biz = "gh_xxxxx"
articles = fetch_all_articles(biz)
with open("article_list.csv", "w", newline="", encoding="utf-8-sig") as f:
fieldnames = [
"ID", "Title", "Author", "PDateText", "ReadNum", "LikeNum",
"CommentNum", "Mov", "ContentURL", "SourceURL",
]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for a in articles:
p_date = int(a.get("PDate") or 0)
writer.writerow({
"ID": a.get("ID", ""),
"Title": a.get("Title", ""),
"Author": a.get("Author", ""),
"PDateText": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(p_date)) if p_date else "",
"ReadNum": a.get("ReadNum", ""),
"LikeNum": a.get("LikeNum", ""),
"CommentNum": a.get("CommentNum", ""),
"Mov": a.get("Mov", ""),
"ContentURL": a.get("ContentURL", ""),
"SourceURL": a.get("SourceURL", ""),
})
3. 导出单篇文章内容
GET /api/article/content
用途:读取单篇文章正文。返回的 Content 可直接保存为 Markdown,也可以保存为 TXT。
参数(Query):
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
nickname | str | 是 | 公众号昵称 |
id | str | 是 | 文章 ID |
返回要点:Content 字段包含文章标题、作者、阅读点赞等信息和正文内容。
示例:保存为 Markdown 文件。
from pathlib import Path
import requests
BASE_URL = "http://localhost:5001"
def safe_name(value, limit=80):
value = "".join("_" if ch in r'\/:*?"<>|' else ch for ch in value)
return value[:limit] or "article"
nickname = "示例公众号"
article_id = "000001234567890"
resp = requests.get(
f"{BASE_URL}/api/article/content",
params={"nickname": nickname, "id": article_id},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
out_dir = Path("article_md")
out_dir.mkdir(exist_ok=True)
Path(out_dir / f"{safe_name(article_id)}.md").write_text(
data.get("Content", ""),
encoding="utf-8",
)
示例:保存为 TXT 文件。
from pathlib import Path
import requests
BASE_URL = "http://localhost:5001"
nickname = "示例公众号"
article_id = "000001234567890"
resp = requests.get(
f"{BASE_URL}/api/article/content",
params={"nickname": nickname, "id": article_id},
timeout=10,
)
resp.raise_for_status()
content = resp.json().get("Content", "")
Path("article_txt").mkdir(exist_ok=True)
Path(f"article_txt/{article_id}.txt").write_text(content, encoding="utf-8")
4. 批量导出某个公众号的 TXT 文本
GET /api/article/export_text
用途:在运行 wcplusPro 的本机批量导出某个公众号的文章文本。
参数(Query):
| 名称 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
biz | str | 是 | - | 公众号 Biz |
nickname | str | 是 | - | 公众号昵称 |
only_main | bool | 否 | false | 是否只导出头条文章 |
need_img | bool | 否 | false | 是否保留图片 |
open_dir | bool | 否 | true | 导出完成后是否自动打开目录 |
返回要点:返回导出成功数量。
示例:
import requests
BASE_URL = "http://localhost:5001"
resp = requests.get(
f"{BASE_URL}/api/article/export_text",
params={
"biz": "gh_xxxxx",
"nickname": "示例公众号",
"only_main": False,
"need_img": False,
"open_dir": False,
},
timeout=60,
)
resp.raise_for_status()
success_num = resp.json()
print("导出数量:", success_num)
5. 批量导出某个公众号的 CSV/XLSX
GET /api/gzh/export_csv
用途:在运行 wcplusPro 的本机导出某个公众号的文章数据。该接口适合导出公众号级别的文章表格数据。
参数(Query):
| 名称 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
biz | str | 是 | - | 公众号 Biz |
nickname | str | 是 | - | 公众号昵称 |
open_dir | bool | 否 | true | 导出完成后是否自动打开目录 |
返回要点:返回导出行数。导出结果会在运行 wcplusPro 的本机生成 CSV/XLSX 文件。
示例:
import requests
BASE_URL = "http://localhost:5001"
resp = requests.get(
f"{BASE_URL}/api/gzh/export_csv",
params={
"biz": "gh_xxxxx",
"nickname": "示例公众号",
"open_dir": False,
},
timeout=60,
)
resp.raise_for_status()
row_count = resp.json()
print("导出行数:", row_count)
6. 导出全库文章 XLSX
POST /api/article/all_articles/export_xlsx
用途:按范围和字段导出全库文章为 XLSX。接口直接返回文件内容,适合用 Python 下载保存。
请求体(JSON):
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
sort | str | 否 | p_date | 排序字段,常用 p_date、read_num、like_num、comment_num、share_num、mov、gzh_nickname |
direction | str | 否 | desc | asc 或 desc |
only_headline | bool | 否 | false | 是否只导出头条 |
range_mode | str | 是 | - | recent、date 或 all |
recent_num | int | 否 | 100 | range_mode=recent 时导出最近 N 篇 |
start_p_date | int | 条件必填 | - | range_mode=date 时使用,Unix 秒 |
end_p_date | int | 条件必填 | - | range_mode=date 时使用,Unix 秒 |
fields | list[str] | 是 | - | 导出字段 |
可选字段:
| 字段值 | 表头 |
|---|---|
gzh_nickname | 公众号 |
title | 标题 |
author | 作者 |
p_date_text | 发文时间 |
post_location | 发文地区 |
read_num | 阅读量 |
old_like_num | 点赞 |
like_num | 在看 |
reward_num | 赞赏 |
share_num | 转发 |
comment_num | 评论 |
copyright_stat | 版权 |
original | 原创性 |
mov | 位置 |
digest | 摘要 |
html_file | 原文文件 |
content_url | 链接 |
source_url | 原文链接 |
content | 文章内容 |
示例:导出最近 100 篇文章 XLSX。
from pathlib import Path
import requests
BASE_URL = "http://localhost:5001"
payload = {
"sort": "p_date",
"direction": "desc",
"only_headline": False,
"range_mode": "recent",
"recent_num": 100,
"fields": [
"gzh_nickname", "title", "author", "p_date_text", "post_location",
"read_num", "old_like_num", "like_num", "reward_num", "share_num",
"comment_num", "copyright_stat", "original", "mov", "digest",
"content_url", "source_url",
],
}
resp = requests.post(
f"{BASE_URL}/api/article/all_articles/export_xlsx",
json=payload,
timeout=120,
)
resp.raise_for_status()
Path("all_articles_recent.xlsx").write_bytes(resp.content)
示例:按时间段导出,并包含文章内容字段。
from pathlib import Path
import requests
BASE_URL = "http://localhost:5001"
payload = {
"sort": "p_date",
"direction": "desc",
"only_headline": True,
"range_mode": "date",
"start_p_date": 1704067200,
"end_p_date": 1735689599,
"fields": ["gzh_nickname", "title", "p_date_text", "read_num", "content"],
}
resp = requests.post(
f"{BASE_URL}/api/article/all_articles/export_xlsx",
json=payload,
timeout=120,
)
resp.raise_for_status()
Path("all_articles_2024_headline.xlsx").write_bytes(resp.content)
拓展案例1. 从公众号清单批量导出文章列表
用途:先读取公众号清单,再逐个读取文章清单,保存为一个总 CSV。
import csv
import time
import requests
BASE_URL = "http://localhost:5001"
def get_json(path, params=None, timeout=20):
resp = requests.get(f"{BASE_URL}{path}", params=params or {}, timeout=timeout)
resp.raise_for_status()
return resp.json()
gzhs = get_json(
"/api/gzh/list",
{"offset": 0, "num": 1000, "sort": "updated_at", "direction": "desc"},
).get("Gzhs", [])
with open("all_gzh_articles.csv", "w", newline="", encoding="utf-8-sig") as f:
fieldnames = [
"Biz", "Nickname", "ArticleID", "Title", "PDateText",
"ReadNum", "LikeNum", "CommentNum", "Mov", "ContentURL",
]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for gzh in gzhs:
biz = gzh.get("Biz")
nickname = gzh.get("Nickname", "")
if not biz:
continue
offset = 0
while True:
data = get_json(
"/api/report/gzh_articles",
{
"biz": biz,
"offset": offset,
"num": 100,
"sort": "p_date",
"direction": "desc",
},
)
articles = data.get("Articles", [])
for a in articles:
p_date = int(a.get("PDate") or 0)
writer.writerow({
"Biz": biz,
"Nickname": nickname,
"ArticleID": a.get("ID", ""),
"Title": a.get("Title", ""),
"PDateText": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(p_date)) if p_date else "",
"ReadNum": a.get("ReadNum", ""),
"LikeNum": a.get("LikeNum", ""),
"CommentNum": a.get("CommentNum", ""),
"Mov": a.get("Mov", ""),
"ContentURL": a.get("ContentURL", ""),
})
if offset + len(articles) >= data.get("Total", 0) or not articles:
break
offset += len(articles)
拓展案例2. 批量导出文章正文为 Markdown/TXT
用途:先读取某个公众号的文章清单,再逐篇调用正文接口,在脚本运行目录保存为 Markdown 或 TXT。
from pathlib import Path
import requests
BASE_URL = "http://localhost:5001"
def safe_name(value, limit=80):
value = "".join("_" if ch in r'\/:*?"<>|' else ch for ch in value)
return value[:limit] or "article"
def get_json(path, params=None, timeout=20):
resp = requests.get(f"{BASE_URL}{path}", params=params or {}, timeout=timeout)
resp.raise_for_status()
return resp.json()
biz = "gh_xxxxx"
nickname = "示例公众号"
out_format = "md" # 可改为 "txt"
articles = get_json(
"/api/report/gzh_articles",
{"biz": biz, "offset": 0, "num": 1000, "sort": "p_date", "direction": "desc"},
).get("Articles", [])
out_dir = Path(f"{safe_name(nickname)}_{out_format}")
out_dir.mkdir(exist_ok=True)
for a in articles:
article_id = a.get("ID")
if not article_id:
continue
data = get_json(
"/api/article/content",
{"nickname": nickname, "id": article_id},
timeout=20,
)
filename = safe_name(a.get("Title") or article_id)
Path(out_dir / f"{filename}.{out_format}").write_text(
data.get("Content", ""),
encoding="utf-8",
)
常见错误与排查
- 请求失败并返回
400:检查必填参数是否缺失,例如biz、nickname、id、num、fields。 - 导出数量为 0:检查该公众号是否已有文章数据,或正文是否已采集完成。
- 正文为空:先确认文章列表中存在对应
ID,并确认该文章正文已采集。 - Python 超时:将
timeout调大,尤其是批量导出和全库 XLSX 导出。 - 文件不在 Python 脚本目录:服务器导出类接口会在运行 wcplusPro 的本机生成文件;Python 保存类示例则保存在 Python 脚本当前目录。
- 自动打开目录不符合批量脚本需求:导出接口中设置
open_dir=False。