Python实现下载网页并将资源改为本地相对路径

 更新时间:2026年01月03日 08:48:28   作者:weixin_46244623  
这篇文章主要为大家详细介绍了如何使用Python轻松实现下载网页并将资源改为本地相对路径,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

一、教程目标

本教程实现以下功能:

1、下载指定 URL 的 HTML 页面

2、自动下载页面中引用的:

  • CSS 文件
  • JS 文件
  • 图片(img)

3、解析 CSS 文件中的:

  • 背景图片(url(…))
  • 字体文件(@font-face)

4、将 HTML 和 CSS 中的外链资源全部修改为本地相对路径

5、最终生成一个可离线访问的网页目录

适合用于:

  • 网页备份
  • 离线浏览
  • 页面模板保存
  • 简单静态站点克隆

二、环境准备

1. Python 版本

建议使用 Python 3.7 及以上版本

2. 安装依赖库

pip install requests beautifulsoup4

三、完整代码(中文注释版)

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


def download_file(url, folder):
    """
    下载单个文件并保存到指定目录
    :param url: 文件的绝对 URL
    :param folder: 保存目录
    """
    response = requests.get(url)
    if response.status_code == 200:
        # 从 URL 中解析出文件名
        filename = os.path.basename(urlparse(url).path)
        save_path = os.path.join(folder, filename)

        # 以二进制方式写入文件
        with open(save_path, 'wb') as f:
            f.write(response.content)


def download_and_modify_links(html_url, save_folder, domain_to_remove):
    """
    下载 HTML 页面,并将其中的 CSS、JS、IMG 等资源下载到本地,
    同时把所有链接修改为相对路径
    :param html_url: 目标网页 URL
    :param save_folder: 本地保存目录
    :param domain_to_remove: 预留参数(当前版本未使用)
    """

    response = requests.get(html_url)
    if response.status_code != 200:
        print(f"页面下载失败,状态码:{response.status_code}")
        return

    # 使用 BeautifulSoup 解析 HTML
    soup = BeautifulSoup(response.text, 'html.parser')

    # 创建保存资源的目录
    os.makedirs(save_folder, exist_ok=True)

    # 处理 link、img、script 标签
    # link -> CSS
    # img  -> 图片
    # script -> JS
    for tag, attribute in [('link', 'href'), ('img', 'src'), ('script', 'src')]:
        elements = soup.find_all(tag, {attribute: True})
        for element in elements:
            original_link = element[attribute]

            # 将相对路径转换为绝对路径
            absolute_link = urljoin(html_url, original_link)

            # 提取文件名
            filename = os.path.basename(urlparse(absolute_link).path)
            if not filename:
                continue

            # 修改 HTML 中的引用为相对路径
            element[attribute] = f"./{filename}"

            # 下载资源文件
            download_file(absolute_link, save_folder)

    # 单独处理 CSS 文件,解析其中的图片和字体
    css_elements = soup.find_all('link', {'rel': 'stylesheet'})
    for css_element in css_elements:
        css_url = urljoin(html_url, css_element['href'])
        css_response = requests.get(css_url)

        if css_response.status_code != 200:
            continue

        css_text = css_response.text

        # 处理 CSS 中的 url(...) 图片
        image_urls = re.findall(r'url\((.*?)\)', css_text)
        for image_url in image_urls:
            clean_url = image_url.strip('\'"')
            absolute_image_url = urljoin(css_url, clean_url)

            filename = os.path.basename(urlparse(absolute_image_url).path)
            if not filename:
                continue

            # 替换 CSS 中的路径为本地相对路径
            css_text = css_text.replace(image_url, f"./{filename}")

            # 下载图片
            download_file(absolute_image_url, save_folder)

        # 处理 @font-face 中的字体文件
        font_urls = re.findall(r'@font-face.*?url\((.*?)\)', css_text, re.S)
        for font_url in font_urls:
            clean_url = font_url.strip('\'"')
            absolute_font_url = urljoin(css_url, clean_url)

            filename = os.path.basename(urlparse(absolute_font_url).path)
            if not filename:
                continue

            css_text = css_text.replace(font_url, f"./{filename}")
            download_file(absolute_font_url, save_folder)

        # 保存修改后的 CSS 文件
        css_filename = os.path.basename(urlparse(css_url).path)
        css_save_path = os.path.join(save_folder, css_filename)

        with open(css_save_path, 'w', encoding='utf-8') as f:
            f.write(css_text)

        # 修改 HTML 中的 CSS 引用路径
        css_element['href'] = f"./{css_filename}"

    # 保存最终修改后的 HTML 文件
    html_save_path = os.path.join(save_folder, 'index.html')
    with open(html_save_path, 'w', encoding='utf-8') as f:
        f.write(str(soup))

    print("HTML 页面及相关资源已成功下载并本地化")

四、主程序入口示例

if __name__ == "__main__":
    html_url = "http://example.com/"
    save_folder = "downloaded_files"
    domain_to_remove = "http://example.com"

    download_and_modify_links(html_url, save_folder, domain_to_remove)

五、运行结果目录结构示例

downloaded_files/
├── index.html

打开 index.html 即可离线访问网页。

到此这篇关于Python实现下载网页并将资源改为本地相对路径的文章就介绍到这了,更多相关Python下载网页资源内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入浅析Python 中 is 语法带来的误解

    深入浅析Python 中 is 语法带来的误解

    这篇文章主要介绍了Python 中 is 语法带来的误解,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • Python中切片操作符的具体使用

    Python中切片操作符的具体使用

    Python切片操作用于提取序列(如列表、字符串)的子集,支持正负索引和步长,返回浅拷贝新对象,切片操作通常用于列表、元组、字符串等,下面就具体来了解一下
    2025-07-07
  • Python访问本地deepseek示例【含deepseek本地部署】

    Python访问本地deepseek示例【含deepseek本地部署】

    这篇文章主要介绍了Python访问本地deepseek功能,结合实例形式分析了使用Ollama本地部署deepseek以及python访问本地deepseek的过程,需要的朋友可以参考下
    2018-06-06
  • 快速上手基于Anaconda搭建Django环境的教程

    快速上手基于Anaconda搭建Django环境的教程

    Django具有完整的封装,开发者可以高效率的开发项目,Django将大部分的功能进行了封装,开发者只需要调用即可,接下来通过本文给大家介绍基于Anaconda搭建Django环境的教程,需要的朋友可以参考下
    2021-10-10
  • 教你使用Python建立任意层数的深度神经网络

    教你使用Python建立任意层数的深度神经网络

    这篇文章主要介绍了Python建立任意层数的深度神经网络,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • Python如何获取多线程返回结果

    Python如何获取多线程返回结果

    这篇文章主要介绍了Python如何获取多线程返回结果,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Python实现图像手绘效果的方法详解

    Python实现图像手绘效果的方法详解

    这篇文章主要为大家详细介绍了如何利用Python语言实现图像手绘效果,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2022-09-09
  • nginx黑名单和django限速,最简单的防恶意请求方法分享

    nginx黑名单和django限速,最简单的防恶意请求方法分享

    今天小编就为大家分享一篇nginx黑名单和django限速,最简单的防恶意请求方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • 对python当中不在本路径的py文件的引用详解

    对python当中不在本路径的py文件的引用详解

    今天小编就为大家分享一篇对python当中不在本路径的py文件的引用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python使用百度通用API进行翻译实现

    Python使用百度通用API进行翻译实现

    本文主要介绍了Python使用百度通用API进行翻译实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02

最新评论