当前位置:首页>python>用python实现下载yifile的文件

用python实现下载yifile的文件

  • 2026-10-11 08:15:02
用python实现下载yifile的文件
经常从yifile上下载一些别的博主分享的文件,但最近发现换了下载方式,我用的火狐浏览器,经常出现无法下载,或是下载了无法打开。
研究了一下,发现是加密了,用AI写了一个pyton的下载加解密的小工具。分享给大家,有用得上的就拿去用。
import hashlibimport timeimport requestsimport sysfrom urllib.parse import parse_qs, urlparseCHUNK_SIZE = 50 * 1024 * 1024def sha256_bytes(data: bytes) -> bytes:    return hashlib.sha256(data).digest()def parse_yifile_link(full_link: str):    # 修复:兼容被CMD截断的链接,手动提取#后面的所有内容    if "#" in full_link:        hash_part = full_link.split("#", 1)[1]    else:        hash_part = full_link    # 处理带&的参数,parse_qs会自动处理    params = parse_qs(hash_part, keep_blank_values=True)    url = params.get("url", [None])[0]    k = params.get("k", [None])[0]    name = params.get("name", ["download.7z"])[0]    # 额外兼容:如果url里也带了&,手动提取    if url and "&" in url:        url = url.split("&")[0]    return url, k, namedef format_size(b):    for u in ["B", "KB", "MB", "GB", "TB"]:        if b < 1024:            return f"{b:.2f}{u}"        b /= 1024    return f"{b:.2f} TB"def format_eta(seconds):    if seconds <= 0:        return "00:00:00"    hours = int(seconds // 3600)    minutes = int((seconds % 3600) // 60)    secs = int(seconds % 60)    return f"{hours:02d}:{minutes:02d}:{secs:02d}"def aes_ctr_decrypt(cipher_data: bytes, key: bytes, counter: bytes):    from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes    from cryptography.hazmat.backends import default_backend    backend = default_backend()    cipher = Cipher(algorithms.AES(key), modes.CTR(counter), backend=backend)    decryptor = cipher.decryptor()    return decryptor.update(cipher_data) + decryptor.finalize()def download_and_decrypt(full_link: str):    down_url, pass_key, file_name = parse_yifile_link(full_link)    print("🔍 解析结果:")    print(f"源文件地址:{down_url}")    print(f"解密密钥:{pass_key}")    print(f"输出文件名:{file_name}\n")    if not down_url or not pass_key:        print("❌ 错误:未能解析出 url 或 k 密钥")        return    key_bytes = sha256_bytes(f"PWD|{pass_key}".encode("utf-8"))    base_ctr = sha256_bytes(f"CTR|{pass_key}".encode("utf-8"))[:16]    try:        resp = requests.get(down_url, stream=True, timeout=20)        resp.raise_for_status()    except Exception as e:        print(f"❌ 下载请求失败:{e}")        return    total_size = int(resp.headers.get("Content-Length", 0))    downloaded = 0    last_time = time.time()    last_down = 0    chunk_buf = b""    chunk_idx = 0    print(f"📁 文件总大小:{format_size(total_size)}\n")    print("⏬ 开始下载并解密,实时进度如下:\n")    with open(file_name, "wb") as f_out:        for data in resp.iter_content(chunk_size=1024*1024):            if not data:                continue            chunk_buf += data            downloaded += len(data)            now = time.time()            if now - last_time >= 1.0:                speed = (downloaded - last_down) / (now - last_time)                last_down = downloaded                last_time = now                progress = (downloaded / total_size * 100) if total_size else 0                remaining_bytes = total_size - downloaded                eta = remaining_bytes / speed if speed > 0 else 0                eta_str = format_eta(eta)                print(                    f"\r进度:{progress:.1f}% | "                    f"已下载:{format_size(downloaded)} / {format_size(total_size)} | "                    f"速度:{format_size(speed)}/s | "                    f"剩余:{eta_str}",                    end="", flush=True                )            while len(chunk_buf) >= CHUNK_SIZE:                block = chunk_buf[:CHUNK_SIZE]                chunk_buf = chunk_buf[CHUNK_SIZE:]                ctr = bytearray(base_ctr)                ctr[12] = (chunk_idx >> 24) & 0xFF                ctr[13] = (chunk_idx >> 16) & 0xFF                ctr[14] = (chunk_idx >> 8) & 0xFF                ctr[15] = chunk_idx & 0xFF                plain = aes_ctr_decrypt(block, key_bytes, bytes(ctr))                f_out.write(plain)                chunk_idx += 1        if chunk_buf:            ctr = bytearray(base_ctr)            ctr[12] = (chunk_idx >> 24) & 0xFF            ctr[13] = (chunk_idx >> 16) & 0xFF            ctr[14] = (chunk_idx >> 8) & 0xFF            ctr[15] = chunk_idx & 0xFF            plain = aes_ctr_decrypt(chunk_buf, key_bytes, bytes(ctr))            f_out.write(plain)    print("\n\n✅ 下载 + 解密全部完成!")    print(f"✅ 已保存为:{file_name}")if __name__ == "__main__":    if len(sys.argv) >= 2:        link = sys.argv[1].strip()    else:        print("请粘贴完整的下载链接,然后按回车:")        link = input().strip()    download_and_decrypt(link)
用上的直接复制到一个py文件里就可以了。我是复制到yf.py里了
调用方法:
直接运行python yf.py后会出现粘贴地址
粘贴第一张图里的所有地址,是所有了不要漏了,很长的那个
这个地址。粘贴完后按回车。就可以开始下载了。
另外一种调用方式就是
python yf.py "https://***连接地址"
会出现上面的下载。已经测试过可以正常下载。
快来试试吧。今天2026年5月8日测试可行,明天以及以后我就不知道了。

最新文章

随机文章