Python 快速克隆网站并保存到本地

下面是完整的 Python 脚本和详细说明:

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
import os
import shutil
import re

def get_valid_filename(url):
    """
    从URL生成有效的本地文件名。
    替换掉文件名中不允许的字符。
    """
    # 提取域名和路径部分用于构造文件名
    parsed_url = urlparse(url)
    # 组合网络位置和路径,替换非字母数字字符为下划线
    filename = parsed_url.netloc + parsed_url.path
    # 确保文件名以.html结尾,且不含无效字符
    if not filename.endswith('.html'):
        if filename.endswith('/'):
            filename += 'index.html'
        else:
            filename += '.html'
    # 使用正则表达式替换无效字符
    filename = re.sub(r'[^a-zA-Z0-9_.-]', '_', filename)
    return filename

def download_resource(url, save_dir):
    """
    下载单个资源(如图片、CSS、JS文件)并保存到指定目录。
    """
    try:
        response = requests.get(url, stream=True, timeout=10)
        response.raise_for_status()  # 检查请求是否成功
        # 从URL中提取有效的文件名
        file_name = os.path.basename(urlparse(url).path)
        if not file_name:  # 如果URL以斜杠结尾,没有文件名部分
            file_name = 'index.html'
        # 确保保存目录存在
        os.makedirs(save_dir, exist_ok=True)
        file_path = os.path.join(save_dir, file_name)
        
        # 写入文件
        with open(file_path, 'wb') as f:
            # 对于大文件,使用流式下载
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)
        print(f"下载成功: {url} -> {file_path}")
        return file_path
    except Exception as e:
        print(f"下载资源 {url} 时出错: {e}")
        return None

def clone_website(base_url, output_dir="cloned_site"):
    """
    克隆指定URL的网站内容到本地目录。
    
    参数:
        base_url (str): 要克隆的网站URL
        output_dir (str): 保存克隆内容的本地目录
    """
    # 获取主页面HTML内容
    try:
        response = requests.get(base_url)
        response.raise_for_status()
        html_content = response.text
    except Exception as e:
        print(f"获取 {base_url} 内容失败: {e}")
        return

    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    
    # 解析HTML内容
    soup = BeautifulSoup(html_content, 'html.parser')
    
    # 查找需要下载的资源 (CSS, JS, 图片)
    resource_tags = soup.find_all(['link', 'script', 'img'])
    resources_to_download = []
    
    for tag in resource_tags:
        url = None
        if tag.name == 'link' and tag.get('rel') == ['stylesheet']:  # CSS文件
            url = tag.get('href')
            attr_name = 'href'
        elif tag.name == 'script' and tag.get('src'):  # JS文件
            url = tag.get('src')
            attr_name = 'src'
        elif tag.name == 'img' and tag.get('src'):  # 图片
            url = tag.get('src')
            attr_name = 'src'
        
        if url:
            # 将相对URL转换为绝对URL
            full_url = urljoin(base_url, url)
            resources_to_download.append((full_url, tag, attr_name))
    
    # 下载所有资源文件并更新HTML中的链接为本地路径
    for resource_url, tag, attr_name in resources_to_download:
        local_path = download_resource(resource_url, output_dir)
        if local_path:
            # 更新标签中的链接为本地文件名
            tag[attr_name] = os.path.basename(local_path)
    
    # 保存主HTML文件
    main_filename = get_valid_filename(base_url)
    main_filepath = os.path.join(output_dir, main_filename)
    with open(main_filepath, 'w', encoding='utf-8') as f:
        f.write(str(soup))
    print(f"主页面已保存: {main_filepath}")
    
    print(f"克隆完成!网站内容已保存到目录: {output_dir}")

if __name__ == "__main__":
    # 用户输入要克隆的网站URL
    target_url = input("请输入要克隆的网站URL (包括 http:// 或 https://): ").strip()
    
    # 指定输出目录
    output_directory = input("请输入保存克隆网站的目录名称 (默认为 'cloned_site'): ").strip()
    if not output_directory:
        output_directory = "cloned_site"
    
    # 开始克隆
    clone_website(target_url, output_directory)

如何使用这个脚本

  1. 安装必要的库:在运行脚本前,确保已安装 requestsbeautifulsoup4。可以通过以下命令安装:

    pip install requests beautifulsoup4
  2. 运行脚本:将上面的代码保存为一个 .py 文件(例如 website_cloner.py),然后在终端或命令行中运行:

    python website_cloner.py
  3. 输入信息:根据提示输入你想克隆的完整网址(包括 http:// https://)和本地保存的目录名称(直接回车则使用默认的 cloned_site 目录)。

脚本功能说明

  • 下载网页内容:脚本会获取目标 URL 的 HTML 内容。

  • 解析并处理资源链接:使用 BeautifulSoup 解析 HTML,找出其中的 CSS、JavaScript 和图片等资源的链接。

  • 下载资源:将这些资源的绝对地址下载到本地目录。

  • 更新本地 HTML 链接:将 HTML 中的资源链接替换为本地路径,以便离线浏览时能正确加载。

  • 保存网页:最后将修改后的 HTML 保存为本地文件。

重要注意事项

  • 合法性与道德规范仅克隆你有权访问或所有者允许克隆的网站。未经授权克隆网站可能违反法律或网站的使用条款。

  • 尊重 robots.txt:理想情况下,爬虫应遵守网站的 robots.txt 文件,但此脚本未内置该功能。

  • 动态内容限制:此脚本主要针对静态内容。对于高度依赖 JavaScript 渲染内容的动态网站(如很多现代 Web 应用),克隆效果可能不完整,可能需要使用 SeleniumPlaywright 等浏览器自动化工具。

  • 错误处理:脚本包含基本错误处理,但网络请求总有各种意外,可能需要根据实际情况调整。

更多选择

工具 / 库名称

主要特点

适用场景

注意事项

wget (命令行)

功能强大,支持递归下载、镜像整个站点

快速下载整个网站用于离线浏览

需要学习命令行参数

PyWebCopy

Python 库,支持保存 CSS、JS、图像等资源,能重新映射链接

网页归档、数据备份

Website-Cloner

Python 脚本,可复制网站所有内容(包括图片、样式表等)到本地

创建本地网站副本

可能无法处理复杂或动态网站

SiteScraper

用于道德黑客的 Python 程序,可克隆 HTML, CSS, JS, PHP

仅限教育用途,且必须获得明确授权

未经授权使用可能导致法律问题


Python 快速克隆网站并保存到本地
https://uniomo.com/archives/python-kuai-su-ke-long-wang-zhan-bing-bao-cun-dao-ben-di
作者
雨落秋垣
发布于
2025年03月20日
许可协议