你是否厌倦了复杂的博客平台?是否希望用最简洁的方式管理自己的文章?Markdown 是程序员最爱的轻量级标记语言,而静态博客生成器(如 Jekyll、Hugo)早已证明了其高效与优雅。但如果你只想用几行 Python 代码快速实现一个属于自己的本地博客生成器,本文将手把手教你完成!
我们将构建一个极简但功能完整的工具:
- 将
posts/目录下的.md文件转换为 HTML - 自动生成首页(列出所有文章)
- 支持基础模板(header/footer)
整个项目不到 100 行代码,却能让你理解静态博客的核心原理。
准备工作
确保你已安装 Python 3.7+,并安装以下依赖:
pip install markdown
我们将使用 Python 内置的 os、glob、datetime 模块,以及第三方库 markdown 来解析 Markdown。
项目结构
创建如下目录结构:
my_blog_generator/
├── posts/
│ ├── hello-world.md
│ └── python-tutorial.md
├── templates/
│ ├── base.html
│ └── index.html
├── output/
└── generate.py
示例文章(posts/hello-world.md)
# Hello World!
这是我的第一篇博客。
发布于:2026-02-14
模板文件(templates/base.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
<style>
body { font-family: sans-serif; line-height: 1.6; max-width: 800px; margin: 40px auto; padding: 0 20px; }
h1 { color: #333; }
.meta { color: #777; font-size: 0.9em; margin-bottom: 20px; }
</style>
</head>
<body>
<h1>{{ title }}</h1>
<div class="meta">{{ meta }}</div>
{{ content }}
</body>
</html>
编写生成脚本(generate.py)
import os
import glob
import markdown
from datetime import datetime
POSTS_DIR = "posts"
OUTPUT_DIR = "output"
TEMPLATE_DIR = "templates"
os.makedirs(OUTPUT_DIR, exist_ok=True)
def read_template(name):
with open(os.path.join(TEMPLATE_DIR, name), "r", encoding="utf-8") as f:
return f.read()
def parse_markdown(filepath):
with open(filepath, "r", encoding="utf-8") as f:
lines = f.readlines()
# 简单提取标题和元信息(假设第一行为 # 标题,最后一行为“发布于:YYYY-MM-DD”)
title_line = lines[0].strip()
if title_line.startswith("# "):
title = title_line[2:]
else:
title = os.path.basename(filepath).replace(".md", "")
meta_line = ""
content_lines = lines[1:]
if lines[-1].startswith("发布于:"):
meta_line = lines[-1].strip()
content_lines = lines[1:-1]
md_content = "".join(content_lines)
html_content = markdown.markdown(md_content)
return title, meta_line, html_content
def generate_post(filepath):
title, meta, content = parse_markdown(filepath)
template = read_template("base.html")
html = template.replace("{{ title }}", title) \
.replace("{{ meta }}", meta) \
.replace("{{ content }}", content)
output_path = os.path.join(OUTPUT_DIR, os.path.basename(filepath).replace(".md", ".html"))
with open(output_path, "w", encoding="utf-8") as f:
f.write(html)
print(f"✅ 生成文章: {output_path}")
return {"title": title, "meta": meta, "filename": os.path.basename(output_path)}
def generate_index(posts_info):
index_template = read_template("index.html")
items = []
for post in sorted(posts_info, key=lambda x: x["meta"], reverse=True):
date = post["meta"].replace("发布于:", "")
items.append(f'<li><a href="{post["filename"]}">{post["title"]}</a> <span>({date})</span></li>')
list_html = "\n".join(items)
index_html = index_template.replace("{{ post_list }}", list_html)
with open(os.path.join(OUTPUT_DIR, "index.html"), "w", encoding="utf-8") as f:
f.write(index_html)
print("✅ 生成首页: output/index.html")
# templates/index.html 内容
index_template_content = """<!DOCTYPE html>
<html>
<head><title>我的博客</title></head>
<body>
<h1>文章列表</h1>
<ul>{{ post_list }}</ul>
</body>
</html>
"""
# 如果 index.html 模板不存在,自动创建
if not os.path.exists(os.path.join(TEMPLATE_DIR, "index.html")):
os.makedirs(TEMPLATE_DIR, exist_ok=True)
with open(os.path.join(TEMPLATE_DIR, "index.html"), "w", encoding="utf-8") as f:
f.write(index_template_content)
# 主流程
if __name__ == "__main__":
posts = glob.glob(os.path.join(POSTS_DIR, "*.md"))
if not posts:
print("⚠️ posts/ 目录下没有 .md 文件")
else:
all_posts = []
for post in posts:
info = generate_post(post)
all_posts.append(info)
generate_index(all_posts)
运行生成器
在终端执行:
python generate.py
输出目录 output/ 中将包含所有 HTML 文件,包括 index.html。你可以用浏览器直接打开 output/index.html 查看效果,或使用 Python 快速启动本地服务器:
cd output
python -m http.server 8000
然后访问 http://localhost:8000。
扩展建议
这个基础版本已经能用,但你可以继续增强它:
- 支持 YAML front matter(如 Jekyll 风格)
- 添加 RSS 订阅
- 集成代码高亮(使用
markdown.extensions.codehilite) - 自动监听文件变化并重新生成(用
watchdog库)
结语
通过几十行 Python 代码,我们实现了一个可工作的静态博客生成器。这不仅加深了对 Markdown 和 HTML 转换的理解,也让你拥有了完全可控的内容发布流程。更重要的是——你的博客,你做主。
快去 posts/ 目录下写一篇新文章,运行脚本,看看效果吧!