使用 Python 快速搭建一个本地 Markdown 博客生成器

2026-02-11 689 0

你是否厌倦了复杂的博客平台?是否希望用最简洁的方式管理自己的文章?Markdown 是程序员最爱的轻量级标记语言,而静态博客生成器(如 Jekyll、Hugo)早已证明了其高效与优雅。但如果你只想用几行 Python 代码快速实现一个属于自己的本地博客生成器,本文将手把手教你完成!

我们将构建一个极简但功能完整的工具:

  • posts/ 目录下的 .md 文件转换为 HTML
  • 自动生成首页(列出所有文章)
  • 支持基础模板(header/footer)

整个项目不到 100 行代码,却能让你理解静态博客的核心原理。

准备工作

确保你已安装 Python 3.7+,并安装以下依赖:

pip install markdown

我们将使用 Python 内置的 osglobdatetime 模块,以及第三方库 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/ 目录下写一篇新文章,运行脚本,看看效果吧!

相关文章

PNG/JPG在线转换WebP:原理、实现与前端源码详解
实现智能深色/浅色模式(Dark Mode)的终极指南:自动适配系统偏好 + 手动切换 + 本地持久化
一行命令搭建临时文件服务器:5 种语言实现的本地文件共享方案(Python/Node.js/Go/Rust/PHP)
开源挂机页:毫秒级北京时间 + 动态星空 + 情绪字幕
好看的404界面并且5秒后跳转指定界面
现代 Web 安全中常被忽视但至关重要的主题:前端如何安全处理敏感数据

发布评论