利用Python+requests批量檢測網(wǎng)站是否可訪問的實(shí)戰(zhàn)指南
引言
在日常開發(fā)、運(yùn)維、測試和數(shù)據(jù)采集中,我們經(jīng)常需要判斷一批網(wǎng)站或接口是否能夠正常訪問。例如:
- 公司官網(wǎng)、后臺(tái)管理系統(tǒng)是否在線
- 多個(gè)接口地址是否返回正常狀態(tài)碼
- 批量檢測客戶提供的網(wǎng)址是否有效
- 監(jiān)控服務(wù)是否超時(shí)、拒絕連接或 DNS 解析失敗
- 爬蟲任務(wù)開始前,先過濾掉不可訪問的網(wǎng)址
如果一個(gè)一個(gè)用瀏覽器打開,不僅效率低,而且很難記錄結(jié)果。使用 Python 的 requests 庫,就可以把這個(gè)過程自動(dòng)化。
本文會(huì)用一個(gè)完整案例演示:如何用 Python + requests 批量檢測網(wǎng)站是否可訪問,并輸出成功或失敗結(jié)果。內(nèi)容適合 Python 初學(xué)者學(xué)習(xí),也適合想提升工作效率的小伙伴直接改造使用。
一、requests 庫介紹
requests 是 Python 中非常常用的 HTTP 請求庫,可以用來發(fā)送 GET、POST 等請求。相比 Python 標(biāo)準(zhǔn)庫里的 urllib,requests 的寫法更簡潔,更適合初學(xué)者。
它常用于:
- 調(diào)用 Web API
- 請求網(wǎng)頁內(nèi)容
- 提交表單數(shù)據(jù)
- 設(shè)置請求頭、Cookie、代理
- 下載文件
- 檢測網(wǎng)站狀態(tài)
- 編寫簡單爬蟲或接口測試腳本
一句話理解:requests 可以讓 Python 像瀏覽器一樣訪問網(wǎng)站或接口。
二、安裝 requests
在命令行執(zhí)行:
pip install requests
如果你的電腦上有多個(gè) Python 版本,建議使用:
python -m pip install requests
安裝完成后,可以在 Python 中測試:
import requests print(requests.__version__)
如果能正常打印版本號(hào),說明安裝成功。
三、發(fā)送 GET 請求
GET 請求通常用于獲取頁面內(nèi)容或查詢接口數(shù)據(jù)。
import requests url = "https://www.baidu.com" response = requests.get(url) print(response.status_code) print(response.text[:200])
常見狀態(tài)碼含義:
| 狀態(tài)碼 | 含義 |
|---|---|
| 200 | 請求成功 |
| 301 / 302 | 重定向 |
| 400 | 請求參數(shù)錯(cuò)誤 |
| 401 / 403 | 未授權(quán)或禁止訪問 |
| 404 | 頁面不存在 |
| 500 | 服務(wù)器內(nèi)部錯(cuò)誤 |
| 502 / 503 / 504 | 網(wǎng)關(guān)或服務(wù)不可用 |
檢測網(wǎng)站是否可訪問時(shí),通常會(huì)把 200 到 399 之間的狀態(tài)碼視為成功,因?yàn)?301、302 這類重定向也說明網(wǎng)站本身是能響應(yīng)的。
四、發(fā)送 POST 請求
POST 請求通常用于提交數(shù)據(jù),比如登錄、表單提交、創(chuàng)建訂單、調(diào)用接口等。
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 數(shù)據(jù),可以這樣寫:
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)
區(qū)別是:
data=更像提交普通表單json=會(huì)自動(dòng)把字典轉(zhuǎn)成 JSON,并設(shè)置對應(yīng)的請求格式
五、設(shè)置超時(shí)時(shí)間
寫請求代碼時(shí),一定建議設(shè)置超時(shí)時(shí)間。
如果不設(shè)置超時(shí),某個(gè)網(wǎng)站一直沒有響應(yīng),程序可能會(huì)卡很久,影響整個(gè)批量檢測流程。
import requests url = "https://www.baidu.com" response = requests.get(url, timeout=5) print(response.status_code)
timeout=5 表示最多等待 5 秒。如果超過 5 秒還沒有響應(yīng),就會(huì)拋出超時(shí)異常。
也可以把連接超時(shí)和讀取超時(shí)分開設(shè)置:
response = requests.get(url, timeout=(3, 5))
含義是:
- 連接服務(wù)器最多等待 3 秒
- 服務(wù)器返回?cái)?shù)據(jù)最多等待 5 秒
六、設(shè)置請求頭 User-Agent
有些網(wǎng)站會(huì)根據(jù)請求頭判斷訪問來源。如果沒有設(shè)置 User-Agent,服務(wù)器可能認(rèn)為這是一個(gè)腳本請求,從而拒絕訪問。
可以模擬常見瀏覽器請求頭:
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)
實(shí)際項(xiàng)目中,設(shè)置 User-Agent 是一個(gè)很常見的習(xí)慣。
七、批量檢測網(wǎng)址狀態(tài)碼
下面進(jìn)入實(shí)戰(zhàn):批量檢測多個(gè)網(wǎng)站是否可訪問。
我們希望程序能夠做到:
- 依次請求多個(gè) URL
- 設(shè)置 User-Agent
- 設(shè)置超時(shí)時(shí)間
- 輸出狀態(tài)碼
- 判斷成功或失敗
- 捕獲常見異常
- 最后統(tǒng)計(jì)成功和失敗數(shù)量
八、完整可運(yùn)行代碼
新建文件 requests_website_checker.py,復(fù)制下面代碼運(yùn)行。
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:
"""判斷狀態(tài)碼是否代表網(wǎng)站可訪問。"""
return 200 <= status_code < 400
def check_url(url: str, timeout: int = 5) -> CheckResult:
"""檢測單個(gè)網(wǎng)址是否可訪問。"""
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"狀態(tài)碼異常:{response.status_code}",
elapsed_ms=elapsed_ms,
)
except Timeout:
return CheckResult(url, False, None, "請求超時(shí)", None)
except ConnectionError:
return CheckResult(url, False, None, "連接失敗,可能是域名錯(cuò)誤或服務(wù)器不可達(dá)", None)
except SSLError:
return CheckResult(url, False, None, "SSL 證書錯(cuò)誤", None)
except InvalidURL:
return CheckResult(url, False, None, "URL 格式不正確", None)
except HTTPError as exc:
return CheckResult(url, False, None, f"HTTP 錯(cuò)誤:{exc}", None)
except RequestException as exc:
return CheckResult(url, False, None, f"請求異常:{exc}", None)
def print_result(result: CheckResult) -> None:
"""格式化輸出檢測結(jié)果。"""
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"狀態(tài)碼:{status_code} | "
f"耗時(shí):{elapsed} | "
f"說明:{result.message}"
)
def main() -> None:
results = []
print("開始批量檢測網(wǎng)站狀態(tài)...\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"總數(shù)量:{len(results)}")
print(f"成功數(shù)量:{success_count}")
print(f"失敗數(shù)量:{fail_count}")
if __name__ == "__main__":
main()
運(yùn)行命令:
python requests_website_checker.py
可能輸出類似下面這樣:
開始批量檢測網(wǎng)站狀態(tài)... [成功] https://www.baidu.com | 狀態(tài)碼:200 | 耗時(shí):122.35ms | 說明:訪問成功 [成功] https://www.csdn.net | 狀態(tài)碼:200 | 耗時(shí):358.41ms | 說明:訪問成功 [成功] https://www.python.org | 狀態(tài)碼:200 | 耗時(shí):489.73ms | 說明:訪問成功 [失敗] https://httpbin.org/status/404 | 狀態(tài)碼:404 | 耗時(shí):280.15ms | 說明:狀態(tài)碼異常:404 [失敗] https://this-domain-does-not-exist-123456.com | 狀態(tài)碼:- | 耗時(shí):- | 說明:連接失敗,可能是域名錯(cuò)誤或服務(wù)器不可達(dá) 檢測完成 總數(shù)量:5 成功數(shù)量:3 失敗數(shù)量:2
不同網(wǎng)絡(luò)環(huán)境下,狀態(tài)碼和耗時(shí)可能不完全一樣,這是正?,F(xiàn)象。
九、代碼重點(diǎn)講解
1. 為什么使用 dataclass 保存結(jié)果
@dataclass
class CheckResult:
url: str
success: bool
status_code: Optional[int]
message: str
elapsed_ms: Optional[float]
dataclass 可以讓結(jié)果結(jié)構(gòu)更清晰。每個(gè)網(wǎng)址的檢測結(jié)果都包含:
- 網(wǎng)址
- 是否成功
- 狀態(tài)碼
- 錯(cuò)誤說明
- 請求耗時(shí)
后續(xù)如果想保存到 Excel、CSV 或數(shù)據(jù)庫,也更容易擴(kuò)展。
2. 為什么 200 到 399 算成功
def is_success_status(status_code: int) -> bool:
return 200 <= status_code < 400
通常:
2xx表示請求成功3xx表示重定向4xx表示客戶端請求有問題5xx表示服務(wù)器異常
網(wǎng)站檢測場景下,如果返回 301 或 302,說明服務(wù)器有響應(yīng),只是跳轉(zhuǎn)到了另一個(gè)地址,所以一般也可以視為可訪問。
3. 為什么要設(shè)置 allow_redirects=True
requests.get(url, allow_redirects=True)
很多網(wǎng)站會(huì)從 http 跳轉(zhuǎn)到 https,或者從不帶 www 跳轉(zhuǎn)到帶 www 的域名。開啟重定向后,requests 會(huì)自動(dòng)跟隨跳轉(zhuǎn)。
4. 為什么要記錄 elapsed_ms
elapsed_ms = round(response.elapsed.total_seconds() * 1000, 2)
狀態(tài)碼只能說明是否響應(yīng),耗時(shí)可以幫助判斷網(wǎng)站是否慢。
例如:
- 200ms:訪問很快
- 2s:偏慢
- 5s 以上:用戶體驗(yàn)較差
- 超時(shí):可能服務(wù)不可用或網(wǎng)絡(luò)不穩(wěn)定
十、常見異常處理
批量檢測網(wǎng)站時(shí),異常處理非常重要。因?yàn)橹灰粋€(gè)網(wǎng)址出錯(cuò),就讓整個(gè)程序停止,顯然不適合批量任務(wù)。
1. Timeout 請求超時(shí)
except Timeout:
return CheckResult(url, False, None, "請求超時(shí)", None)
常見原因:
- 網(wǎng)站響應(yīng)太慢
- 網(wǎng)絡(luò)不穩(wěn)定
- 服務(wù)器沒有及時(shí)返回
解決建議:
- 設(shè)置合理超時(shí)時(shí)間
- 對重要網(wǎng)址增加重試機(jī)制
- 記錄日志,后續(xù)人工排查
2. ConnectionError 連接失敗
except ConnectionError:
return CheckResult(url, False, None, "連接失敗,可能是域名錯(cuò)誤或服務(wù)器不可達(dá)", None)
常見原因:
- 域名寫錯(cuò)
- DNS 解析失敗
- 服務(wù)器關(guān)閉
- 本地網(wǎng)絡(luò)無法訪問目標(biāo)地址
3. SSLError 證書錯(cuò)誤
except SSLError:
return CheckResult(url, False, None, "SSL 證書錯(cuò)誤", None)
常見原因:
- HTTPS 證書過期
- 證書鏈不完整
- 目標(biāo)站點(diǎn)證書配置錯(cuò)誤
不建議隨便使用 verify=False 跳過證書校驗(yàn),除非你非常明確是在內(nèi)網(wǎng)測試環(huán)境。
4. InvalidURL 地址格式錯(cuò)誤
except InvalidURL:
return CheckResult(url, False, None, "URL 格式不正確", None)
例如:
www.baidu.com htp://example.com
建議批量檢測前統(tǒng)一檢查 URL 是否包含 http:// 或 https://。
5. RequestException 兜底異常
except RequestException as exc:
return CheckResult(url, False, None, f"請求異常:{exc}", None)
RequestException 是 requests 異常的基類,可以作為最后的兜底處理,避免程序因?yàn)槲搭A(yù)料的請求問題直接崩潰。
十一、擴(kuò)展:從文件讀取網(wǎng)址
真實(shí)工作中,網(wǎng)址可能不是寫死在代碼里,而是放在文本文件中。
可以新建 urls.txt:
https://www.baidu.com https://www.csdn.net https://www.python.org
然后這樣讀?。?/p>
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("#")
]
這樣就可以讓非技術(shù)同事只維護(hù) urls.txt,腳本負(fù)責(zé)自動(dòng)檢測。
十二、使用場景分析
這個(gè)腳本可以應(yīng)用在很多實(shí)際場景中。
1. 運(yùn)維巡檢
每天上班前自動(dòng)檢測公司官網(wǎng)、后臺(tái)系統(tǒng)、接口網(wǎng)關(guān)、報(bào)表系統(tǒng)是否可訪問,提前發(fā)現(xiàn)服務(wù)異常。
2. 測試環(huán)境冒煙檢查
部署完成后,先批量請求幾個(gè)關(guān)鍵接口。如果狀態(tài)碼異常,就不必繼續(xù)進(jìn)行后續(xù)測試。
3. 爬蟲任務(wù)預(yù)檢查
爬蟲開始前先檢測目標(biāo)網(wǎng)址是否可訪問,過濾掉 404、超時(shí)、連接失敗的網(wǎng)址,減少無效請求。
4. 客戶網(wǎng)址批量核驗(yàn)
如果有一批客戶官網(wǎng)、供應(yīng)商鏈接或資料鏈接,可以批量檢測哪些還能訪問,哪些已經(jīng)失效。
5. 接口健康檢查
雖然專業(yè)系統(tǒng)會(huì)使用 Prometheus、Zabbix、Uptime Kuma 等監(jiān)控工具,但對于初學(xué)者或輕量任務(wù),一個(gè) Python 腳本已經(jīng)能解決不少問題。
十三、可以繼續(xù)優(yōu)化的方向
掌握本文代碼后,還可以繼續(xù)擴(kuò)展:
- 把檢測結(jié)果保存到 CSV 或 Excel
- 使用多線程提高檢測速度
- 加入失敗重試機(jī)制
- 定時(shí)執(zhí)行腳本
- 將失敗結(jié)果發(fā)送到郵箱、企業(yè)微信或釘釘
- 支持從配置文件讀取 URL、超時(shí)時(shí)間、請求頭
- 對接口返回內(nèi)容做關(guān)鍵字校驗(yàn)
例如,一個(gè)頁面雖然返回 200,但如果返回的是錯(cuò)誤頁,也可能不算真正可用。這時(shí)就可以繼續(xù)檢查響應(yīng)內(nèi)容中是否包含指定關(guān)鍵字。
十四、總結(jié)
本文從 requests 的基礎(chǔ)用法講起,演示了 GET 請求、POST 請求、超時(shí)設(shè)置、User-Agent 請求頭設(shè)置,并通過一個(gè)完整腳本實(shí)現(xiàn)了批量檢測網(wǎng)站是否可訪問。
對于 Python 初學(xué)者來說,這個(gè)案例非常適合練習(xí):
- HTTP 請求基礎(chǔ)
- 狀態(tài)碼判斷
- 異常處理
- 函數(shù)封裝
- 批量任務(wù)處理
- 控制臺(tái)結(jié)果輸出
把重復(fù)性工作交給腳本,是 Python 提升辦公和開發(fā)效率的典型用法。你可以直接把本文代碼改造成自己的網(wǎng)址檢測工具,用在日常巡檢、接口測試和數(shù)據(jù)采集預(yù)檢查中。
以上就是利用Python+requests批量檢測網(wǎng)站是否可訪問的實(shí)戰(zhàn)指南的詳細(xì)內(nèi)容,更多關(guān)于Python requests檢測網(wǎng)站是否可訪問的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實(shí)現(xiàn)二次元圖片展示(屏保)
這篇文章主要介紹了python實(shí)現(xiàn)二次元圖片展示,用了API端口相關(guān)的知識(shí)實(shí)現(xiàn),下面詳細(xì)的文章內(nèi)容需要的小伙伴可以參考一下2022-02-02
Python正則表達(dá)式匹配數(shù)字和小數(shù)的方法
這篇文章主要介紹了Python正則匹配數(shù)字和小數(shù)的方法,本文通過示例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07

