技术博客
PDF文档转换失败怎么处理:超时、重试与7天时效下载链接管理

PDF文档转换失败怎么处理:超时、重试与7天时效下载链接管理

作者: 万维易源
2026-09-07
pdf-doc-convert-fail-retry-3275
# PDF文档转换失败怎么处理:超时、重试与7天时效下载链接管理 > 接口:PDF文档转换 · 接入点 `3275-1` / `3275-2` / `3275-3` · 付费 · POST/GET · JSON > 适用人群:已接入用户、运维工程师 > 阅读时间:约 5 分钟 > 最后实测核对:2026-09-07 --- ## 核心要点 - 常见失败原因:文件格式不支持、超过 100MB、网络超时、AppKey 余额不足、task_id 无效。 - 重试策略:指数退避(间隔 2s → 4s → 8s),最多重试 3 次,避免雪崩。 - download_url 7 天时效必须在代码层管理,不能依赖外部链接长期有效。 --- ## 失败类型与排查 ### 1. 上传阶段失败(3275-1 返回 ret_code=-1) **常见原因:** | 原因 | 排查方法 | |------|---------| | AppKey 无效或余额不足 | 登录控制台查看账户状态和资源包用量 | | 文件格式不是 PDF | 检查文件后缀和 MIME type,用 `file` 命令或浏览器确认 | | 文件超过 100MB | 打印文件大小,必要时先压缩或拆分 | | file_url 无法访问 | 确认 URL 可公开访问(无鉴权、无 403),用浏览器打开测试 | | base64 编码错误 | 检查 base64 字符串是否完整、有无换行符干扰 | --- ### 2. 轮询阶段失败(3275-2 返回 state=failed) **常见原因:** | 原因 | 排查方法 | |------|---------| | PDF 内容无法解析(加密、损坏) | 尝试用本地 PDF 阅读器打开,确认文件完整 | | 纯图片 PDF(无文字层) | 接口对扫描版 PDF 不支持有效转换,`remark` 会提示 | | 服务器端解析超时 | 大文件(>50页)可能需要较长时间,适当延长轮询上限 | | task_id 已过期或被清理 | 调用 3275-3 查询历史记录,确认 task_id 是否存在 | --- ### 3. 下载阶段失败 **常见原因:** | 原因 | 排查方法 | |------|---------| | download_url 已过期(超过 7 天) | 查 3275-3 历史记录,若仍在窗口内重新获取链接 | | OSS 链接临时不可达 | 等几分钟重试下载,OSS 偶发抖动 | | 下载后文件损坏 | 检查文件头,确认是有效 Markdown 或 docx | --- ## 重试策略:指数退避实现 ```python import time import requests def poll_with_retry(task_id: str, app_key: str, max_retries: int = 3, base_delay: float = 2.0): """ 带指数退避的轮询,处理网络抖动导致的偶发失败 """ for attempt in range(max_retries): try: resp = requests.post( "https://route.showapi.com/3275-2", params={"appKey": app_key}, data={"task_id": task_id}, timeout=10, ) body = resp.json()["showapi_res_body"] if body["state"] == "success": return body["download_url"] if body["state"] == "failed": return None # 失败不重试,由调用方决定重新上传 # preparing / processing:继续轮询 return body["state"] except (requests.Timeout, requests.ConnectionError) as e: if attempt < max_retries - 1: delay = base_delay * (2 ** attempt) print(f"网络异常,{delay}s 后重试...") time.sleep(delay) else: raise RuntimeError(f"轮询失败,已重试 {max_retries} 次") from e return None ``` 关键点: - 网络错误(超时、连接断开)才重试,业务失败(state=failed)不重试。 - 指数退避避免密集请求触发限流。 - max_retries=3、base_delay=2 是经验值,可根据实际调整。 --- ## 7 天时效下载链接的管理策略 这是最容易踩的坑:把 download_url 存进数据库当永久链接,7 天后调用发现 404。 **正确做法:转换完成后立即下载,存储到自有存储。** ```python import requests from pathlib import Path def fetch_and_store(download_url: str, store_dir: Path, filename: str): """下载转换结果并存储到自有位置""" store_dir.mkdir(parents=True, exist_ok=True) local_path = store_dir / filename resp = requests.get(download_url, timeout=30) resp.raise_for_status() local_path.write_bytes(resp.content) return str(local_path) ``` **进阶:建立定期刷新机制** 如果业务需要长期保留转换结果,可以写一个定时任务(如每天一次): 1. 查 3275-3 历史记录,找出即将过期的任务。 2. 重新调用 3275-2 获取新的 download_url。 3. 下载并覆盖本地副本。 --- ## 历史记录查询(3275-3)的使用 ```python def query_history(app_key: str, page: int = 1): resp = requests.post( "https://route.showapi.com/3275-3", params={"appKey": app_key}, data={"page": str(page)}, timeout=10, ) body = resp.json()["showapi_res_body"] if body["ret_code"] != 0: raise RuntimeError(f"查询失败: {body.get('remark')}") tasks = body.get("contentlist", []) print(f"共 {body['allNum']} 条记录,当前第 {body['currentPage']}/{body['allPages']} 页") for t in tasks: print(f" task_id={t['task_id']} state={t['state']} ct={t['ct']}") return tasks ``` `contentlist` 每条记录包含 `task_id`、`state`、`ct`(上传时间)、`file_url`、`download_url`,注意这些 URL 同样有 7 天时效。 --- ## FAQ **Q1:state=failed 时能不能用同一个 task_id 重新查询得到新结果?** 不能。failed 状态的 task_id 无法恢复,需要重新上传 PDF 生成新 task_id。 **Q3:download_url 过期了还能从 3275-3 历史查询里拿到吗?** 可以,3275-3 返回的 download_url 和 3275-2 一样有 7 天时效。如果任务已超过 7 天,历史记录里的链接也已过期,只能重新转换。 **Q4:怎么知道哪些 PDF 适合这个接口?** 先用小文件(≤10页、含文字层)测试,确认输出格式符合预期后再批量接入。扫描件、加密 PDF、超大文件(>50MB)建议先做前置过滤。 **Q5:接口有调用频率限制吗?** 接口文档未公开限流规则。实测中正常速率(每秒 1~2 次)无问题,建议生产环境加并发控制(如令牌桶),保守起见单 AppKey 不超过 10 QPS。 --- ## 下一步阅读 - [PDF文档转换:5分钟完成异步上传与结果下载](https://www.showapi.com/guides/pdf-doc-convert-quickstart-3275) - [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) --- *本系列共 5 篇:查看[PDF文档转换指南总目录](https://www.showapi.com/guides/pdf-doc-convert-guides-3275)*