一:通过github镜像网站访问github
github镜像站点1:https://bgithub.xyz
github镜像站点2:https://ggithub.xyz

二、针对仓库经常容易被墙,写个脚本批量检测代码层仓可不可达

#!/usr/bin/env python3
"""批量检测网址连通性(HTTP 请求 + TCP 回退)"""

import socket
import ssl
import sys
import time
import urllib.request
import urllib.error
from urllib.parse import urlparse
from concurrent.futures import ThreadPoolExecutor, as_completed

# 硬编码网址列表(直接在这里添加)
URLS = [
    "https://hub.fastgit.xyz/",
    "https://hub.fastgit.org/",
    "https://cdn.githubjs.cf/",
    "https://gitclone.com/",
    "https://www.github.do/",
    "https://ghproxy.com/",
    "https://github.com/",
    "https://bgithub.xyz",
    "https://ggithub.xyz", 
]

# 超时(秒)
TIMEOUT = 4
# 并发数
CONCURRENCY = 64
# 重试次数(仅对疑似抖动的错误重试)
RETRY = 1

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"
}

# 忽略 SSL 证书校验,避免证书问题导致误判
_SSL_CTX = ssl.create_default_context()
_SSL_CTX.check_hostname = False
_SSL_CTX.verify_mode = ssl.CERT_NONE


def http_check(url):
    """先 HEAD/GET 快速验证,失败则回退 TCP 探测"""
    raw = url.strip()
    if not raw.startswith(("http://", "https://")):
        raw = "http://" + raw

    last_err = None
    for attempt in range(RETRY + 1):
        try:
            start = time.time()
            # 用 HEAD 更快,不下载 body
            req = urllib.request.Request(raw, headers=HEADERS, method="HEAD")
            with urllib.request.urlopen(req, timeout=TIMEOUT, context=_SSL_CTX) as resp:
                elapsed = (time.time() - start) * 1000
                code = resp.status
                if 200 <= code < 400:
                    return url, True, f"{code} {elapsed:.0f}ms"
                return url, False, f"HTTP {code}"
        except urllib.error.HTTPError as e:
            # 4xx/5xx 都说明服务器活着,端口通,视为可达
            elapsed = (time.time() - start) * 1000
            if 400 <= e.code < 600:
                return url, True, f"HTTP {e.code}(可达) {elapsed:.0f}ms"
            last_err = f"HTTP {e.code}"
            break  # HTTP 错误无需重试
        except urllib.error.URLError as e:
            last_err = str(e.reason)
            # DNS 失败不重试
            if "Name or service not known" in last_err or "nodename" in last_err:
                break
        except socket.timeout:
            last_err = "超时"
        except Exception as e:
            last_err = type(e).__name__
            break

    # HTTP 全部失败 -> TCP 端口探测(更短超时)
    parsed = urlparse(raw)
    host = parsed.hostname
    port = parsed.port or (443 if parsed.scheme == "https" else 80)
    if host:
        try:
            start = time.time()
            with socket.create_connection((host, port), timeout=2):
                elapsed = (time.time() - start) * 1000
                return url, False, f"TCP通但HTTP失败({last_err}) {elapsed:.0f}ms"
        except Exception:
            pass
    return url, False, last_err or "不可达"


def main(urls):
    print(f"\n{'URL':<50} {'状态':<8} {'延迟/错误'}")
    print("-" * 80)
    ok, fail = 0, 0
    results = []

    with ThreadPoolExecutor(max_workers=CONCURRENCY) as executor:
        futures = {executor.submit(http_check, url): url for url in urls if url.strip()}
        for future in as_completed(futures):
            results.append(future.result())

    # 按原始顺序排序
    order = {url.strip(): i for i, url in enumerate(urls)}
    results.sort(key=lambda r: order.get(r[0].strip(), 999))

    for url, success, info in results:
        if success:
            print(f"\033[32m{url:<50} {'OK':<8} {info}\033[0m")
            ok += 1
        else:
            print(f"\033[31m{url:<50} {'FAIL':<8} {info}\033[0m")
            fail += 1
    print(f"\n总计: {ok + fail} | ✓ {ok} | ✗ {fail}")

if __name__ == "__main__":
    if URLS:
        urls = URLS
    elif len(sys.argv) > 1:
        arg = sys.argv[1]
        try:
            with open(arg) as f:
                urls = f.read().splitlines()
        except FileNotFoundError:
            urls = sys.argv[1:]
    else:
        print("输入网址(每行一个,空行结束):")
        urls = []
        while True:
            line = input()
            if not line:
                break
            urls.append(line)

    main(urls)

三、项目解释

批量网址连通性检测工具

使用 HTTP 请求 + TCP 回退的方式多线程并发检测大量网址是否真正可访问,纯 Python 标准库实现,零依赖。

原理

  1. urllib 发起真实 HTTP GET 请求并读取响应,确认网页确实可达
  2. 支持重试(默认 2 次),应对偶发抖动
  3. HTTP 失败时回退到 TCP 端口探测,区分"完全不通"和"端口通但服务异常"
  4. HTTP 4xx 也视为可达(服务器在响应)
  5. 忽略 SSL 证书校验,避免证书问题误判

比单纯 ping 或 TCP 探测更可靠(有些服务器端口开着但网页已挂)。

使用方式

方式一:硬编码网址列表

直接编辑 check_urls.py 中的 URLS 列表:

URLS = [
    "https://www.google.com",
    "https://github.com",
    "https://example.com",
]

然后运行:

python check_urls.py

方式二:从文件读取

准备一个文本文件,每行一个网址:

https://www.google.com
https://github.com
https://example.com

运行:

python check_urls.py urls.txt

方式三:命令行直接传入

python check_urls.py https://google.com https://github.com https://example.com

方式四:交互式输入

python check_urls.py

每行输入一个网址,输入空行结束。

注意:如果 URLS 列表非空,会优先使用硬编码列表,忽略其他输入方式。

配置项

在脚本顶部可调整:

参数默认值说明
TIMEOUT4单个请求超时时间(秒)
CONCURRENCY64最大并发线程数
RETRY1失败重试次数(DNS/HTTP错误不重试)

输出示例

URL                                                状态     延迟/错误
--------------------------------------------------------------------------------
https://example.com                                OK       200 234ms
https://some-site.com/missing                      OK       HTTP 404(可达)
https://broken.com                                 FAIL     TCP通但HTTP失败(超时) 80ms
https://unreachable.invalid                        FAIL     DNS解析失败

总计: 4 | ✓ 2 | ✗ 2

绿色 = 可通(2xx/3xx),红色 = 不通。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