周一至周五 09:00 - 18:00(UTC+08:00) 
©2026 NST LABS TECH LTD. 保留所有权利。 Python的Try Except用于可靠的网络爬虫错误处理Lena ZhouGrowth & Integration Specialist
Python 尝试异常处理用于可靠的网页爬虫 2026
Python 的 try except 是在一个请求失败后停止的抓取器与能够在网络故障中继续工作的爬虫之间的区别。在生产抓取中,错误是正常的。服务器可能会超时,代理可能会失败,页面可能会返回 403,或者在布局更改后选择器可能会失效。本指南通过高可用性爬虫的视角解释 try、except、else 和 finally。它是为那些已经发送 HTTP 请求并且现在需要更安全故障处理的 Python 开发者编写的。您将学习如何捕获特定的异常、进行重试、轮换代理、释放资源,并将 Nstproxy 作为稳定代理工作流程的一部分使用。
关键要点
- 使用
python try except 处理预期的爬虫故障,而不掩盖错误。
- 捕获特定的异常,如
Timeout、ProxyError 和 HTTPError。
- 在成功请求之后使用
else 进行解析。
- 使用
finally 进行清理、会话关闭和指标记录。
- 当网络故障重复时,将重试逻辑与代理轮换配对。
网络爬取中的常见异常
抓取器以特定模式失败,因此异常处理应该匹配这些模式。将网络错误、代理错误、HTTP 状态错误和解析错误视为不同的事件。
| 故障类型 | 常见原因 | 典型异常或信号 | 行动 |
|---|
| 超时 | 服务器慢或网络差 | requests.exceptions.Timeout | 进行重试 |
| 代理失败 | 代理失效或身份验证问题 | requests.exceptions.ProxyError | 切换代理 |
| 连接失败 | DNS、重置、拒绝连接 | ConnectionError | 重试或暂停 |
| HTTP 阻塞 | 403、407、429 | 状态码 | 轮换代理或降低速率 |
| 解析失败 | HTML 改变 | AttributeError、KeyError | 记录并更新解析器 |
| JSON 失败 | 无效的响应主体 | ValueError | 验证内容类型 |
官方的 requests 文档列出了 、 和 等异常,详见其 。Python 也在 中记录了异常处理。
Lena ZhouGrowth & Integration Specialist
Timeout
TooManyRedirects
HTTPError
关键规则很简单。捕获您可以恢复的内容。在开发过程中,让未知的错误浮现出来。
爬虫的 Python Try Except 基础
Python 的 try except 应该仅保护有风险的操作。在爬虫中,这通常意味着请求、状态检查、解析步骤或存储步骤。确保每个块足够小以进行解释。
import requests
url = "https://example.com/products"
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
except requests.exceptions.Timeout:
print("请求超时;安排重试。")
except requests.exceptions.HTTPError as exc:
print(f"HTTP 错误:{exc.response.status_code}")
except requests.exceptions.RequestException as exc:
print(f"网络错误:{exc}")
else:
html = response.text
print("现在可以安全地解析页面。")
这个模式比广泛的 except: 更好。它分开了超时、HTTP 错误和一般请求失败。它还保持解析在 else 块中,只有在请求成功后才会运行。
try:
response = requests.get(url)
except:
pass
它隐藏了真正的错误。此外,它还造成了静默的数据缺口,这比可见错误更难修复。
捕获代理错误和轮换 IP
代理错误需要自己的分支,因为修复与正常重试不同。如果一个代理端点失败,重复同样的请求通过同一代理可能会浪费时间。抓取器应该将代理标记为不健康,并尝试另一个代理。
import requests
def fetch_with_proxy(url, proxy):
proxies = {
"http": proxy,
"https": proxy,
}
try:
response = requests.get(url, proxies=proxies, timeout=12)
response.raise_for_status()
except requests.exceptions.ProxyError:
return {"ok": False, "reason": "proxy_error", "retry": True}
except requests.exceptions.Timeout:
return {"ok": False, "reason": "timeout", "retry": True}
except requests.exceptions.HTTPError as exc:
status = exc.response.status_code
return {"ok": False, "reason": f"http_{status}", "retry": status in (403, 407, 429)}
except requests.exceptions.RequestException as exc:
return {"ok": False, "reason": str(exc), "retry": True}
else:
return {"ok": True, "html": response.text}
这种结构使重试决策变得明确。 ProxyError 可以触发代理替换。429 可以触发减慢节奏。403 可以触发对头部、会话行为或代理质量的审查。
Nstproxy 自然适合在这里使用。如果您的爬虫使用旋转代理池,Nstproxy 可以为重试工作流提供更清洁的代理源。其智能 IP 旋转和全球覆盖降低了被封锁、出现验证码和速率限制的可能性,使爬虫能够大规模访问公共信息。
正确使用 else 和 finally
else 块最适合在没有异常发生后运行的工作。在抓取中,将解析或提取放在这里。这可以防止在缺失或失败的响应上运行解析器。
finally 块最适合用于清理。使用它来关闭会话,释放浏览器页面,更新指标或将代理令牌返回到池中。避免在 finally 中使用复杂的业务逻辑。
session = requests.Session()
try:
response = session.get(url, timeout=10)
response.raise_for_status()
except requests.exceptions.RequestException as exc:
logger.warning("fetch_failed", extra={"url": url, "error": str(exc)})
else:
title = parse_title(response.text)
save_record(url, title)
finally:
session.close()
这看起来就像是一个爬虫生命周期。尝试请求。处理已知的失败。仅在成功时解析。每次执行清理。
Python 文档还支持在调用者应决定接下来发生什么时重新抛出异常。这在低级抓取函数不应将失败隐藏在作业调度程序中时非常有用。
生产重试策略
生产重试逻辑应该是有限的、可观察的和礼貌的。无限重试可能会使目标网站过载,并浪费代理带宽。更安全的模式是带有抖动的指数回退、重试上限和状态感知的决策。
urllib3 项目文档中有一个用于处理 HTTP 客户端中的重试行为的 Retry 实用程序。请参见 urllib3 Retry 获取基础概念。
| 重试触发 | 是否重试? | 额外操作 |
|---|
| 超时 | 是 | 增加回退 |
| 代理错误 | 是 | 更换代理 |
| 403 | 有时 | 审查头部和代理声誉 |
| 407 | 是 | 检查代理认证 |
| 429 | 是 | 限速并轮换 IP |
| 404 | 否 | 记录缺失页面 |
| 解析器错误 | 不立即重试 | 记录样本 HTML |
生产代码应记录每次尝试。包括 URL、状态代码、异常类型、代理 ID、重试计数和最终结果。这些字段有助于您区分差的代理和差的解析器。
Nstproxy 可以通过为爬虫提供管理的代理源,而不是随机的免费代理,从而减少网络层的噪声。团队在诊断期间还可以使用 免费代理检查器 和 住宅代理 进行需要真实网络配置文件的工作流。
比较总结:简单的 Try Except 与生产处理
简单的 python try except 示例适合学习。生产爬虫需要更多的结构,因为同一个异常可能意味着不同的操作。
| 领域 | 初学者模式 | 生产爬虫模式 |
|---|
| 异常类型 | 捕获所有错误 | 捕获特定异常 |
| 代理处理 | 重试相同请求 | 在代理失败时替换代理 |
| HTTP 状态 | 忽略或打印 | 根据 403、407、429、5xx 路由 |
| 日志记录 | 控制台输出 | 带有代理 ID 的结构化日志 |
| 重试 | 手动循环 | 回退、抖动、最大尝试次数 |
| 解析 | 在 try 内解析 | 在成功后于 else 中解析 |
| 清理 | 常常被跳过 | finally 关闭会话 |
高可用性爬虫的实用工作流
一个稳定的爬虫应该将失败视为数据。每个失败的请求都应该更新下一个决策。
- 选择一个 URL 和代理。
- 发送带有超时的请求。
- 捕获特定的网络和代理异常。
- 当错误可以恢复时,进行带回退的重试。
- 在
ProxyError、407、重复的 403 或重复的 429 时轮换代理。
- 仅在干净的响应后解析。
- 记录最终结果。
- 存储失败的 URL 以供后续审查。
这个工作流提高了存活率,而不会掩盖真实缺陷。它也帮助团队决定问题是目标页面、解析器、请求模式还是代理池。
常见问题
python 的 try except 是什么?
它允许 Python 在 try 块中运行风险代码,并在一个或多个 except 块中处理预期的失败。在抓取器中,它防止一个失败的请求停止整个工作。
我应该在抓取器中捕获 Exception 吗?
优先捕获特定异常。仅在记录错误并保持工作运行的边界处使用 Exception。避免裸 except: ,因为它可能隐藏错误。
我该如何在 Python 请求中处理代理错误?
捕获 requests.exceptions.ProxyError,将代理标记为不健康,然后使用不同的代理重试。还要记录代理 ID、URL 和重试次数。
解析代码应该放在 try 还是 else 中?
当解析依赖于成功请求时,将解析放在 else 中。这可以防止失败的响应到达你的解析器。
Nstproxy 如何帮助抓取器的可靠性?
Nstproxy 提供支持重试和 IP 轮换工作流的代理基础设施。它有助于减少由低质量或不稳定代理源引起的故障。
结论
在构建网络抓取器时,Python 的 try except 不仅仅是初学者的语法。它是控制层,可以通过超时、代理失败、HTTP 阻止和解析器变化来保持工作存活。
从小开始。捕获特定异常。使用 else 进行解析,使用 finally 进行清理。增加限额重试并配合退避。在失败与网络有关时轮换代理。对于需要更稳定代理基础设施的团队,Nstproxy 是 Python 抓取工作流的实用选择。
Lena Zhou
May 29th 2026
立即访问住宅、数据中心、IPv6 与 ISP 高质量代理池。