一、教程目标
本教程实现以下功能:
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下载网页资源内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论