Blog-Building

从CSDN迁移博客到Hexo+Next+GitHub Pages

本指南专为「从CSDN导出博客,部署到Hexo+Next主题GitHub Pages」的用户设计,全面解决:

  • CSDN导出图片不显示问题
  • Hexo配置错误导致部署失败
  • 路径解析和缓存冲突
  • GitHub Pages部署疑难杂症
  • 博客结构混乱、功能缺失、体验不佳

一、环境准备与项目初始化

1.1 必备环境安装

1
2
3
4
5
6
7
8
9
10
# 安装Node.js(必需v14+,推荐v18+)
# 官网下载:https://nodejs.org/

# 安装Git
# 官网下载:https://git-scm.com/

# 验证安装
node --version
npm --version
git --version

1.2 GitHub仓库准备

  • 创建一个名为 你的用户名.github.io 的仓库(必须是此格式)。
  • 推荐:配置SSH密钥以实现免密推送。
    1
    2
    ssh-keygen -t rsa -C "your_email@example.com"
    # 将 ~/.ssh/id_rsa.pub 内容添加到 GitHub 的 SSH Keys 设置中

1.3 Hexo项目初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 安装Hexo命令行工具
npm install -g hexo-cli

# 创建博客项目
hexo init myBlog
cd myBlog

# 安装Next主题
npm install hexo-theme-next --save

# 安装部署插件
npm install hexo-deployer-git --save

# 安装搜索插件(用于本地搜索)
npm install hexo-generator-searchdb --save

# 安装站点地图插件(用于SEO)
npm install hexo-generator-sitemap --save
npm install hexo-generator-baidu-sitemap --save # 可选,百度专用

二、核心配置文件详解

