Python 网站连通性检查项目
在本教程中,我们将学习Python中的网站连通性检查器。它本身就是一个有趣的项目,可以提升技能。我们将学习如何处理HTTP请求,创建命令行界面(CLI),以及使用常见的Python项目布局实践组织我们应用程序的代码。
我们还将讨论异步特性,以帮助有效地理解多个HTTP请求。
项目概述
网站连通性检查器是一种有助于确定网站是否可访问的工具。它可以帮助识别网站何时处于宕机或不可用状态。用户输入他们要检查的网站的网址,应用程序将验证其连通性状态,并为用户显示结果。
我们的应用程序将通过最小化的命令行界面(CLI)输入一些选项。下面是这些选项的摘要 –
- -u或-urls - 它允许通过命令行输入一个或多个目标URL。
- -f或-input-file- 它允许提供包含要检查的URL列表的文件。
- -a或-asynchronous- 它允许异步运行连通性检查。
默认情况下,我们的应用程序将同步运行,这意味着网站连通性将一个接一个地检查。
要并行运行连通性检查,我们可以使用-a或–asynchronous选项,并利用Python的异步功能和aiohttp库。但是,异步检查可以使网站连通性检查器更快且更有效。
先决条件
在进一步操作之前,我们应该对以下主题有基本的了解。
- 熟悉异常处理
- 使用语句和pathlib模块处理文件
- 使用argparse模块创建CLI应用程序
- 使用标准库或第三方工具处理HTTP请求
- Python的asyncio库
了解aiohttp库对于这个项目是有益的,但是可以选择性地学习。如果您对该库还不熟悉,请不要灰心。尝试一下该项目将让您学习和成长,如果需要,您可以随时参考资源以获得帮助。
在深入编码网站连通性检查器项目之前,设置适当的工作环境和组织我们的项目文件非常重要。在考虑项目概述和必要的先决条件之后,我们可以开始准备我们的工作区并建立一个最适合您的项目布局。这将使编码更容易,并确保您的项目运行顺利。
设置Python中的网站连通性检查器
本节将讨论网站连通性检查器应用程序的结构。首先,我们将创建Python虚拟环境,以隔离依赖项与其他项目的依赖项。接下来,我们将通过创建所有必需的文件和目录结构来设置项目的布局。
设置开发环境
首先,我们将使用以下命令创建虚拟环境并激活。
python -m venv venv
venv\Scripts\activate
现在,我们将在虚拟环境中使用pip安装以下库。
pip install aiohttp
此命令将安装aiohttp到虚拟环境中,将与Python的异步功能一起使用,以处理我们的网站连通性检查应用程序中的异步HTTP请求。
组织网站连通性检查器项目
Python在组织应用程序方面提供了灵活性,因此您可能会在不同项目中遇到各种结构。然而,对于小型可安装的Python项目,常见的结构是拥有一个单一的软件包,该包通常以项目本身的名称命名。
以下是网站连通性检查器应用程序的目录结构。
[('Cache-Control', 'max-age=0, no-cache, no-store, must-revalidate'), ('CF-Cache-Status', 'DYNAMIC'), ('CF-RAY', '6b882f6c5cec3fbe-SIN'), ('CF-Visitor', '{"scheme":"https"}'), ('Content-Type', 'text/html; charset=utf-8'), ('Date', 'Thu, 04 Nov 2021 12:05:08 GMT'), ('Edge-Cache-Tag', 'CT-8892258947'), ('Expect-CT', 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'), ('Expires', 'Thu, 04 Nov 2021 12:05:08 GMT'), ('Server', 'cloudflare'), ('Vary', 'Accept-Encoding'), ('X-Content-Type-Options', 'nosniff'), ('X-Frame-Options', 'SAMEORIGIN'), ('X-Xss-Protection', '1; mode=block')]
解释-
上述代码使用了http.client模块中的HTTPConnection类来检查pypi.org网站的可用性。HTTPConnection类在端口80上创建与HTTP服务器(此处为pypi.org)的连接,并设置了10秒的超时时间。
然后,使用 request() 方法向服务器发送一个HEAD请求,并将“HEAD”作为请求方法和“/”作为资源路径传递进去。
最后,使用 getresponse() 方法获取HEAD请求的响应,并使用getheaders()方法打印响应头。头中包含了响应的状态码、内容类型和内容长度等信息。
现在,我们将在checker.py文件中实现以下代码。
示例-
from http.client import HTTPConnection
from urllib.parse import urlparse
def check_site_is_online(url, timeout=2):
"""如果目标URL在线,返回True
"""
error = Exception("未知错误")
parser = urlparse(url)
host = parser.netloc or parser.path.split("/")[0]
for port in (80, 443):
connection = HTTPConnection(host=host, port=port, timeout=timeout)
try:
connection.request("HEAD", "/")
return True
except Exception as e:
error = e
finally:
connection.close()
raise error
解释-
上述代码定义了名为 check_site_is_online() 的函数,该函数以URL和超时时间为输入,并在网站在线时返回True,或在网站离线或出现未知错误时引发异常。
该函数使用urllib.parse模块中的urlparse函数来解析URL并提取主机名。如果在网络位置(parser.netloc)中未找到主机名,则它将从资源路径(parser.path)中删除。
然后,该函数尝试使用http.client模块中的HTTPConnection类在端口80和443上连接主机(默认超时时间为2秒,可通过timeout参数传递不同的值进行更改)。使用request方法发送一个HEAD请求,如果请求成功,则函数返回True。
如果引发了异常,则将其捕获并存储在错误变量中。最后,关闭连接,并在未进行任何成功的请求时引发错误。它允许函数检测网站是否离线或是否存在其他错误,并引发适当的异常。
运行第一个可连通性检查器
我们将执行 check_site_is_online() 函数,并检查函数是否工作。
Example –
import site_checker.checker as site
urls = ["python.org", "javatpoint.com"]
for url in urls:
result = site.check_site_is_online(url)
status = "在线" if result else "离线"
print(f"{url} {status}。")
Output:
True
True
创建我们的网站连通性检查器CLI
目前为止,我们已经实现了站点检查器,该检查器通过使用标准库中的 http.client 模块执行HTTP请求来验证网站是否在线。这个部分将有一个最小的CLI,允许我们从命令行运行我们的网站连通性检查应用程序。
在这里,我们将提供来自命令行的URL和一个包含URL列表的文本文件的加载列表。此应用程序还将返回用户友好的消息。 上面的代码将驻留在main .py文件中,我们将从命令行接受参数并返回输出。
让我们理解下面的代码。
示例 –
import argparse
import asyncio
import aiohttp
async def check_site(url):
async with aiohttp.ClientSession() as session:
try:
async with session.get(url, timeout=5) as response:
return response.status == 200
except:
return False
async def main():
parser = argparse.ArgumentParser(description="Check website connectivity.")
group = parser.add_mutually_exclusive_group()
group.add_argument("-u", "--urls", nargs="*", help="list of URLs to check")
group.add_argument("-f", "--file", type=argparse.FileType("r"), help="text file containing a list of URLs to check")
args = parser.parse_args()
if args.urls:
urls = args.urls
elif args.file:
urls = [url.strip() for url in args.file.readlines()]
else:
parser.print_help()
return
tasks = [asyncio.ensure_future(check_site(url)) for url in urls]
results = await asyncio.gather(*tasks)
for url, result in zip(urls, results):
status = "online" if result else "offline"
print(f"{url} is {status}.")
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
输出:
(venv) C:\Users\User\Desktop\my_project>python site_checker_async.py -u python.org pypi.org javatpoint.com
python.org is online.
pypi.org is online.
javatpoint.com is online.
(venv) C:\Users\User\Desktop\my_project>python site_checker_async.py -u python.org pypi.org non-existing-site.org
python.org is online.
pypi.org is online.
non-existing-site.org is offline.
(venv) C:\Users\User\Desktop\my_project>vim sample.txt
python.org
javatpoint.com
google.com
geeksforgeek.com
pypi.org
docs.python.org
(venv) C:\Users\User\Desktop\my_project>python site_checker_async.py -f sample.txt
python.org is online.
javatpoint.com is online.
google.com is online.
geeksforgeek.com is online.
pypi.org is online.
docs.python.org is online.
说明 –
这段代码使用argparse模块为应用程序创建了一个命令行界面。创建了一个带有应用程序说明的parser对象,并添加了两个互斥的参数:–urls和–file。–urls参数允许用户在命令行参数中提供URL列表,而–file参数允许用户提供包含URL列表的文件。
如果提供了–urls参数,则URL列表存储在urls变量中。如果提供了–file参数,则会读取该文件并提取URL列表,将其存储在urls变量中。如果未提供任何参数,将调用parser.print_help()方法以显示帮助信息,并返回函数。
最后,代码循环遍历urls列表并为每个URL调用检查网站是否在线的函数,将每个网站的状态打印到控制台。
我们的网站连通性检查程序很有效。运行site_connectivity应用程序并使用-h或–help选项会显示一个使用消息,其中概述如何使用该应用程序。该应用程序允许您通过在命令行中提供URL或从文本文件中加载它们来检查多个网站的连通性。如果在连通性检查期间发生错误,则将显示详细的消息,指示错误的原因。
异步检查多个网站
在这里,我们将编写检查网站的异步代码。让我们理解下面的代码。
示例 –
import argparse
import asyncio
import site_checker.checker
async def check_site(url):
result = await asyncio.get_event_loop().run_in_executor(None, site_checker.checker.check_site_is_online, url)
status = "online" if result else "offline"
print(f"{url} is {status}.")
def main():
parser = argparse.ArgumentParser(description="检查网站连接性。")
group = parser.add_mutually_exclusive_group()
group.add_argument("-u", "--urls", nargs="*", help="要检查的网站的URL列表")
group.add_argument("-f", "--file", type=argparse.FileType("r"), help="包含要检查的网站列表的文本文件。")
args = parser.parse_args()
if args.urls:
urls = args.urls
elif args.file:
urls = [url.strip() for url in args.file.readlines()]
else:
parser.print_help()
return
tasks = [check_site(url) for url in urls]
asyncio.get_event_loop().run_until_complete(asyncio.gather(*tasks))
if __name__ == "__main__":
main()
输出:
(venv) C:\Users\User\Desktop\my_project>python -m site_checker -u python.org pypi.org javatpoint.com
pypi.org is online.
javatpoint.com is online.
python.org is online.
结论
在本教程中,我们已经在Python中构建了可用的网站连接性检查器应用程序。我们学习了有关处理给定网站的HTTP请求的基础知识。我们还使用argparse实现了命令行接口,并讨论了使用Python的http.client检查网站是否在线。我们还同步检查了多个网站。