CSV参数化批量跑、Shell脚本while循环、Python异步并发、Postman Runner一键拖拽,四种API批量请求方式的速度和门槛各差多少
网站做到一定量级,API批量请求就绕不过去了。100个站要提交百度推送,500个域名要查Whois,2000个URL要过一遍死链检测——如果还是一条一条手动发请求,不夸张地说,一个通宵都搞不完。更头疼的是,不同的API有不同的频率限制、不同的鉴权方式、不同的返回格式,搞不好触发429被限流,前面的全白跑了。
但好消息是,批量请求这件事本身没多复杂。说白了就三个问题:参数怎么批量管理、请求怎么控制节奏、失败怎么处理。这四个主流方案,各解决了其中一个到全部三个问题,但上手门槛和灵活性差得挺多。
四种方案一句话定位
| 1 | Postman Runner:适合不想写代码的人,CSV/JSON文件拖进去,点点鼠标就跑完几千条请求 |
| 2 | curl + Shell脚本:服务器上跑最方便,不用装任何额外软件,一个.sh文件搞定 |
| 3 | Python requests + 异步:灵活性天花板,并发控制、重试策略、结果入库全部自己掌控 |
| 4 | Apifox / Apipost:Postman的国产替代,自动化测试和文档生成更强,但批量跑大型任务稍重 |
一、Postman Runner:拖个CSV文件进去,500个URL提交10秒跑完
Postman的Collection Runner是零代码方案里最好用的,没有之一。核心思路很简单:先把一个API请求调通,保存到Collection里,然后把变化的参数(URL、token、域名等)写进CSV或JSON文件,Runner会自动逐行读取参数、替换到请求里、按顺序执行。

