利用Python+requests批量检测网站是否可访问的实战指南
作者:yuanpan
引言
在日常开发、运维、测试和数据采集中,我们经常需要判断一批网站或接口是否能够正常访问。例如:
- 公司官网、后台管理系统是否在线
- 多个接口地址是否返回正常状态码
- 批量检测客户提供的网址是否有效
- 监控服务是否超时、拒绝连接或 DNS 解析失败
- 爬虫任务开始前,先过滤掉不可访问的网址
如果一个一个用浏览器打开,不仅效率低,而且很难记录结果。使用 Python 的 requests 库,就可以把这个过程自动化。
本文会用一个完整案例演示:如何用 Python + requests 批量检测网站是否可访问,并输出成功或失败结果。内容适合 Python 初学者学习,也适合想提升工作效率的小伙伴直接改造使用。
一、requests 库介绍
requests 是 Python 中非常常用的 HTTP 请求库,可以用来发送 GET、POST 等请求。相比 Python 标准库里的 urllib,requests 的写法更简洁,更适合初学者。
它常用于:
- 调用 Web API
- 请求网页内容
- 提交表单数据
- 设置请求头、Cookie、代理
- 下载文件
- 检测网站状态
- 编写简单爬虫或接口测试脚本
一句话理解:requests 可以让 Python 像浏览器一样访问网站或接口。
二、安装 requests
在命令行执行:
pip install requests
如果你的电脑上有多个 Python 版本,建议使用:
python -m pip install requests
安装完成后,可以在 Python 中测试:
import requests print(requests.__version__)
如果能正常打印版本号,说明安装成功。
三、发送 GET 请求
GET 请求通常用于获取页面内容或查询接口数据。
import requests url = "https://www.baidu.com" response = requests.get(url) print(response.status_code) print(response.text[:200])
常见状态码含义:
| 状态码 | 含义 |
|---|---|
| 200 | 请求成功 |
| 301 / 302 | 重定向 |
| 400 | 请求参数错误 |
| 401 / 403 | 未授权或禁止访问 |
| 404 | 页面不存在 |
| 500 | 服务器内部错误 |
| 502 / 503 / 504 | 网关或服务不可用 |
检测网站是否可访问时,通常会把 200 到 399 之间的状态码视为成功,因为 301、302 这类重定向也说明网站本身是能响应的。
四、发送 POST 请求
POST 请求通常用于提交数据,比如登录、表单提交、创建订单、调用接口等。
import requests
url = "https://httpbin.org/post"
data = {
"username": "test",
"password": "123456"
}
response = requests.post(url, data=data)
print(response.status_code)
print(response.json())
如果接口接收 JSON 数据,可以这样写:
import requests
url = "https://httpbin.org/post"
payload = {
"keyword": "python requests",
"page": 1
}
response = requests.post(url, json=payload)
print(response.status_code)
print(response.text)
区别是:
data=更像提交普通表单json=会自动把字典转成 JSON,并设置对应的请求格式
五、设置超时时间
写请求代码时,一定建议设置超时时间。
如果不设置超时,某个网站一直没有响应,程序可能会卡很久,影响整个批量检测流程。
import requests url = "https://www.baidu.com" response = requests.get(url, timeout=5) print(response.status_code)
timeout=5 表示最多等待 5 秒。如果超过 5 秒还没有响应,就会抛出超时异常。
也可以把连接超时和读取超时分开设置:
response = requests.get(url, timeout=(3, 5))
含义是:
- 连接服务器最多等待 3 秒
- 服务器返回数据最多等待 5 秒
六、设置请求头 User-Agent
有些网站会根据请求头判断访问来源。如果没有设置 User-Agent,服务器可能认为这是一个脚本请求,从而拒绝访问。
可以模拟常见浏览器请求头:
import requests
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
)
}
response = requests.get("https://www.baidu.com", headers=headers, timeout=5)
print(response.status_code)
实际项目中,设置 User-Agent 是一个很常见的习惯。
七、批量检测网址状态码
下面进入实战:批量检测多个网站是否可访问。
我们希望程序能够做到:
- 依次请求多个 URL
- 设置 User-Agent
- 设置超时时间
- 输出状态码
- 判断成功或失败
- 捕获常见异常
- 最后统计成功和失败数量
八、完整可运行代码
新建文件 requests_website_checker.py,复制下面代码运行。
from dataclasses import dataclass
from typing import Optional
import requests
from requests import Response
from requests.exceptions import (
ConnectionError,
HTTPError,
InvalidURL,
RequestException,
SSLError,
Timeout,
)
URLS = [
"https://www.baidu.com",
"https://www.csdn.net",
"https://www.python.org",
"https://httpbin.org/status/404",
"https://this-domain-does-not-exist-123456.com",
]
HEADERS = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
)
}
@dataclass
class CheckResult:
url: str
success: bool
status_code: Optional[int]
message: str
elapsed_ms: Optional[float]
def is_success_status(status_code: int) -> bool:
"""判断状态码是否代表网站可访问。"""
return 200 <= status_code < 400
def check_url(url: str, timeout: int = 5) -> CheckResult:
"""检测单个网址是否可访问。"""
try:
response: Response = requests.get(
url,
headers=HEADERS,
timeout=timeout,
allow_redirects=True,
)
elapsed_ms = round(response.elapsed.total_seconds() * 1000, 2)
if is_success_status(response.status_code):
return CheckResult(
url=url,
success=True,
status_code=response.status_code,
message="访问成功",
elapsed_ms=elapsed_ms,
)
return CheckResult(
url=url,
success=False,
status_code=response.status_code,
message=f"状态码异常:{response.status_code}",
elapsed_ms=elapsed_ms,
)
except Timeout:
return CheckResult(url, False, None, "请求超时", None)
except ConnectionError:
return CheckResult(url, False, None, "连接失败,可能是域名错误或服务器不可达", None)
except SSLError:
return CheckResult(url, False, None, "SSL 证书错误", None)
except InvalidURL:
return CheckResult(url, False, None, "URL 格式不正确", None)
except HTTPError as exc:
return CheckResult(url, False, None, f"HTTP 错误:{exc}", None)
except RequestException as exc:
return CheckResult(url, False, None, f"请求异常:{exc}", None)
def print_result(result: CheckResult) -> None:
"""格式化输出检测结果。"""
status = "成功" if result.success else "失败"
status_code = result.status_code if result.status_code is not None else "-"
elapsed = f"{result.elapsed_ms}ms" if result.elapsed_ms is not None else "-"
print(
f"[{status}] {result.url} | "
f"状态码:{status_code} | "
f"耗时:{elapsed} | "
f"说明:{result.message}"
)
def main() -> None:
results = []
print("开始批量检测网站状态...\n")
for url in URLS:
result = check_url(url, timeout=5)
results.append(result)
print_result(result)
success_count = sum(1 for item in results if item.success)
fail_count = len(results) - success_count
print("\n检测完成")
print(f"总数量:{len(results)}")
print(f"成功数量:{success_count}")
print(f"失败数量:{fail_count}")
if __name__ == "__main__":
main()
运行命令:
python requests_website_checker.py
可能输出类似下面这样:
开始批量检测网站状态... [成功] https://www.baidu.com | 状态码:200 | 耗时:122.35ms | 说明:访问成功 [成功] https://www.csdn.net | 状态码:200 | 耗时:358.41ms | 说明:访问成功 [成功] https://www.python.org | 状态码:200 | 耗时:489.73ms | 说明:访问成功 [失败] https://httpbin.org/status/404 | 状态码:404 | 耗时:280.15ms | 说明:状态码异常:404 [失败] https://this-domain-does-not-exist-123456.com | 状态码:- | 耗时:- | 说明:连接失败,可能是域名错误或服务器不可达 检测完成 总数量:5 成功数量:3 失败数量:2
不同网络环境下,状态码和耗时可能不完全一样,这是正常现象。
九、代码重点讲解
1. 为什么使用 dataclass 保存结果
@dataclass
class CheckResult:
url: str
success: bool
status_code: Optional[int]
message: str
elapsed_ms: Optional[float]
dataclass 可以让结果结构更清晰。每个网址的检测结果都包含:
- 网址
- 是否成功
- 状态码
- 错误说明
- 请求耗时
后续如果想保存到 Excel、CSV 或数据库,也更容易扩展。
2. 为什么 200 到 399 算成功
def is_success_status(status_code: int) -> bool:
return 200 <= status_code < 400
通常:
2xx表示请求成功3xx表示重定向4xx表示客户端请求有问题5xx表示服务器异常
网站检测场景下,如果返回 301 或 302,说明服务器有响应,只是跳转到了另一个地址,所以一般也可以视为可访问。
3. 为什么要设置 allow_redirects=True
requests.get(url, allow_redirects=True)
很多网站会从 http 跳转到 https,或者从不带 www 跳转到带 www 的域名。开启重定向后,requests 会自动跟随跳转。
4. 为什么要记录 elapsed_ms
elapsed_ms = round(response.elapsed.total_seconds() * 1000, 2)
状态码只能说明是否响应,耗时可以帮助判断网站是否慢。
例如:
- 200ms:访问很快
- 2s:偏慢
- 5s 以上:用户体验较差
- 超时:可能服务不可用或网络不稳定
十、常见异常处理
批量检测网站时,异常处理非常重要。因为只要一个网址出错,就让整个程序停止,显然不适合批量任务。
1. Timeout 请求超时
except Timeout:
return CheckResult(url, False, None, "请求超时", None)
常见原因:
- 网站响应太慢
- 网络不稳定
- 服务器没有及时返回
解决建议:
- 设置合理超时时间
- 对重要网址增加重试机制
- 记录日志,后续人工排查
2. ConnectionError 连接失败
except ConnectionError:
return CheckResult(url, False, None, "连接失败,可能是域名错误或服务器不可达", None)
常见原因:
- 域名写错
- DNS 解析失败
- 服务器关闭
- 本地网络无法访问目标地址
3. SSLError 证书错误
except SSLError:
return CheckResult(url, False, None, "SSL 证书错误", None)
常见原因:
- HTTPS 证书过期
- 证书链不完整
- 目标站点证书配置错误
不建议随便使用 verify=False 跳过证书校验,除非你非常明确是在内网测试环境。
4. InvalidURL 地址格式错误
except InvalidURL:
return CheckResult(url, False, None, "URL 格式不正确", None)
例如:
www.baidu.com htp://example.com
建议批量检测前统一检查 URL 是否包含 http:// 或 https://。
5. RequestException 兜底异常
except RequestException as exc:
return CheckResult(url, False, None, f"请求异常:{exc}", None)
RequestException 是 requests 异常的基类,可以作为最后的兜底处理,避免程序因为未预料的请求问题直接崩溃。
十一、扩展:从文件读取网址
真实工作中,网址可能不是写死在代码里,而是放在文本文件中。
可以新建 urls.txt:
https://www.baidu.com https://www.csdn.net https://www.python.org
然后这样读取:
from pathlib import Path
def load_urls(file_path: str) -> list[str]:
path = Path(file_path)
return [
line.strip()
for line in path.read_text(encoding="utf-8").splitlines()
if line.strip() and not line.strip().startswith("#")
]
这样就可以让非技术同事只维护 urls.txt,脚本负责自动检测。
十二、使用场景分析
这个脚本可以应用在很多实际场景中。
1. 运维巡检
每天上班前自动检测公司官网、后台系统、接口网关、报表系统是否可访问,提前发现服务异常。
2. 测试环境冒烟检查
部署完成后,先批量请求几个关键接口。如果状态码异常,就不必继续进行后续测试。
3. 爬虫任务预检查
爬虫开始前先检测目标网址是否可访问,过滤掉 404、超时、连接失败的网址,减少无效请求。
4. 客户网址批量核验
如果有一批客户官网、供应商链接或资料链接,可以批量检测哪些还能访问,哪些已经失效。
5. 接口健康检查
虽然专业系统会使用 Prometheus、Zabbix、Uptime Kuma 等监控工具,但对于初学者或轻量任务,一个 Python 脚本已经能解决不少问题。
十三、可以继续优化的方向
掌握本文代码后,还可以继续扩展:
- 把检测结果保存到 CSV 或 Excel
- 使用多线程提高检测速度
- 加入失败重试机制
- 定时执行脚本
- 将失败结果发送到邮箱、企业微信或钉钉
- 支持从配置文件读取 URL、超时时间、请求头
- 对接口返回内容做关键字校验
例如,一个页面虽然返回 200,但如果返回的是错误页,也可能不算真正可用。这时就可以继续检查响应内容中是否包含指定关键字。
十四、总结
本文从 requests 的基础用法讲起,演示了 GET 请求、POST 请求、超时设置、User-Agent 请求头设置,并通过一个完整脚本实现了批量检测网站是否可访问。
对于 Python 初学者来说,这个案例非常适合练习:
- HTTP 请求基础
- 状态码判断
- 异常处理
- 函数封装
- 批量任务处理
- 控制台结果输出
把重复性工作交给脚本,是 Python 提升办公和开发效率的典型用法。你可以直接把本文代码改造成自己的网址检测工具,用在日常巡检、接口测试和数据采集预检查中。
以上就是利用Python+requests批量检测网站是否可访问的实战指南的详细内容,更多关于Python requests检测网站是否可访问的资料请关注脚本之家其它相关文章!