2.1 Hexo主配置文件 (_config.yml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Site
title: ZQ-Rookie-Hacker的技术博客
subtitle: '分享编程、网络安全、工具使用技巧'
description: '专注于Hexo博客搭建、前端开发、网络安全的技术分享平台'
keywords: ['Hexo', '博客搭建', '网络安全', 'SSH', '编程技巧']
author: ZQ-Rookie-Hacker
language: zh-CN
timezone: 'Asia/Shanghai'

# URL
url: https://你的用户名.github.io
root: /
permalink: :year/:month/:day/:title/
permalink_defaults:

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories

# Writing
new_post_name: :title.md
default_layout: post
titlecase: false
external_link:
enable: true
field: site
exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: true # 🔑 关键:启用文章资源文件夹(每篇文章一个文件夹存放图片)
relative_link: false # 🔑 关键:禁用相对链接,确保路径正确
future: true

# Markdown配置(解决图片核心问题)
syntax_highlighter: highlight.js
highlight:
line_number: true
auto_detect: false
tab_replace: ''
wrap: true
hljs: false

marked:
prepend_root: true # 🔑 关键:自动为相对路径添加根路径
post_asset: true # 🔑 关键:识别文章资源文件夹中的图片

prismjs:
preprocess: true
line_number: true
tab_replace: ''

# 关闭缓存避免路径问题
cache:
enable: false

# Extensions
theme: next

# Deployment
deploy:
type: git
repo: git@github.com:你的用户名/你的用户名.github.io.git
branch: main

2.2 Next主题配置 (themes/next/_config.yml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# Scheme Settings (推荐简洁大气的Gemini或Mist)
scheme: Gemini
# scheme: Mist
# scheme: Pisces
# scheme: Muse

# Dark Mode
darkmode: false

# Menu Settings
menu:
home: / || fa fa-home
categories: /categories/ || fa fa-folder # 新增:分类页
tags: /tags/ || fa fa-tags # 新增:标签页
archives: /archives/ || fa fa-archive
about: /about/ || fa fa-user # 可选:需先创建about页

# Sidebar Settings
sidebar:
position: left
display: post

# Post Settings
excerpt_description: true
read_more_btn: true

# 图片懒加载(提升加载速度)
lazyload:
enable: true

# 代码高亮优化
codeblock:
copy_button:
enable: true

# 本地搜索
local_search:
enable: true
placeholder: 搜索文章...

# 阅读量统计(不蒜子)
busuanzi_count:
enable: true
total_visitors: true
total_views: true
post_views: true
archive_views: true

# 评论系统(推荐Gitalk)
gitalk:
enable: true
client_id: 你的Client ID
client_secret: 你的Client Secret
repo: blog-comments # 用于存储评论的GitHub仓库名
owner: 你的GitHub用户名
admin: [你的GitHub用户名]
distraction_free_mode: false
language: zh-CN

# SEO
seo: true

三、CSDN图片处理终极方案

3.1 自动化图片下载与修复脚本 (fix_csdn_images.py)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import os
import re
import requests
from urllib.parse import urlparse
import time

# ====== 你只需要改这一行:你的文章放哪儿? ======
POSTS_DIR = r"F:\myBlog\source\_posts" # 修改为你的实际路径
# ================================================

# 支持的图片格式
IMG_EXTENSIONS = ('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp')

def download_image(url, save_path):
"""下载单张图片"""
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
res = requests.get(url, headers=headers, timeout=15)
res.raise_for_status()
with open(save_path, 'wb') as f:
f.write(res.content)
return True
except Exception as e:
print(f"❌ 下载失败:{url},错误:{e}")
return False

def process_markdown_file(file_path):
"""处理单个Markdown文件"""
article_name = os.path.splitext(os.path.basename(file_path))[0]
image_dir = os.path.join(os.path.dirname(file_path), article_name)
os.makedirs(image_dir, exist_ok=True)

with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()

# 查找所有CSDN网络图片链接
img_pattern = r'!\[([^\]]*)\]\((https?://[^\s)]+\.(?:png|jpg|jpeg|gif|bmp|webp))\)'
matches = list(re.finditer(img_pattern, content))

print(f"🔍 找到 {len(matches)} 张图片")

success_count = 0
for i, match in enumerate(matches):
alt_text = match.group(1) or '图片描述'
url = match.group(2)

print(f"⬇️ 正在下载 ({i+1}/{len(matches)}): {os.path.basename(url)} ")

# 生成图片文件名
parsed = urlparse(url)
ext = os.path.splitext(parsed.path)[1].lower()
if not ext or ext not in IMG_EXTENSIONS:
ext = '.png'

# 清理文件名中的特殊字符
clean_alt = re.sub(r'[^\w\u4e00-\u9fa5-]', '_', alt_text)
filename_on_disk = f"{clean_alt}_{i+1}{ext}" if clean_alt else f"image_{i+1}{ext}"

local_path = os.path.join(image_dir, filename_on_disk)

if download_image(url, local_path):
# 使用标准Markdown语法,引用本地文件
new_link = f"![{alt_text}]({filename_on_disk})"
content = content.replace(match.group(0), new_link)
success_count += 1
print(f"✅ 已保存:{filename_on_disk} ")

# 保存修改后的内容
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)

return success_count, len(matches)

def main():
print("🚀 开始处理CSDN导出的图片...")
total_success = 0
total_images = 0

for filename in os.listdir(POSTS_DIR):
if not filename.endswith('.md'):
continue

blog_path = os.path.join(POSTS_DIR, filename)
print(f"\n📄 正在处理:{filename}")

success, total = process_markdown_file(blog_path)
total_success += success
total_images += total

print(f"🎉 {filename} 处理完成:{success}/{total} 张图片成功")

print(f"\n🎊 全部完成!总计处理 {total_success}/{total_images} 张图片")
print("\n📝 接下来执行:")
print(" hexo clean && hexo generate && hexo server")

if __name__ == "__main__":
main()

3.2 使用说明

  1. 修改路径:将脚本中的 POSTS_DIR 修改为你博客文章的实际路径(如 F:\myBlog\source\_posts)。
  2. 运行脚本:在命令行中进入脚本所在目录,执行 python fix_csdn_images.py
  3. 验证结构:脚本执行后,你的文章目录结构应变为:
    1
    2
    3
    4
    5
    6
    source/_posts/
    ├── SSH隧道技术.md
    └── SSH隧道技术/
    ├── 图片描述_1.png
    ├── 图片描述_2.jpg
    └── ...
  4. 本地预览:执行 hexo clean && hexo generate && hexo server,在浏览器中访问 http://localhost:4000,确认图片已正常加载。

四、核心:搭建清晰的「分类/标签」体系(解决文章归类问题)

分类是博客的“骨架”,标签是“索引”,两者结合让读者快速找到内容,也让你的博客结构更规整。

4.1 先明确规则(避免混乱)

  • 分类:层级化、不重复(例如:技术网络安全工具Hexo配置)。一篇文章建议1-2个主分类。
  • 标签:扁平化、多维度(例如:一篇「Hexo分类配置」的文章,标签可设 Hexo博客搭建分类管理)。一篇文章可多个标签。

4.2 步骤1:创建「分类页」「标签页」(让导航能访问)
Hexo需要手动创建分类/标签的“容器页面”,否则导航栏点击后会404:

1
2
3
4
5
# 创建分类页面
hexo new page "categories"

# 创建标签页面
hexo new page "tags"

然后分别编辑这两个文件的 Front-matter,添加 type 标识:

  • source/categories/index.md
    1
    2
    3
    4
    5
    ---
    title: 分类
    date: 2025-11-11
    type: "categories"
    ---
  • source/tags/index.md
    1
    2
    3
    4
    5
    ---
    title: 标签
    date: 2025-11-11
    type: "tags"
    ---

4.3 步骤2:给文章分配「分类/标签」
编辑每篇文章(source/_posts/xxx.md)的 Front-matter:

1
2
3
4
5
6
7
8
9
10
11
12
---
title: "什么是SSH隧道及相关技术"
date: 2025-11-10
updated: 2025-11-11
categories:
- 技术
- 网络安全
tags:
- SSH
- 隧道技术
- 服务器
---

4.4 步骤3:让分类/标签显示在导航栏
themes/next/_config.ymlmenu 配置中,添加 categoriestags 菜单项(已在上文2.2节中包含)。


二、优化导航与功能:让博客更好用

1. 开启「搜索功能」(必备!)
已在 themes/next/_config.yml 中配置 local_search,确保已安装 hexo-generator-searchdb 插件。

2. 代码高亮优化(程序员必备)
已在 themes/next/_config.yml 中配置 codeblock.copy_button,并在 hexo/_config.yml 中启用了 highlight.line_number

3. 图片处理:避免失效+优化显示

  • 方案1:本地图片(推荐):通过 post_asset_folder: true + marked.post_asset: true 配置,脚本已自动将图片存入文章同名文件夹,使用 ![描述](图片名.png) 的相对路径,永不失效
  • 方案2:图床:若需多设备编辑,可用PicGo上传至GitHub图床,复制链接粘贴。但强烈推荐方案1,数据完全可控。
  • 优化显示:在Markdown中,使用以下代码让图片居中并限制宽度:
    1
    2
    <!-- 居中+限制宽度 -->
    <img src="图片链接" alt="描述" style="display: block; margin: 0 auto; max-width: 80%;">

五、外观优化:让博客更个性化

5.1 选择Next主题风格(Scheme)
themes/next/_config.yml 中设置:

1
2
3
4
scheme: Gemini  # 推荐:简洁大气,适配分类/标签
# scheme: Mist # 更紧凑
# scheme: Pisces # 卡片式
# scheme: Muse # 默认

5.2 自定义颜色/字体
编辑 themes/next/source/css/_custom/custom.styl 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 自定义导航栏背景色
.header {
background: #2c3e50;
}

// 自定义链接颜色
a {
color: #3498db;
&:hover {
color: #e74c3c;
}
}

// 全局字体(推荐思源黑体)
body {
font-family: "Source Han Sans CN", "PingFang SC", "Microsoft YaHei", sans-serif;
}

// 代码字体(推荐Fira Code)
code, pre {
font-family: "Fira Code", "Consolas", monospace;
}

// 页面背景图(可选)
body {
background-image: url('/images/bg.jpg');
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
background-color: rgba(255, 255, 255, 0.9);
background-blend-mode: overlay;
}

注意:将背景图 bg.jpg 放入 source/images/ 目录下。

5.3 添加背景图/头像

  • 头像:在 themes/next/_config.yml 中设置:
    1
    2
    3
    4
    avatar:
    url: /images/avatar.jpg # 图片放在 source/images/ 目录下
    rounded: true
    opacity: 1.0
  • 背景图:已在上文 custom.styl 中配置。

六、增强互动与体验:添加评论/阅读量

6.1 评论系统(推荐 Gitalk,适配 GitHub Pages)
已在 themes/next/_config.yml 中配置 gitalk,请按说明申请GitHub OAuth App并填入 client_idclient_secret

2. 阅读量统计(不蒜子,无需注册)
已在 themes/next/_config.yml 中启用 busuanzi_count


七、SEO优化:让博客被搜索引擎收录

7.1 配置站点信息(Hexo根目录 _config.yml
已在上文2.1节中包含 title, subtitle, description, keywords, author, language, timezone

7.2 生成站点地图
已在上文1.3节安装了 hexo-generator-sitemaphexo-generator-baidu-sitemap 插件。无需额外配置,它们会自动生成 sitemap.xmlbaidu_sitemap.xml

7.3 提交站点到搜索引擎

  • Google 搜索控制台:添加你的域名,提交 https://你的博客地址/sitemap.xml
  • 百度搜索资源平台:添加你的域名,提交 https://你的博客地址/baidu_sitemap.xml

八、细节优化:提升质感

8.1 文章排版

  • 折叠块(适合长代码/补充说明):
    1
    2
    3
    4
    <details>
    <summary>点击查看补充说明</summary>
    这里是折叠的内容...
    </details>
  • 每篇文章添加「前言/小结」,让结构更清晰。

8.2 404 页面
创建 source/404.md

1
2
3
4
5
6
7
8
9
---
title: 页面不存在
date: 2025-11-11
---
<div style="text-align: center; margin-top: 50px;">
<h1>404 - 页面走丢啦~</h1>
<p>你访问的页面不存在或已被移动</p>
<a href="/" style="color: #3498db; font-size: 18px;">返回首页</a>
</div>

8.3 关闭无用功能
themes/next/_config.yml 中关闭不需要的功能:

1
2
3
4
reward:
enable: false
sharejs:
enable: false

九、部署与备份**

9.1 部署流程
每次修改后,执行以下命令部署:

1
hexo clean && hexo generate && hexo deploy

9.2 本地测试
在部署前,务必先在本地测试:

1
2
3
hexo clean
hexo generate --debug
hexo server

访问 http://localhost:4000,检查:

  • ✅ 文章正常显示
  • ✅ 图片正确加载
  • ✅ 样式正常
  • ✅ 搜索、分类、标签功能正常

9.3 备份
将 Hexo 根目录的 _config.ymlthemes/next/_config.ymlsource/ 目录(文章+图片)备份到 GitHub(新建一个仓库,比如 blog-source),避免电脑故障丢失数据。


十、故障排除大全

10.1 图片不显示问题

  • 症状:图片显示为空白或404。
  • 解决方案
    1. 检查配置:确保 _config.ymlpost_asset_folder: truemarked.prepend_root: true 已开启。
    2. 清理缓存:执行 hexo clean 后重新 hexo generate
    3. 检查路径:浏览器F12查看Network标签,确认图片请求的URL是 文章名/图片名.png 的相对路径。

10.2 部署失败问题

  • 常见错误1:权限拒绝
    • 解决方案:使用HTTPS地址或配置SSH密钥。
    1
    2
    3
    4
    deploy:
    type: git
    repo: https://github.com/用户名/你的用户名.github.io.git
    branch: main
  • 常见错误2:分支不存在
    • 解决方案:确认你的GitHub仓库默认分支是 main 还是 gh-pages,并相应修改 branch 配置。

10.3 主题显示异常

  • 解决方案
    1. 确认主题安装:npm list hexo-theme-next
    2. 检查 hexo/_config.ymltheme: next
    3. 清理重新安装:rm -rf node_modules && npm install

10.4 时间显示问题

  • 症状:文章时间相差8小时。
  • 解决方案:确保 hexo/_config.ymltimezone: 'Asia/Shanghai'

十一、优化与进阶

11.1 性能优化

  • themes/next/_config.yml 中启用 lazyload: enable: true
  • hexo/_config.yml 中启用 highlight.line_number: true

11.2 自定义域名

  • source/ 目录下创建一个名为 CNAME 的文件。
  • 文件内容写入你的域名,例如:yourdomain.com
  • 在你的域名DNS服务商处,添加一条CNAME记录,指向 你的用户名.github.io

十二、实用命令速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建新文章
hexo new "文章标题"

# 本地写作(预览草稿)
hexo server --draft

# 仅生成静态文件
hexo generate

# 强制清理缓存
hexo clean --debug

# 查看Hexo版本
hexo version

# 一键部署(最常用)
hexo clean && hexo generate && hexo deploy

十三、博客协作更新

13.1 拉取myBlog + 配置git

  • git clone git@github.com:用户名/myBlog.git
  • git init (初始化刚拉取的myBlog)
  • git remote add origin git@github.com:用户名/myBlog.git (关联仓库)

13.2 下载nodejs + hexo

  • 官网下载nodejs
  • 下载 hexo npm install -g hexo-cli

13.3 nmp 相关插件下载

  • npm install
  • npm install hexo-deployer-git –save

因为 myBlog 已经hexo 初始化完毕,不需要再进行初始化
myBlog 私仓用于博客协作更新(用git), 用hexo deploy 更新博客仓

注意:每次修改文章或其他文件时,hexo clean -> hexo g -> hexo deploy -> git add . -> git commit …. -> git push origin main