以最常见的场景举例——手上有500个URL要推送到百度站长API。先建一个POST请求,body里用{{url}}占位符替代具体URL,然后准备一个CSV文件,第一列写url,下面500行各写一个链接。打开Runner,选Collection、选环境变量、导入CSV,点"Run",等10秒左右,500条全部跑完。
Runner操作流程(五分钟上手版)
· 调通一个API请求 → 保存到Collection
· 把变化参数用{{变量名}}替换
· 创建CSV/JSON文件,第一行为变量名,下面为具体值
· 点击Collection右侧的"Run" → 导入数据文件 → 设置延迟(ms) → 运行
· 运行完毕查看结果:绿色=成功,红色=失败,点进去看具体返回内容
Runner还有个容易被忽略的功能:延迟设置。在Run配置页面有个"Delay"输入框,单位毫秒。如果目标API有频率限制(比如每秒最多5次),设200ms延迟就正好。比手动写sleep语句省心多了。
Runner容易踩的两个坑
· CSV编码问题:Windows下用Excel保存的CSV默认是ANSI编码,Postman只认UTF-8。如果参数里有中文,Runner跑出来全是乱码。用记事本另存为UTF-8,或者直接用JSON格式替代CSV。
· 变量作用域:Postman有四层变量(Global、Collection、Environment、Data),优先级不同。CSV里的变量是Data层,优先级最高——但如果Collection里定义过同名变量且勾了"Persist",可能会覆盖CSV数据。建议跑之前把所有同名变量清掉。
二、curl + Shell脚本:服务器上一条命令,零依赖开箱即用
如果你操作的是Linux服务器,curl + Shell脚本是成本最低的方案。不需要装任何东西——curl基本是Linux标配,bash更不用说。把URL列表存成txt文件,一行一个,然后一个while循环逐行读取、拼接curl命令、发送请求。
最基础的批量提交脚本,20行就能搞定。把站点token和URL列表准备好,跑一遍就完事。
#!/bin/bash# 百度API批量推送脚本API_URL="http://data.zz.baidu.com/urls?site=你的站点&token=你的token"URL_FILE="urls.txt" # 每行一个URL,最多2000条/次LOG_FILE="push_log.txt"COUNT=0SUCCESS=0FAIL=0while IFS= read -r url; do[[ -z "$url" ]] && continueCOUNT=$((COUNT + 1))RESPONSE=$(curl -s -w "%{http_code}" -H 'Content-Type:text/plain' --data-binary "$url" "$API_URL" 2>&1)HTTP_CODE=$(echo "$RESPONSE" | tail -1)BODY=$(echo "$RESPONSE" | sed '$d')if [[ "$HTTP_CODE" == "200" ]]; thenSUCCESS=$((SUCCESS + 1))echo "[$(date '+%H:%M:%S')] OK $url" >> "$LOG_FILE"elseFAIL=$((FAIL + 1))echo "[$(date '+%H:%M:%S')] FAIL $url (HTTP $HTTP_CODE)" >> "$LOG_FILE"fi# 百度API限制:每秒最多提交约3-5次sleep 0.3done < "$URL_FILE"echo "总计: $COUNT | 成功: $SUCCESS | 失败: $FAIL"echo "详细日志: $LOG_FILE"这个脚本做了三件事:逐行读URL、发curl请求、把成功/失败结果记到日志文件。sleep 0.3秒控制节奏,防止触发百度的频率限制。
Shell方案的三个硬伤
· 单线程慢:while循环是一条一条串行跑。1000条URL,每条sleep 0.3秒,总共要跑5分钟。换成Python异步并发能压缩到30秒。
· 错误处理弱:curl返回非200时脚本只能记录日志,不会自动重试。如果某条因为网络波动失败了,得手动从日志里捞出失败URL重新跑。
· 跨平台不友好:Windows的cmd和PowerShell也能跑curl,但Shell脚本的很多语法(while read、sed、date等)在Windows下行为不同。如果团队里有人用Mac有人用Windows,维护成本会上去。
三、Python requests + 异步并发:灵活性最高,但需要写代码
如果你要处理的不是"发完就完"的简单场景,而是需要智能重试、并发控制、结果入库、进度条显示、断点续传这些能力,Python是绕不过去的选择。用requests库发请求,用asyncio + aiohttp做异步并发,配合tqdm显示进度条,写一个完整的批量请求工具大概80行代码。
import asyncio, aiohttp, json, timefrom pathlib import Pathfrom tqdm.asyncio import tqdm# 配置区API_URL = "http://data.zz.baidu.com/urls?site=xxx&token=xxx"URLS_FILE = "urls.txt"CONCURRENCY = 5 # 并发数,别设太高DELAY = 0.3 # 单请求间隔(秒)MAX_RETRIES = 3 # 失败重试次数OUTPUT_FILE = "result.json"async def push_url(session, url, sem, pbar):async with sem: # 控制并发数for attempt in range(MAX_RETRIES):try:await asyncio.sleep(DELAY)async with session.post(API_URL,data=url.encode(),headers={"Content-Type": "text/plain"},timeout=10) as resp:result = await resp.json()status = "ok" if resp.status == 200 else "fail"pbar.update(1)return {"url": url, "status": status, "resp": result}except Exception as e:if attempt == MAX_RETRIES - 1:pbar.update(1)return {"url": url, "status": "error", "msg": str(e)}await asyncio.sleep(2 ** attempt) # 指数退避async def main():urls = [line.strip() for line in Path(URLS_FILE).read_text(encoding="utf-8").splitlines() if line.strip()]sem = asyncio.Semaphore(CONCURRENCY)connector = aiohttp.TCPConnector(limit=CONCURRENCY)async with aiohttp.ClientSession(connector=connector) as session:with tqdm(total=len(urls), desc="推送进度") as pbar:tasks = [push_url(session, url, sem, pbar) for url in urls]results = await asyncio.gather(*tasks)# 统计并保存结果ok = sum(1 for r in results if r["status"] == "ok")fail = sum(1 for r in results if r["status"] == "fail")err = sum(1 for r in results if r["status"] == "error")Path(OUTPUT_FILE).write_text(json.dumps(results, ensure_ascii=False, indent=2), encoding="utf-8")print(f"\n总计 {len(results)} | 成功 {ok} | 失败 {fail} | 异常 {err}")print(f"结果已保存至 {OUTPUT_FILE}")asyncio.run(main())这个脚本比Shell版本强在四个地方:并发跑(Semaphore控制同时发几个请求,5并发比串行快5倍)、自动重试(失败后指数退避,等2秒、4秒、8秒各试一次)、进度条可视化(tqdm实时显示完成了多少条)、结果结构化保存(JSON文件方便后续分析或重新跑失败的)。
Python方案最适合的三种场景
· 大批量+高并发:超过5000条请求,Shell串行跑一两个小时,Python异步几分钟搞定
· 需要数据处理:API返回结果要解析、过滤、入库、生成报表,Python的pandas和数据库库直接搞定

