python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python requests检测网站是否可访问

利用Python+requests批量检测网站是否可访问的实战指南

作者:yuanpan

在日常开发、运维、测试和数据采集中,我们经常需要判断一批网站或接口是否能够正常访问,如果一个一个用浏览器打开,不仅效率低,而且很难记录结果,使用 Python 的 requests 库,就可以把这个过程自动化,本文会用一个完整案例演示,需要的朋友可以参考下

引言

在日常开发、运维、测试和数据采集中,我们经常需要判断一批网站或接口是否能够正常访问。例如:

如果一个一个用浏览器打开,不仅效率低,而且很难记录结果。使用 Python 的 requests 库,就可以把这个过程自动化。

本文会用一个完整案例演示:如何用 Python + requests 批量检测网站是否可访问,并输出成功或失败结果。内容适合 Python 初学者学习,也适合想提升工作效率的小伙伴直接改造使用。

一、requests 库介绍

requests 是 Python 中非常常用的 HTTP 请求库,可以用来发送 GET、POST 等请求。相比 Python 标准库里的 urllibrequests 的写法更简洁,更适合初学者。

它常用于:

一句话理解: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网关或服务不可用

检测网站是否可访问时,通常会把 200399 之间的状态码视为成功,因为 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)

区别是:

五、设置超时时间

写请求代码时,一定建议设置超时时间。

如果不设置超时,某个网站一直没有响应,程序可能会卡很久,影响整个批量检测流程。

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))

含义是:

六、设置请求头 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 是一个很常见的习惯。

七、批量检测网址状态码

下面进入实战:批量检测多个网站是否可访问。

我们希望程序能够做到:

八、完整可运行代码

新建文件 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

通常:

网站检测场景下,如果返回 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)

状态码只能说明是否响应,耗时可以帮助判断网站是否慢。

例如:

十、常见异常处理

批量检测网站时,异常处理非常重要。因为只要一个网址出错,就让整个程序停止,显然不适合批量任务。

1. Timeout 请求超时

except Timeout:
    return CheckResult(url, False, None, "请求超时", None)

常见原因:

解决建议:

2. ConnectionError 连接失败

except ConnectionError:
    return CheckResult(url, False, None, "连接失败,可能是域名错误或服务器不可达", None)

常见原因:

3. SSLError 证书错误

except SSLError:
    return CheckResult(url, False, None, "SSL 证书错误", None)

常见原因:

不建议随便使用 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)

RequestExceptionrequests 异常的基类,可以作为最后的兜底处理,避免程序因为未预料的请求问题直接崩溃。

十一、扩展:从文件读取网址

真实工作中,网址可能不是写死在代码里,而是放在文本文件中。

可以新建 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 脚本已经能解决不少问题。

十三、可以继续优化的方向

掌握本文代码后,还可以继续扩展:

例如,一个页面虽然返回 200,但如果返回的是错误页,也可能不算真正可用。这时就可以继续检查响应内容中是否包含指定关键字。

十四、总结

本文从 requests 的基础用法讲起,演示了 GET 请求、POST 请求、超时设置、User-Agent 请求头设置,并通过一个完整脚本实现了批量检测网站是否可访问。

对于 Python 初学者来说,这个案例非常适合练习:

把重复性工作交给脚本,是 Python 提升办公和开发效率的典型用法。你可以直接把本文代码改造成自己的网址检测工具,用在日常巡检、接口测试和数据采集预检查中。

以上就是利用Python+requests批量检测网站是否可访问的实战指南的详细内容,更多关于Python requests检测网站是否可访问的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文