本文目录导读:

我来详细介绍几种用脚本批量生成静态网站的方法,从简单到复杂:
使用静态网站生成器(推荐)
Hugo (Go语言)
#!/bin/bash
# 批量生成Hugo网站
# 创建多个站点
for site_name in site1 site2 site3; do
hugo new site $site_name
cd $site_name
# 添加主题
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke
echo 'theme = "ananke"' >> config.toml
# 生成内容
hugo new content posts/first-post.md
echo "---" > content/posts/first-post.md
echo "title: 'Welcome to $site_name'" >> content/posts/first-post.md
echo "date: $(date +'%Y-%m-%d')" >> content/posts/first-post.md
echo "---" >> content/posts/first-post.md
echo "This is $site_name." >> content/posts/first-post.md
# 构建
hugo
cd ..
done
Python + Pelican
#!/usr/bin/env python3
import os
import shutil
# Pelican生成脚本
sites = [
{"name": "blog1", "title": "Tech Blog"},
{"name": "blog2", "title": "Personal Site"},
{"name": "blog3", "title": "Project Docs"}
]
for site in sites:
os.makedirs(f"{site['name']}/content", exist_ok=True)
os.makedirs(f"{site['name']}/output", exist_ok=True)
# 创建配置文件
with open(f"{site['name']}/pelicanconf.py", "w") as f:
f.write(f"""
SITENAME = '{site['title']}'
SITEURL = 'https://example.com/{site['name']}'
PATH = 'content'
OUTPUT_PATH = 'output'
TIMEZONE = 'Asia/Shanghai'
DEFAULT_LANG = 'zh'
""")
# 创建文章
article = f"""Title: Welcome
Date: {os.popen('date +%Y-%m-%d').read().strip()}
Category: General
Welcome to {site['title']}!
"""
with open(f"{site['name']}/content/welcome.md", "w") as f:
f.write(article)
# 生成静态网站
os.system(f"cd {site['name']} && pelican content")
Node.js + Eleventy (11ty)
#!/usr/bin/env node
const fs = require('fs');
const { execSync } = require('child_process');
const sites = ['docs', 'blog', 'portfolio'];
sites.forEach(site => {
// 创建目录结构
fs.mkdirSync(`./${site}/src`, { recursive: true });
fs.mkdirSync(`./${site}/_site`, { recursive: true });
// 创建Eleventy配置
const config = `
module.exports = function(eleventyConfig) {
return {
dir: {
input: "src",
output: "_site"
}
};
};
`;
fs.writeFileSync(`./${site}/.eleventy.js`, config);
// 创建模板
fs.writeFileSync(`./${site}/src/index.njk`, `---
layout: base.njk ${site}
---
<h1>Welcome to ${site}</h1>
`);
// 创建布局
fs.mkdirSync(`./${site}/src/_includes`, { recursive: true });
fs.writeFileSync(`./${site}/src/_includes/base.njk`, `
<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body>
<main>{{ content | safe }}</main>
</body>
</html>
`);
// 构建
execSync(`cd ${site} && npx @11ty/eleventy`);
});
使用Python直接生成HTML
简单模板渲染
#!/usr/bin/env python3
import os
from string import Template
# HTML模板
HTML_TEMPLATE = Template("""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">${title}</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>${title}</h1>
<nav>
<a href="/">首页</a>
<a href="/about.html">lt;/a>
<a href="/blog.html">博客</a>
</nav>
</header>
<main>
<h2>欢迎来到 ${title}</h2>
<p>${content}</p>
<p>更新时间: ${date}</p>
</main>
<footer>
<p>© ${year} ${title}</p>
</footer>
</body>
</html>
""")
# 站点数据
sites = [
{
"title": "技术博客",
"content": "分享编程知识和经验",
"pages": ["index", "about", "blog"]
},
{
"title": "个人网站",
"content": "展示个人作品和想法",
"pages": ["index", "about", "projects"]
}
]
for site in sites:
# 创建文件夹
dir_name = site["title"].replace(" ", "_")
os.makedirs(f"./output/{dir_name}", exist_ok=True)
# 生成页面
for page in site["pages"]:
html_content = HTML_TEMPLATE.safe_substitute(
title=f"{page.capitalize()} - {site['title']}",
content=f"{page.capitalize()} page content for {site['title']}",
date=os.popen('date +%Y-%m-%d').read().strip(),
year=os.popen('date +%Y').read().strip()
)
with open(f"./output/{dir_name}/{page}.html", "w", encoding="utf-8") as f:
f.write(html_content)
# 创建CSS
css_content = """
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
header { border-bottom: 2px solid #333; padding-bottom: 10px; }
nav a { margin-right: 15px; color: #0066cc; text-decoration: none; }
footer { border-top: 1px solid #ccc; padding-top: 10px; margin-top: 20px; }
"""
with open(f"./output/{dir_name}/style.css", "w") as f:
f.write(css_content)
print("网站批量生成完成!")
Shell脚本批量处理
基于已有模板
#!/bin/bash
# 批量生成类似结构的网站
TEMPLATE_DIR="./template"
SITES=("site-a" "site-b" "site-c")
for site in "${SITES[@]}"; do
# 复制模板
cp -r "$TEMPLATE_DIR" "./$site"
# 替换占位符
find "./${site}" -type f -exec sed -i "s/{{SITE_NAME}}/${site}/g" {} \;
# 自定义内容
echo "<p>Welcome to $site</p>" > "./$site/index.html"
# 生成sitemap
echo "https://example.com/$site" >> "./sitemap.txt"
echo "Generated: $site"
done
使用Makefile自动化
# Makefile for batch site generation
SITES = site1 site2 site3
HTML = index.html about.html contact.html
all: $(foreach site,$(SITES),gen-$(site))
gen-%:
@echo "Generating $*..."
@mkdir -p $*/public
@for page in $(HTML); do \
echo "<html><body><h1>Welcome to $*</h1><p>$$page</p></body></html>" > $*/public/$$page; \
done
@echo "✓ $* generated"
clean:
@rm -rf $(SITES)
.PHONY: all clean
推荐的工具和工作流程
完整示例:Python批量生成器
#!/usr/bin/env python3
"""
批量静态网站生成器
支持自定义模板、内容、配置
"""
import os
import json
import shutil
from datetime import datetime
from jinja2 import Environment, FileSystemLoader
class SiteGenerator:
def __init__(self, template_dir="templates"):
self.env = Environment(loader=FileSystemLoader(template_dir))
self.output_dir = "output"
def generate_site(self, site_config):
"""生成单个站点"""
site_name = site_config["name"]
site_dir = os.path.join(self.output_dir, site_name)
os.makedirs(site_dir, exist_ok=True)
# 生成页面
for page in site_config.get("pages", []):
template = self.env.get_template(f"{page['template']}.html")
html = template.render(
title=page.get("title", site_name),
content=page.get("content", ""),
date=datetime.now().strftime("%Y-%m-%d"),
site_name=site_name
)
with open(os.path.join(site_dir, f"{page['name']}.html"), "w") as f:
f.write(html)
# 复制静态资源
if os.path.exists("static"):
for item in os.listdir("static"):
src = os.path.join("static", item)
dst = os.path.join(site_dir, item)
if os.path.isfile(src):
shutil.copy2(src, dst)
else:
shutil.copytree(src, dst)
return site_dir
def batch_generate(self, config_file="sites.json"):
"""批量生成所有站点"""
with open(config_file, "r") as f:
sites_config = json.load(f)
for site in sites_config:
result = self.generate_site(site)
print(f"Generated: {result}")
# 使用示例
if __name__ == "__main__":
generator = SiteGenerator()
generator.batch_generate()
sites.json配置示例
[
{
"name": "tech-blog",
"pages": [
{
"name": "index",
"template": "default",
"title": "技术博客",
"content": "分享编程知识"
},
{
"name": "about",
"template": "default",
"title": "关于我",
"content": "全栈开发者"
}
]
},
{
"name": "photo-gallery",
"pages": [
{
"name": "index",
"template": "gallery",
"title": "摄影作品",
"content": "展示摄影作品"
}
]
}
]
推荐工具选择
| 工具 | 适合场景 | 学习曲线 | 性能 |
|---|---|---|---|
| Hugo | 大型文档站、博客 | 中等 | 极快 |
| Eleventy | 灵活的项目 | 中等 | 快 |
| Pelican | Python开发者 | 低 | 中等 |
| 手写Python | 完全自定义 | 中等 | 中等 |
最佳实践
- 使用模板引擎:Jinja2 (Python)、Nunjucks (Node.js)
- 分离配置和内容:使用JSON/YAML配置,Markdown内容
- 增量构建:只重新生成修改过的页面
- 缓存处理:对静态资源添加哈希
- 并行构建:使用多进程加速
选择哪种方法取决于你的具体需求、技术栈和网站规模,对于简单需求,直接使用SSG工具;对于复杂自定义场景,使用脚本生成更灵活。