You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python requests.get保存网页时未下载关联图片的问题咨询

为什么原代码保存的页面会出现图片失效

原逻辑仅抓取了主HTML文档的内容,没有处理HTML内部嵌套引用的图片、CSS等外部资源:这些资源的原始路径都是指向线上服务器的,当你把HTML存到本地后,相对路径找不到对应文件,自然就会出现裂链效果。要实现和浏览器右键「另存为-完整网页」等价的效果,需要补全三个核心动作:

  • 解析HTML内的所有外部资源引用
  • 批量下载对应资源到本地目录
  • 将HTML内的资源引用路径替换为本地相对路径,保证本地打开时能正常加载
改造后的完整实现

前置依赖安装

需要搭配轻量的HTML解析库处理资源路径识别,安装命令:
pip install requests beautifulsoup4 lxml

适配原有爬取逻辑的代码替换

原代码存在两处基础问题:一是文件关闭方法close()漏写括号会触发语法报错;二是完全缺失资源下载和路径替换的逻辑。改造后的逻辑完全复用你原本的遍历链接、请求页面的流程,补充全量资源存储能力:

  • 为每个爬取的HTML页面单独创建同名资源目录,和浏览器的存储逻辑保持一致
  • 自动识别HTML中所有<img>、<link>、<script>标签内的资源引用
  • 自动跳过内嵌data:协议的资源,避免无效请求
  • 已下载过的资源自动跳过,减少重复请求
  • 路径拼接自动适配相对路径、绝对路径的场景,不会出现路径错位
import os
import time
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse

# 定义通用资源下载函数
def download_asset(asset_url, save_dir):
    parsed_url = urlparse(asset_url)
    file_name = os.path.basename(parsed_url.path)
    # 跳过无有效文件名的空路径资源
    if not file_name:
        return
    save_path = os.path.join(save_dir, file_name)
    # 已下载的资源直接跳过,避免重复请求
    if os.path.exists(save_path):
        return save_path
    # 发起请求下载资源
    res = requests.get(asset_url)
    res.raise_for_status()
    with open(save_path, 'wb') as f:
        f.write(res.content)
    return save_path

base_url = "http://aosabook.org/en/"
for link in aosa1:
    page_url = urljoin(base_url, link)
    # 请求主HTML页面
    res = requests.get(page_url)
    print(res.status_code)
    print(len(res.text))
    res.raise_for_status()
    # 处理页面存储命名
    page_name = link.split("/")[-1]
    if not page_name.endswith(".html"):
        page_name += ".html"
    # 创建当前页面对应的资源存储目录
    asset_dir = f"{os.path.splitext(page_name)[0]}_assets"
    os.makedirs(asset_dir, exist_ok=True)
    # 解析HTML内容
    soup = BeautifulSoup(res.text, "lxml")
    # 处理所有带src属性的标签(图片、脚本等)
    for tag in soup.find_all(src=True):
        src_path = tag["src"]
        if src_path.startswith("data:"):
            continue
        asset_abs_url = urljoin(page_url, src_path)
        local_path = download_asset(asset_abs_url, asset_dir)
        if local_path:
            tag["src"] = local_path
    # 处理所有带href属性的标签(样式表、图标等)
    for tag in soup.find_all(href=True):
        href_path = tag["href"]
        if href_path.startswith("data:"):
            continue
        # 仅下载媒体类资源,跳过外站跳转链接
        if not any(ext in href_path for ext in [".css", ".png", ".jpg", ".jpeg", ".gif", ".ico"]):
            continue
        asset_abs_url = urljoin(page_url, href_path)
        local_path = download_asset(asset_abs_url, asset_dir)
        if local_path:
            tag["href"] = local_path
    # 保存处理完成的HTML文件
    with open(page_name, "wb") as f:
        f.write(soup.prettify("utf-8"))
    # 加延时避免给目标服务器造成过大压力
    time.sleep(1)

注意事项

  • 所有文件写入采用with上下文管理器,避免文件句柄泄漏、写入内容不完整的问题
  • 该逻辑完全匹配浏览器「另存为完整网页」的效果,本地打开保存的HTML时可以正常加载所有图片、样式资源,不会出现裂链
  • 如果遇到跨域的资源路径,只需要在download_asset函数中补全对应域的请求头配置即可正常下载

内容的提问来源于stack exchange,提问作者Fomorian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 07:57:00