· 定时任务:配合crontab或Windows计划任务,每天自动跑一遍,新内容自动推送
四、Apifox / Apipost:Postman的国产替代,自动化测试场景更强
如果你除了批量请求之外,还需要API文档自动生成、团队协作、自动化测试用例管理这些能力,Apifox和Apipost值得看一下。它们本质上和Postman是同类产品,但在几个点上做了差异化。
Apifox最大的卖点是API设计-调试-测试-文档一条龙。你定义好接口的请求和响应Schema,它能自动生成Mock数据、自动跑测试用例、自动导出API文档。批量跑接口时,它支持前置脚本和后置脚本(类似Postman的Pre-request和Tests脚本),可以在请求前动态生成参数、请求后自动提取响应中的token存为环境变量。
| 对比维度 | Postman | Apifox | Apipost |
|---|---|---|---|
| 批量请求 | Collection Runner,CSV/JSON数据驱动 | 测试用例批量跑,支持数据驱动+断言 | 流程测试,多接口串联 |
| 免费额度 | 每月1000次Collection Run | 个人免费版不限次数 | 免费版有次数限制 |
| API文档生成 | 需付费升级 | 免费版即可自动生成 | 免费版支持 |
| 环境变量 | 四层变量体系,灵活 | 全局+环境+临时变量 | 全局+环境变量 |
| 脚本语言 | JavaScript | JavaScript | JavaScript |
| 团队协作 | 付费团队版 | 免费版支持多人 | 免费版支持多人 |
Apifox的一个细节优势:后置脚本提取变量
比如你要批量提交百度API,但每个站点的token不同。可以在第一个请求里调用获取token的接口,然后在后置脚本里写pm.environment.set("site_token", response.json().data.token),后续所有请求直接引用{{site_token}}。不需要手动复制粘贴token,也不用担心token过期。
五、四种方案怎么选?看你的技术能力和使用频率
没有哪个方案是绝对"最好"的,取决于你具体的使用场景和自身条件。
选Postman Runner
不会写代码 / 偶尔用一次 / 参数简单(CSV就能搞定)/ 需要在GUI里直观看到每条请求的结果
选curl + Shell
只在Linux服务器上跑 / 逻辑简单不需要重试 / 不想装任何软件 / 配合crontab做定时推送
选Python异步
请求量大(千条以上)/ 需要智能重试 / 结果要结构化处理 / 要做定时自动化 / 有Python基础
选Apifox/Apipost
团队协作场景 / 需要API文档 / 自动化测试需求多 / 不想付费用Postman高级功能
六、不管用哪个工具,三个通用坑提前避开
工具只是手段,批量请求真正的难点不在工具本身,在于对API限制的理解和容错设计。下面三个坑,用任何工具都会遇到。
坑1:频率限制没看文档
每个API都有频率上限。百度推送大约每秒3-5次,GitHub API每小时5000次(认证用户),IndexNow理论上不限但建议不超过每秒10次。不看文档就开跑,跑一半全429。
坑2:失败不重试也不记录
批量跑1000条,跑完看到"完成",以为全成功了。实际上中间有80条因为网络抖动返回了500或timeout,但没有日志、没有重试、没有单独列表——这80条就永远丢了。
坑3:参数里有特殊字符没转义
URL里带&、空格、中文等特殊字符,直接拼进请求里会导致参数解析错误。URL必须做encode处理。CSV文件里也要注意引号和逗号的转义。
| 避坑项 | Postman Runner | Shell curl | Python异步 |
|---|---|---|---|
| 频率控制 | Delay参数设毫秒 | sleep N秒 | Semaphore + asyncio.sleep |
| 失败重试 | 手动重新跑失败的 | 手动从日志提取 | 自动指数退避重试 |
| 结果记录 | Runner界面查看,可导出JSON | 自定义echo到日志文件 | 结构化保存JSON/CSV/数据库 |
| URL编码 | 自动处理 | 需手动--data-urlencode | urllib.parse.quote() |
如果是多站管理的场景——比如你有20个站点,每天新增内容需要自动推送到百度和IndexNow——手动一个一个工具跑也不现实。这时候可以考虑系统化的方案:用UC建站系统内置的双通道推送功能,内容发布后自动触发百度API推送和IndexNow通知,不需要人工介入。多站看板上能直接看到每个站点的推送状态和索引变化,比手动维护一堆Shell脚本和CSV文件省心不少。
七、选工具的本质,是选你愿意在哪花时间
四种方案各有各的定位,不存在谁秒杀谁。Postman Runner省时间但不灵活,Shell脚本零依赖但慢且容错差,Python功能最强但要写代码,Apifox适合团队但批量场景不是它主业。
说穿了,这跟工具本身关系不大。你能接受花10分钟学Postman Runner的操作,还是愿意花半小时写一个Python脚本但以后一劳永逸?你是一次性需求还是每周都要跑?你的API有没有严格的频率限制?回答清楚这三个问题,选哪个方案基本就定了。
有一点是确定的:别把时间花在手动一条条发请求上。哪怕你现在只管理三五个站,养成批量处理的习惯,后面站数翻倍的时候才不会被运维成本拖垮。
