简介
在运维工作中,检查 Web 服务是否可用是一项常见任务。虽然 requests 等第三方库很受欢迎,但在受限环境中,有时只能依赖 Python 标准库。
在本实验中,你将使用 Python 标准库中的 urllib 模块创建一个简单的网络连接检查器。这个过程说明,即使不添加额外依赖,也可以构建实用的运维工具。
完成本实验后,你将了解如何:
- 导入
urllib.request模块。 - 定义用于检查 URL 的函数。
- 获取 HTTP 状态码,例如
200 OK。 - 处理服务器错误或主机无法访问等异常。
- 显示易于理解的状态消息。
导入模块
在本步骤中,先创建 Python 脚本并导入所需模块。urllib.request 是 Python 内置的 URL 打开工具。你可以把它理解为一个由代码控制的 Web 浏览器,例如 Chrome 或 Firefox,而不需要使用鼠标。它可以让脚本从互联网获取数据。
这对运维工作很有用,因为许多系统会提供基于 HTTP 的 API 或健康检查端点。即使团队之后采用第三方库,理解标准库工具也能帮助你更清楚地掌握底层的请求—响应模型。
首先确认当前位于正确的目录。打开终端并进入项目目录:
cd ~/project
现在,使用 nano 文本编辑器(或你喜欢的其他编辑器)创建名为 connectivity_check.py 的 Python 文件:
nano connectivity_check.py
在 Python 中,使用库之前必须先导入它。在文件顶部添加以下内容。这里导入 urllib.request 来处理请求,导入 urllib.error 来处理后续可能出现的错误。
import urllib.request
import urllib.error
按 Ctrl+O,再按 Enter 保存文件,然后按 Ctrl+X 退出 nano。
你可以使用 cat 命令验证文件内容:
cat connectivity_check.py
定义函数
现在已经准备好导入模块,接下来需要组织代码。将逻辑封装在函数中是一种良好实践,这样代码更易于复用和测试。
函数在运维脚本中特别有用,因为同一个操作通常需要针对多个目标执行。将网络检查封装到函数后,你可以为不同的 URL 调用该函数,而不必重复编写代码。
在本步骤中,定义名为 check_url 的函数,并让它接收一个 URL 字符串作为参数。
再次打开 connectivity_check.py 文件:
nano connectivity_check.py
将以下函数定义添加到导入语句下方。现在先添加 pass 语句。在 Python 中,pass 是表示「不执行任何操作」的占位语句。下一步会补充具体逻辑。
import urllib.request
import urllib.error
def check_url(url):
print(f"Checking connectivity for: {url}")
## Logic will go here
pass
保存并退出编辑器(Ctrl+O、Enter、Ctrl+X)。
这个结构为后续代码搭建了基础。check_url 函数接收一个名为 url 的参数,该参数表示要测试的网站地址,例如 "https://www.google.com"。
发送请求
在本步骤中,实现发送请求并获取 HTTP 状态码的核心逻辑。HTTP 状态码 200 通常表示「OK」,也就是请求成功。
从整体上看,HTTP 请求是客户端与服务器之间的一次对话。你的脚本充当客户端,向 URL 发送请求,等待服务器响应,然后检查状态码等元数据,再决定下一步操作。
我们将使用 urllib.request.urlopen() 打开 URL。该函数会返回一个响应对象,响应对象提供 .getcode() 方法,用于获取状态码。
打开 connectivity_check.py:
nano connectivity_check.py
将 check_url 函数更新为以下内容。注意,这里设置了 5 秒超时,防止服务器没有响应时脚本一直等待。
import urllib.request
import urllib.error
def check_url(url):
print(f"Checking connectivity for: {url}")
## Open the URL with a 5-second timeout
response = urllib.request.urlopen(url, timeout=5)
## Get the status code
status_code = response.getcode()
print(f"Status Code: {status_code}")
注意:在此阶段,如果 URL 无效或服务器已停止运行,脚本会崩溃,因为我们还没有添加错误处理。下一步将解决这个问题。
保存并退出编辑器。
处理错误
网络编程具有不可预测性。服务器可能停止运行,DNS 查询可能失败,互联网连接也可能中断。如果 urlopen 执行失败,就会引发异常。为了让脚本更加健壮,必须使用 try...except 代码块处理这些异常。
在实际监控中,区分不同的故障类型非常重要。服务器返回 500,表示你已经连接到服务器,并且服务器报告了内部问题。而 URLError 通常表示请求根本没有到达可用的 HTTP 端点。优秀的运维人员会将它们视为不同类型的事件。
我们将处理以下两种具体错误:
urllib.error.HTTPError:服务器返回了响应,但状态码表示错误,例如 404 Not Found 或 500 Server Error。urllib.error.URLError:根本无法访问服务器,例如没有互联网连接或域名错误。
你可以把 try...except 代码块理解为安全网。如果发生问题,例如互联网连接中断,代码不会直接崩溃,而是进入 except 代码块,在那里捕获错误并显示有帮助的信息。
打开 connectivity_check.py:
nano connectivity_check.py
修改函数,将请求逻辑放入 try 代码块中:
import urllib.request
import urllib.error
def check_url(url):
print(f"Checking connectivity for: {url}")
try:
## Attempt to open the URL
response = urllib.request.urlopen(url, timeout=5)
status_code = response.getcode()
print(f"Success! Status Code: {status_code}")
except urllib.error.HTTPError as e:
## Server responded with an error (e.g., 404, 500)
print(f"HTTP Error: {e.code}")
except urllib.error.URLError as e:
## Failed to reach the server
print(f"URL Error: {e.reason}")
代码会先尝试执行 try 代码块中的语句。如果发生错误,Python 会停止执行 try 代码块,并跳转到匹配的 except 代码块。
保存并退出编辑器。
测试脚本
在最后一个步骤中,添加一个调用函数的主代码块,使脚本可以直接执行。这样就能从终端直接运行脚本。
if __name__ == "__main__": 是 Python 中的惯用模式,用于区分可复用的函数和直接执行脚本时应运行的代码。这个小型设计可以方便后续复用,因为其他脚本导入 check_url 时,不会自动执行测试调用。
我们将使用一个已知可用的 URL(例如 https://www.example.com)进行测试。你也可以测试一个虚构的 URL,观察错误处理的效果。
打开 connectivity_check.py:
nano connectivity_check.py
将以下代码添加到文件末尾:
if __name__ == "__main__":
## Test with a valid URL
target_url = "https://www.example.com"
check_url(target_url)
print("-" * 20)
## Test with an invalid URL to see error handling
invalid_url = "https://www.this-domain-does-not-exist-12345.com"
check_url(invalid_url)
if __name__ == "__main__": 代码块确保其中的代码只会在直接执行脚本时运行,而不会在其他脚本将该文件作为模块导入时运行。
保存并退出编辑器。
现在运行脚本,查看结果:
python3 connectivity_check.py
你应该会看到类似以下内容的输出:
Checking connectivity for: https://www.example.com
Success! Status Code: 200
--------------------
Checking connectivity for: https://www.this-domain-does-not-exist-12345.com
URL Error: [Errno -2] Name or service not known
(注意:无效 URL 的具体错误消息可能会因网络环境不同而略有差异。)
总结
在本实验中,你已经成功使用 Python 标准库创建了一个网络连接检查器。你学习了如何:
- 导入模块:使用
urllib.request和urllib.error。 - 发送 HTTP 请求:使用
urlopen连接 Web 服务器。 - 处理响应:获取 HTTP 状态码,以验证服务是否可用。
- 管理错误:使用
try...except代码块处理HTTPError和URLError,让脚本能够应对网络故障。
这项技能是创建监控脚本、健康检查工具和简单 Web 抓取器的基础,尤其适用于无法安装外部依赖的环境。



