技术博客
精品长文一键写作:用 Python 提交第一个写作任务并取回成稿

精品长文一键写作:用 Python 提交第一个写作任务并取回成稿

作者: 万维易源
2026-09-15
精品长文一键写作Python示例快速接入AI长文生成
# 精品长文一键写作:用 Python 提交第一个写作任务并取回成稿 > 接口:精品长文一键写作(apiCode=3206)· 接入点:3206-1 提交写作任务 / 3206-3 查询文章详情 > 计费:计次收费(3206-1 为 300 厘/次,3206-3 为 0 厘/次)· 请求方式:POST/GET · 返回格式:JSON(3206-3 生成中为纯文本) > 适用人群:第一次接入的新用户、初级开发者 · 阅读时间:约 8 分钟 · **最后实测核对:2026-09-15** ## 核心要点 - 精品长文一键写作(apiCode=3206)是异步接口:`3206-1` 提交后只拿到 `task_id`,正文要再用 `3206-3` 轮询取回。 - `3206-1` 的 `topic` 是唯一必填参数,写清主题和要求即可,示例值就是「帮我写一篇关于DeepSeek的介绍」这种自然语言。 - 文章没写完时,`3206-3` 返回 **HTTP 450**,响应体形态随 `need_md` 变化:传 `1` 是一句纯文本,传 `2` 或不传是 `{"ret_code":-1,"task_status":"writing",…}` 的 JSON。**生成中 `ret_code` 是 -1**,只判断 `ret_code` 会把还在生成的任务当成失败。 - `need_md` 决定响应体形态:传 `2` 或不传拿到 JSON,传 `1` 拿到的直接就是 Markdown 原文。 ## 为什么值得用一次接口换一篇成稿 要自己从零写一篇结构化长文,得先找资料、再列提纲、再逐段写,中间还要反复调结构。这套流程里最耗时的部分不是写字,是前期检索和搭骨架。 精品长文一键写作把这两步合到一次调用里。你给一句主题,接口返回的是「摘要 + 关键词 + 章节大纲 + 完整正文」这样一份带层次的结果,拿到之后直接二次编辑或发布。它适合那些需要稳定、批量产出长文的场景:内容矩阵、专题页初稿、行业综述、产品文档的开头几版。 需要说清一点,**这个接口不返回全文**。提交任务时只回一个任务标识,正文要另外查询。下面按这个流程走一遍。 ## 接口速览 | 项目 | 说明 | |------|------| | 提交写作任务 | `https://route.showapi.com/3206-1` | | 查询文章详情 | `https://route.showapi.com/3206-3` | | 鉴权 | URL query 参数 `appKey` | | 请求方式 | POST / GET,文档给出的是 POST | | 返回格式 | JSON(`3206-3` 生成中时为纯文本,见下文) | | 3206-1 必填参数 | `topic`(写作要求) | | 3206-3 必填参数 | `task_id`(任务 id,具有唯一性) | | 超时(OpenAPI 声明) | 两个接入点读写超时均为 60s | | 并发量 | 2 次/秒 | ## 第一步:拿到 AppKey 登录后到 https://www.showapi.com/console#/myApp 复制 AppKey。下面代码里的 `YOUR_APPKEY` 就是它的位置。 ## 第二步:提交写作任务 `3206-1` 的 content-type 是 `multipart/form-data`,`topic` 必填,`reference_list`、`lang`、`file` 都可选。 **Python(requests)** ```python import requests APPKEY = "YOUR_APPKEY" BASE = "https://route.showapi.com" resp = requests.post( f"{BASE}/3206-1", params={"appKey": APPKEY}, data={ "topic": "帮我写一篇关于DeepSeek的介绍", # 必填:写作要求 "lang": "zh", # 可选:zh 中文 / en 英文 }, timeout=60, # OpenAPI 声明 3206-1 读写超时 60s ) resp.raise_for_status() body = resp.json()["showapi_res_body"] if body["ret_code"] != 0: raise RuntimeError(f"提交失败:{body['remark']}") task_id = body["task_id"] print("任务已提交:", task_id, "状态:", body["task_status"]) ``` **cURL** ```bash curl -X POST "https://route.showapi.com/3206-1?appKey=YOUR_APPKEY" \ -H "content-type: multipart/form-data" \ -d "topic=%E5%B8%AE%E6%88%91%E5%86%99%E4%B8%80%E7%AF%87%E5%85%B3%E4%BA%8EDeepSeek%E7%9A%84%E4%BB%8B%E7%BB%8D&lang=zh" ``` **Node.js(fetch)** ```javascript const APPKEY = "YOUR_APPKEY"; const BASE = "https://route.showapi.com"; const resp = await fetch(`${BASE}/3206-1?appKey=${APPKEY}`, { method: "POST", headers: { "content-type": "multipart/form-data" }, body: new URLSearchParams({ topic: "帮我写一篇关于DeepSeek的介绍", lang: "zh" }), signal: AbortSignal.timeout(60000), }); const body = (await resp.json()).showapi_res_body; if (body.ret_code !== 0) throw new Error(`提交失败:${body.remark}`); const taskId = body.task_id; ``` 提交成功后,实际拿到的返回长这样(2026-09-15 实测): ```json { "showapi_res_error": "", "showapi_res_id": "6aa8c4bbfb638c2f69edc8ba", "showapi_res_code": 0, "showapi_fee_num": 1, "showapi_res_body": { "topic": "写一篇介绍昆明气候特点的短文,300字左右", "task_status": "preparing", "remark": "文章正在生成中,请稍后!", "task_id": "1ef05f9fa412444aa77c99fae4db1358", "ret_code": 0 } } ``` 两点实测观察值得记一下。`remark` 实际返回的是「文章正在生成中,请稍后!」,文档示例里写的是「提交成功」,判断成败请认 `ret_code`,别拿 `remark` 做字符串比对。`showapi_fee_num` 为 1,表示这次调用计入一次计费。 ## 第三步:轮询取回正文 `3206-3` 是透传模式,它**不用 `showapi_res_body` 包一层**,`title` / `content` / `keywords` / `outline` 都是顶层字段。 文章还没写完时它返回 HTTP 450,响应体跟着 `need_md` 走:传 `2` 是 JSON(`ret_code` 为 `-1`、`task_status` 为 `writing`),传 `1` 是一句纯文本。所以轮询代码要先看状态码,再看状态字段。 ```python import time import requests def wait_for_article(task_id, appkey, base="https://route.showapi.com", interval=15, max_tries=60): """轮询文章详情,直到 task_status 变成 success。need_md=2 走 JSON 响应。""" for _ in range(max_tries): time.sleep(interval) r = requests.post( f"{base}/3206-3", params={"appKey": appkey}, data={"task_id": task_id, "need_md": "2"}, # need_md=2 返回 JSON timeout=60, ) if r.status_code != 200: # 生成中:HTTP 450。need_md=2 时是 JSON(ret_code=-1),need_md=1 时是纯文本 print("生成中:", r.text.strip()) continue detail = r.json() if detail.get("task_status") == "success": return detail print("当前状态:", detail.get("task_status")) raise TimeoutError("等待超时,可稍后用同一个 task_id 再查") detail = wait_for_article(task_id, APPKEY) print("标题:", detail["title"]) print("正文长度:", len(detail["content"])) print("章节数:", len(detail["outline"])) ``` ## need_md 传 1 还是 2 `need_md` 决定的是**整个响应体的形态**,不只是正文格式。这是最容易写错的一处。 | `need_md` | 响应体 | 客户端怎么解析 | |------|------|------| | `1` | 纯 Markdown 文本,以 `# 文章标题` 起头 | 直接读响应文本,**不要调 `json()`** | | `2` | JSON,正文在 `content` 字段 | `json()` 之后取字段 | | 不传 | 与传 `2` 相同,返回 JSON | 同上 | 2026-09-15 实测同一个 `task_id`:`need_md=1` 返回 11780 字节的 Markdown 原文,`need_md=2` 与不传都返回 12788 字节的 JSON。GET 方式同样可用,响应形态一致。 **任务未完成时也分两种形态。** 同样在 2026-09-15 实测:`need_md=1` 时拿到的是一行纯文本「文章正在生成中,请稍后!」;`need_md=2` 时拿到的是 JSON: ```json { "ret_code": -1, "task_status": "writing", "remark": "文章正在生成中,请稍后!" } ``` 这里的 `ret_code` 是 **-1**。如果取稿逻辑只判断 `ret_code == 0` 就当成失败,会把还在生成中的正常任务按失败处理。判断顺序必须是「先看 HTTP 状态码是不是 450,再看 `task_status`」。 想要 `title`、`keywords`、`outline`、`imgs` 这些结构化字段就用 `2`;只想把成稿整段拿走、自己再解析标题层级就用 `1`。在 `need_md=1` 上调用 `json()` 会直接抛解析异常。 生成完成后,`3206-3`(`need_md=2`)返回的结构如下,取自 2026-09-15 的真实返回,`content` 为节选: ```json { "ret_code": 0, "task_status": "success", "task_id": "26d32f71742b40c2b7a91504e438c060", "title": "Exploring the ShowAPI Open API Marketplace: A Comprehensive Guide", "topic": "Write a brief introduction to the ShowAPI open API marketplace", "remark": "文章生成完成", "imgs": [], "keywords": [ { "is_ai": true, "keyword": "ShowAPI" }, { "is_ai": true, "keyword": "开放接口" }, { "is_ai": true, "keyword": "API市场" }, { "is_ai": true, "keyword": "开发者平台" }, { "is_ai": true, "keyword": "云服务" } ], "outline": [ { "name": "1. Introduction to ShowAPI and Its Significance", "child_list": [ "1.1 Understanding the Concept of an Open API Marketplace", "1.2 The Evolution of API Markets in the Digital Era", "1.3 ShowAPI's Position in the Cloud Service Ecosystem" ] }, { "name": "2. Key Features and Capabilities of ShowAPI", "child_list": ["2.1 ……", "2.2 ……", "2.3 ……", "2.4 ……"] } ], "content": "> ### 摘要 \n> ShowAPI is a leading aggregated open API marketplace, ……" } ``` 这次实测里有三处值得记下的细节: - `keywords` 的 `is_ai` 全部为 `true`;正文是英文,关键词仍返回**中文**(`开放接口`、`API市场` 这类)。要英文关键词得自己在调用侧映射。 - `imgs` 在未生成配图时是空数组,配图要单独调 `3206-5`。 - `outline` 实测返回 2 个章节,而 `content` 里实际出现了 3 个 `##` 章节外加一个 `## References` 参考文献小节。做目录时以 `outline` 为准,但不要假设它覆盖正文的全部标题。 `content` 以 `> ### 摘要` 起头,这个「摘要」小标题保持中文,即使正文是英文。整段是 Markdown 原文,交给常见 Markdown 渲染器即可。 ## 计费与调用方式 `3206-1` 每次 300 厘,`3206-3` 每次 0 厘。调用成功才计费,失败不扣费。同一接口的费率同时用于通用资源包计费。专用资源包 ¥9.90 起,有效期一年,具体档位与其余接入点费率见 https://www.showapi.com/apiGateway/view/3206 的「产品价格」标签。 接口并发量为 2 次/秒。写批量提交时按这个上限做节流,第 6 篇[批量任务队列](https://www.showapi.com/guides/longform-writing-batch-queue-3206)给了具体做法。 ## FAQ **Q1:提交任务后多久能拿到正文?** 长文生成属于长耗时任务,耗时因内容而异。2026-09-15 实测两次:一次 12:17 提交的英文主题约 7 分钟内变为 `success`;另一次 12:08 提交的中文主题到当日 13:35(87 分钟)仍是 `writing`、`content_length` 一直为 0,始终没出稿。样本只有两次,无法据此判断这属于偶发还是常态。建议轮询间隔设在 15 秒以上,并给等待设一个按业务容忍度定的上限——超时后用 `3206-4` 清掉任务再重提。 **Q2:`3206-1` 返回成功,但 `3206-3` 报错怎么办?** 先看 HTTP 状态码。450 表示还在生成,等下一轮再查;如果 `task_status` 变成 `success` 之外的终态,用 `3206-2` 查询任务列表看 `remark` 与 `content_length`,再用 `3206-4` 删除失败任务。 **Q3:正文为什么带 `>` 和 `###`?** `3206-3` 返回的正文是 Markdown 原文,摘要用引用块包裹,章节标题用 `##` / `###`。交给 Markdown 渲染器即可;想要纯文本,自己做一次 Markdown 到文本的转换。 **Q4:`need_md` 传 1 还是 2?** 传 2(或不传)返回 JSON,正文在 `content` 字段;传 1 的响应体本身就是 Markdown 原文,不能再调 `json()`。需要 `title`、`keywords`、`outline` 这些字段就用 2。 **Q5:`remark` 写着「提交成功」,我可以拿它判断成功吗?** 不建议。实测提交成功时 `remark` 返回的是「文章正在生成中,请稍后!」,与文档示例不一致。判断成败统一看 `ret_code`,`3206-1` 和 `3206-2` 都是 0 成功、-1 失败。 **Q6:可以一次提交多篇吗?** `3206-1` 每次只接受一个 `topic`,没有批量参数。多篇要循环提交,注意 2 次/秒的并发限制。 ## 下一步阅读 - 状态流转与轮询节奏:[精品长文一键写作:任务写完了没有?看 task_status 三种状态](https://www.showapi.com/guides/longform-writing-task-status-3206) - 全部返回字段与 `ret_code`:[精品长文一键写作返回字段与 ret_code 说明](https://www.showapi.com/guides/longform-writing-response-fields-3206) - 引用链接、引用文件怎么传:[reference_list、file、lang 三个参数怎么传](https://www.showapi.com/guides/longform-writing-reference-params-3206) - **本系列共 9 篇**:查看[精品长文一键写作指南总目录](https://www.showapi.com/guides/longform-writing-guides-3206)