PDF文档转换:5分钟完成异步上传与结果下载
pdf-doc-convert-quickstart-3275 # PDF文档转换:5分钟完成异步上传与结果下载
> 接口:PDF文档转换 · 接入点 `3275-1` / `3275-2` · 付费(¥9.90起/12个月)· POST · JSON · 异步两步走
> 适用人群:新注册用户、初级开发者
> 阅读时间:约 6 分钟
> 最后实测核对:2026-09-07
---
## 核心要点
- 接口**不直接返回转换内容**,上传后先拿到 `task_id`,再轮询获取 `download_url`。
- 单文件上限 **100MB**;`type=md` 输出 Markdown,`type=docx` 输出 Word。
- `download_url` 和 `file_url` 实效 **7 天**,过期需重新提交或查历史记录(`3275-3`)。
---
## Why 这个接口
你有一份 PDF,想把内容转成 Markdown 丢进知识库做 RAG,或者转成 docx 给业务系统用。最土的做法是自己接 Tesseract OCR,精度差还难调;花钱买 SaaS OCR,按页计费贵且黑盒。
ShowAPI 的 PDF文档转换接口(apiCode=3275,万维易源自营)把这件事封装成 HTTP 调用:传文件、等任务完成、下载结果。返回的是标准 JSON,状态机清晰,代码量小。
---
## What 前置条件
1. 在 [ShowAPI 控制台](https://www.showapi.com/console#/myApp) 注册账号并获取 AppKey。
2. 购买资源包(专用资源包 ¥9.90/12个月起,或充值通用资源包直接使用)。
3. 准备一份不超过 100MB 的 PDF 文件(本地文件、可访问的 URL、或 base64 字符串,三选一)。
---
## How 完整流程(以 file_url 方式为例)
### 第 1 步:上传 PDF,获取 task_id
```bash
curl -X POST "https://route.showapi.com/3275-1?appKey=YOUR_APPKEY" \
-H "content-type: multipart/form-data" \
-F "file_url=https://example.com/sample.pdf" \
-F "type=md"
```
**响应示例:**
```json
{
"showapi_res_code": 0,
"showapi_res_body": {
"ret_code": 0,
"remark": "文件创建成功",
"state": "preparing",
"task_id": "54f9a8a59e8b",
"file_name": "sample.pdf"
}
}
```
关键判断:`ret_code == 0` 说明上传成功,`task_id` 是你之后轮询的依据。
---
### 第 2 步:轮询结果,直到 state 不再是 preparing / processing
```bash
# 每 2 秒轮询一次,直到 state 变为 success 或 failed
curl -X POST "https://route.showapi.com/3275-2?appKey=YOUR_APPKEY" \
-d "task_id=54f9a8a59e8b"
```
**成功时响应:**
```json
{
"showapi_res_code": 0,
"showapi_res_body": {
"ret_code": 0,
"remark": "成功",
"state": "success",
"download_url": "http://showapi-pub-shanghai.oss-cn-shanghai.aliyuncs.com/7day-delete/abc.md",
"file_url": "http://showapi-pub-shanghai.oss-cn-shanghai.aliyuncs.com/7day-delete/abc.md"
}
}
```
**失败时 state 为 `failed`**,查看 `remark` 字段了解原因(常见:文件格式不支持、超出 100MB 限制)。
---
### 第 3 步:下载结果文件
`download_url` 指向实际转换后的 `.md` 或 `.docx` 文件,下载后使用。
---
## Python 完整示例(含轮询逻辑)
```python
import time
import requests
APP_KEY = "YOUR_APPKEY"
PDF_URL = "https://example.com/sample.pdf"
BASE = "https://route.showapi.com"
# Step 1: 上传
resp = requests.post(
f"{BASE}/3275-1",
params={"appKey": APP_KEY},
data={"file_url": PDF_URL, "type": "md"},
timeout=10,
)
body = resp.json()["showapi_res_body"]
if body["ret_code"] != "0":
raise RuntimeError(f"上传失败: {body['remark']}")
task_id = body["task_id"]
print(f"task_id={task_id}, state={body['state']}")
# Step 2: 轮询
for _ in range(30): # 最多轮询 30 次(约 60 秒)
time.sleep(2)
r = requests.post(
f"{BASE}/3275-2",
params={"appKey": APP_KEY},
data={"task_id": task_id},
timeout=10,
)
body = r.json()["showapi_res_body"]
if body["state"] == "success":
print(f"转换成功!下载: {body['download_url']}")
break
if body["state"] == "failed":
raise RuntimeError(f"转换失败: {body['remark']}")
print(f" 进行中... state={body['state']}")
else:
raise TimeoutError("转换超时,请检查 PDF 大小或格式")
```
---
## Node.js 完整示例
```javascript
const axios = require("axios");
const APP_KEY = "YOUR_APPKEY";
const PDF_URL = "https://example.com/sample.pdf";
async function convertPdf() {
// Step 1: 上传
const uploadRes = await axios.post(
"https://route.showapi.com/3275-1",
null,
{
params: { appKey: APP_KEY },
data: new URLSearchParams({ file_url: PDF_URL, type: "md" }),
timeout: 10000,
}
);
const { task_id, state } = uploadRes.data.showapi_res_body;
console.log(`task_id=${task_id}, state=${state}`);
// Step 2: 轮询
for (let i = 0; i < 30; i++) {
await new Promise((r) => setTimeout(r, 2000));
const queryRes = await axios.post(
"https://route.showapi.com/3275-2",
null,
{
params: { appKey: APP_KEY },
data: new URLSearchParams({ task_id }),
timeout: 10000,
}
);
const { state: st, download_url, remark } = queryRes.data.showapi_res_body;
if (st === "success") {
console.log(`转换成功!下载: ${download_url}`);
return download_url;
}
if (st === "failed") throw new Error(`转换失败: ${remark}`);
console.log(` 进行中... state=${st}`);
}
throw new Error("转换超时");
}
convertPdf().catch(console.error);
```
---
## 关键注意事项
1. **三选一上传方式**:`file_byte`(本地文件字节)、`file_url`(可下载链接)、`file_base64`(base64 字符串),三者任选其一,不能同时传多个。
2. **type 参数**:`md` 输出 Markdown,`docx` 输出 Word,默认 `md`。
3. **超时设置**:接入点 1 的 read_timeout 为 10s,建议代码中设 `timeout=10`;接入点 2/3 为 5s。
4. **7 天时效**:`download_url` 和 `file_url` 有效期 7 天,建议在代码中及时下载并缓存本地。
5. **文件大小**:超过 100MB 会失败,大文件建议先分割再分批上传。
---
## FAQ
**Q1:上传后一直返回 state=preparing 不动怎么办?**
通常说明服务正在处理队列中,正常情况 processing 会在几秒内出现。如果超过 30 秒仍无变化,可能是 PDF 过大或格式特殊,建议先用小文件测试连通性。
**Q2:下载链接 7 天后过期了还能重新获取吗?**
可以。调用历史记录查询接口(`3275-3`)查看该 `task_id` 的 `download_url`,若仍在 7 天窗口内可重新下载;已过期则需重新提交转换任务。
**Q3:ret_code=-1 怎么排查?**
先看 `remark` 字段的描述信息,常见原因:AppKey 无效、文件格式不支持、文件无法访问(file_url 方式)、参数缺失。
**Q4:想批量转换几十个 PDF 怎么办?**
本接口不支持同步批量,需要对每个文件单独调用上传接口,建议加个并发控制(如 Python 的 `concurrent.futures`)避免限流。
**Q5:怎么知道转换后的文件有多少页?**
转换后的 Markdown/docx 文件内容里可统计页码,但接口本身不直接返回页数。计费是按实际页数计算的,账单中可查看。
---
## 下一步阅读
- [PDF文档转换返回字段全解:state 状态机与 task_id 生命周期](https://www.showapi.com/guides/pdf-doc-convert-state-machine-3275)
- [在知识库系统里集成PDF文档转换](https://www.showapi.com/guides/pdf-doc-convert-knowledge-base-3275)
- [PDF文档转换失败怎么处理:超时、重试与7天时效下载链接管理](https://www.showapi.com/guides/pdf-doc-convert-fail-retry-3275)
- [PDF转Markdown方案怎么选:自建 OCR、付费接口与 ShowAPI 三方对比](https://www.showapi.com/guides/pdf-doc-convert-compare-3275)
---
*本系列共 5 篇:查看[PDF文档转换指南总目录](https://www.showapi.com/guides/pdf-doc-convert-guides-3275)*