关于 bulk-url-checker
bulk-url-checker 是用于提交大批量网址检查任务的 Python 客户端和命令行工具,可返回状态码、重定向及失效链接结果,并支持轮询任务和安全重试。
主要功能
- 01批量检查网址并返回状态码
- 02获取重定向链和失效链接结果
- 03提交、轮询并分页读取任务
- 04幂等重试与签名 Webhook
- 05命令行导出 CSV、JSON 和 JSONL
适用场景
- 01检查大量网址中的失效链接
- 02恢复或跟踪长时间运行的检查
- 03将网址检查结果导出为报告
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.bulkurlchecker.com/mcpclaude mcp add --transport http carlosofscience-bulk-url-checker https://mcp.bulkurlchecker.com/mcp{"mcpServers":{"carlosofscience-bulk-url-checker":{"type":"http","url":"https://mcp.bulkurlchecker.com/mcp"}}}在 Cursor 中打开{"servers":{"carlosofscience-bulk-url-checker":{"type":"http","url":"https://mcp.bulkurlchecker.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"carlosofscience-bulk-url-checker":{"type":"http","url":"https://mcp.bulkurlchecker.com/mcp"}}}{"mcpServers":{"carlosofscience-bulk-url-checker":{"serverUrl":"https://mcp.bulkurlchecker.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
5| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| urls | array | 是 | 要检查的 URL。每个 URL 都必须包含 http:// 或 https:// 协议。 |
详细介绍
bulkurlchecker
用于调用 Bulk URL Checker API 的 Python 客户端。
省去代理轮换、速率限制器、软 404 检测器和重试分类器——这些功能原本需要你花两周时间来构建。 提交数千个 URL,即可获取状态码、重定向链和失效链接检测结果,数据以纯 Python 对象的形式返回。由托管云服务提供支持,具备住宅代理和按域名限流功能。
安装
pip install bulkurlchecker
5 行示例
from bulkurlchecker import Client
client = Client(api_key="uck_live_...")
results = client.check_urls(["https://example.com", "https://example.org"])
for r in results.results:
print(r.url, r.status_code, "BROKEN" if r.is_broken else "ok")
请前往 https://app.bulkurlchecker.com/dashboard/api-keys 获取 API 密钥。前 300 个 URL 免费,无需绑定银行卡。
返回结果
results = client.check_urls(urls)
results.status # 'completed' | 'paused' | 'failed' | 'cancelled'
results.timed_out # True if the wait deadline passed (job still running)
results.total_urls # how many URLs the engine accepted
results.completed_urls # how many it finished checking
results.duplicates_removed
results.invalid_urls_rejected
for r in results.results:
r.url # the original URL you submitted
r.final_url # after redirects
r.status_code # 200, 301, 404, 429, 500, ...
r.redirect_chain # list of intermediate URLs
r.is_broken # True if the engine flagged this as broken
r.is_soft_404 # True if 200 OK but page content says "not found"
r.response_time_ms
# Convenience properties:
results.broken # list of URLResult where is_broken == True
results.soft_404s # list where is_soft_404 == True
命令行用法
安装 [cli] 附加组件即可使用 bulkurlchecker 命令:
pip install 'bulkurlchecker[cli]'
export BULKURLCHECKER_API_KEY=uck_live_...
# One URL per line in urls.txt → CSV on stdout
bulkurlchecker check urls.txt > report.csv
# Pipe from anywhere
sitemap-extractor mydomain.com | bulkurlchecker check - --output jsonl > report.jsonl
# Only show broken URLs, ad-hoc input
bulkurlchecker check --urls "https://example.com,https://example.org" --only-broken
# Two-step (submit, then poll & fetch later)
JOB=$(bulkurlchecker submit urls.txt)
bulkurlchecker status "$JOB"
bulkurlchecker results "$JOB" --output csv > report.csv
输出格式:csv(默认)、json、jsonl。运行 bulkurlchecker check --help 查看完整的标志列表。
处理较大的任务:提交并轮询
check_urls() 会在服务端阻塞最多 15 分钟。对于等待时间可能超时的列表,请使用以下两步模式:
job = client.submit(my_500k_urls)
print(f"Submitted {job.job_id}, {job.total_urls} URLs queued")
# Poll explicitly, or use the convenience method
done = client.wait_until_done(job.job_id, timeout=3600)
# Stream results in pages
for batch in client.iter_results(job.job_id, page_size=1000):
for r in batch:
if r.is_broken:
print(r.url, r.status_code)
使用 idempotency_key 安全重试
在 submit() 或 check_urls() 中传入幂等键,即可在网络故障时安全重试。服务器会将响应缓存 24 小时;使用相同的键和相同的请求正文重试时,会返回原始结果,而不会创建重复任务。
import uuid
key = str(uuid.uuid4()) # generate once per logical request
# First call: creates a new job.
job = client.submit(urls, idempotency_key=key)
# Network blip, no clean response received? Just retry with the same
# key -- you'll get the SAME job summary back, no duplicate submission.
same_job = client.submit(urls, idempotency_key=key)
# job.job_id == same_job.job_id
相同的 idempotency_key 配上不同的 urls 会返回 409 Conflict(以 ValidationError 的形式抛出),这样客户端重复使用密钥提交新载荷时会明确报错,而不会悄悄映射到错误的缓存结果。
接收 Webhook
任务完成时,我们会向你注册的端点发送包含签名载荷的 POST 请求。请先验证签名,再信任请求正文——否则,任何知道你端点 URL 的人都可以发送伪造事件。
from flask import Flask, request
from bulkurlchecker import verify_signature, InvalidSignatureError
SECRET = os.environ["MY_WEBHOOK_SECRET"] # the signing_secret we showed once
app = Flask(__name__)
@app.route("/webhook/bulkurlchecker", methods=["POST"])
def webhook():
try:
verify_signature(
request.get_data(), # RAW bytes — not request.get_json()
request.headers.get("Bulkurlchecker-Signature", ""),
SECRET,
)
except InvalidSignatureError:
return "", 401
event = request.get_json()
if event["type"] == "job.completed":
job_id = event["data"]["job_id"]
# ... fetch results, update your DB, ping Slack, etc ...
return "", 200
请前往 https://app.bulkurlchecker.com/dashboard/webhooks 注册端点并获取密钥(也可通过 POST /api/v2/webhooks/endpoints 操作)。
verify_signature() 默认会强制执行 5 分钟的时间戳容差,以防止重放攻击。可通过 tolerance_seconds= 调整。
错误处理
所有错误都继承自 BulkURLCheckerError。若要针对不同失败情况采取不同处理方式,请捕获具体的子类:
from bulkurlchecker import (
Client,
BulkURLCheckerError,
AuthenticationError,
RateLimitError,
QuotaError,
ValidationError,
)
try:
results = client.check_urls(urls)
except QuotaError as e:
print(f"Out of credits. Top up at https://app.bulkurlchecker.com/billing")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s.")
except AuthenticationError:
print("API key rejected — check it's not revoked.")
except ValidationError as e:
print(f"Bad request: {e}") # bad URLs, too many URLs, etc.
except BulkURLCheckerError as e:
print(f"Other error: {e} (request_id={e.request_id})")
每个错误都包含 status_code、code(服务器提供的机器可读字符串)、request_id(用于联系支持团队)以及 details(服务器提供时)。
为什么要用这个,而不是用 httpx + asyncio 自己编写检测器?
坦白说:对于 ≤500 个 URL,你不需要它。标准的 requests/httpx 工具链足以应付。
规模增大后,就会遇到瓶颈:
| 问题 | 自己搭建 | 本 SDK |
|---|---|---|
| 并发 | asyncio + 精心配置的信号量 | 已处理 |
| 跨住宅 IP 轮换代理 | 每月 90 美元以上的 Webshare / Bright Data 订阅 + 自定义代码 | 已处理 |
| 按域名限流(避免向单个主机发送过多请求) | 自己接入 | 已处理 |
| 区分真正的 403 和“你被拦截了”的 403 | 靠猜测和测试 | 已处理 |
| 检测软 404(200 OK +“未找到”正文) | 为每种模板编写正则表达式 / 启发式规则 | 已处理 |
| 重试分类(临时错误还是永久错误) | 花数周调优 | 已处理 |
| 长时间运行任务的状态(崩溃后恢复) | Redis + 队列 + Worker 基础设施 | 已处理 |
| 工程师投入,第 1–4 周 | $$$ | 无,今天即可上线 |
如果你已经因为 httpx + 代理轮换搭建忙了一个周末,你就知道我们在说什么。
定价
- **首月免费:**Starter 计划提供 15,000 次 URL 检查,无需信用卡。 首次通过 API 或 SDK 集成成功运行后,试用期将延长 为一个月的 Pro 计划:50,000 次 URL 检查,每个账户限一次。
- **之后:**每个账户每月均包含 300 次 URL 检查。
- Starter:$9/月或 $90/年,每月 15,000 个 URL
- Pro:$29/月或 $290/年,每月 50,000 个 URL
- Agency:$99/月或 $990/年,每月 200,000 个 URL
所有计划均包含定期检查,以及电子邮件、Slack 和 webhook 告警。一次性额度包售价从 $5(3,000 次检查)起,额度可结转。当前价格:https://bulkurlchecker.com/#pricing
链接
稳定性
SDK 遵循语义化版本规范。在我们处于 0.x 阶段时,次要版本可能包含破坏性变更(我们会始终在 CHANGELOG.md 中注明)。达到 1.0 后,你可以放心固定主版本。
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。