1. 为什么要把CSDN博客迁移到Hexo?
作为一个在CSDN写了8年技术博客的老鸟,我去年终于下定决心把全部内容迁移到Hexo静态博客系统。这个决定不是一时冲动,而是经历了无数次"被删文"、"被限流"、"被强制插入广告"后的必然选择。CSDN作为国内老牌技术社区,确实给早期技术分享者提供了不错的平台,但随着商业化程度加深,创作者体验每况愈下。
最让我无法忍受的是三件事:一是后台频繁无故删除技术文章(连Redis教程都曾被判"敏感"),二是文章页面的广告密度堪比街边小广告(正文中竟会插入动态广告位),三是搜索引擎优先展示CSDN的爬虫复制内容而非原创出处。相比之下,自建Hexo博客就像拥有了自己的数字花园——零广告、全控制、永久存续,还能用Git版本管理所有内容。
2. 迁移前的准备工作
2.1 环境配置清单
我的迁移环境组合是:
- Node.js v16.14.2(Hexo运行基础)
- Git 2.35.1(版本控制)
- Hexo 6.3.0(博客框架)
- hexo-migrator-csdn 1.1.3(专用迁移插件)
- Typora 0.11.18(Markdown编辑器)
重要提示:Node.js请务必安装LTS版本,我在Windows 11和macOS Ventura上都测试过这个组合。曾尝试用Node 18导致hexo-server频繁崩溃,回退到16版立即稳定。
2.2 CSDN数据导出
CSDN官方不提供文章导出功能,但通过开发者工具可以曲线救国:
- 登录CSDN后按F12打开控制台
- 在Network面板筛选"blog/overview"
- 复制response中的JSON数据到jsonformatter.org格式化
- 保存为csdn_articles.json备用
这个文件包含所有文章的标题、发布时间、分类等元数据,但注意:
- 不会包含被CSDN删除的文章
- 图片仍是CSDN的CDN链接(后续需要处理)
- 代码块格式可能错乱
3. 完整迁移实战步骤
3.1 Hexo初始化
# 创建博客目录 mkdir hexo-blog && cd hexo-blog # 初始化项目(注意跳过npm install) hexo init --no-install # 单独安装关键依赖(避免网络问题) npm install hexo@6.3.0 hexo-cli@4.3.0 --save-exact npm install hexo-migrator-csdn@1.1.3 --save初始化后需要修改_config.yml关键配置:
# 将文章永久链接格式改为和CSDN一致 permalink: :year/:month/:day/:title/ # 启用代码高亮 highlight: enable: true line_number: true auto_detect: true3.2 批量导入文章
把之前保存的csdn_articles.json放在hexo-blog根目录,执行:
hexo migrate csdn csdn_articles.json常见问题处理:
- 若出现"ECONNRESET"错误:因为CSDN反爬,建议在命令后添加--delay=3000(3秒间隔)
- 部分数学公式乱码:安装hexo-filter-mathjax插件
- 代码块丢失语言标识:用正则表达式批量添加,例如
sed -i 's/```$/```java/g' source/_posts/*.md
3.3 图片资源迁移
CSDN的图片外链迟早会失效,我写了个Python脚本处理:
import os import requests from urllib.parse import urlparse def download_csdn_images(md_file): with open(md_file, 'r+', encoding='utf-8') as f: content = f.read() # 匹配CSDN图片链接的正则 pattern = r'!\[.*?\]\((https?://img-blog\.csdnimg\.cn/.*?)\)' matches = re.finditer(pattern, content) for match in matches: img_url = match.group(1) img_name = os.path.basename(urlparse(img_url).path) local_path = f"source/images/{img_name}" # 下载图片 res = requests.get(img_url, headers={'User-Agent': 'Mozilla/5.0'}) with open(local_path, 'wb') as img_f: img_f.write(res.content) # 替换链接 content = content.replace(img_url, f"/images/{img_name}") # 写回文件 f.seek(0) f.write(content) f.truncate()4. 迁移后的优化工作
4.1 自动化部署方案
我的部署组合:
- GitHub Pages托管静态文件
- GitHub Actions自动化构建
- Cloudflare CDN加速
.github/workflows/deploy.yml配置示例:
name: Deploy Hexo on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Use Node.js 16 uses: actions/setup-node@v3 with: node-version: '16' - name: Install Dependencies run: | npm install - name: Generate Files run: | hexo generate - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public4.2 访问量统计方案
放弃CSDN的虚假PV计数后,我采用:
- Google Analytics 4(基础流量分析)
- Umami(开源自托管方案)
- Cloudflare Analytics(抗DDoS附带统计)
在Hexo主题中注入GA4的代码位置:
<!-- themes/your-theme/layout/_partial/head.ejs --> <% if (config.google_analytics) { %> <script async src="https://www.googletagmanager.com/gtag/js?id=<%= config.google_analytics %>"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '<%= config.google_analytics %>'); </script> <% } %>5. 那些年我踩过的坑
5.1 中文文件名悲剧
最初直接用文章标题作为Markdown文件名,结果出现各种问题:
- Git显示中文乱码
- Windows/Mac/Linux系统编码不一致
- URL中出现百分号编码
解决方案:
- 在
scaffolds/post.md中添加slug字段 - 迁移时用Python生成英文文件名:
import hashlib def generate_filename(title): return hashlib.md5(title.encode()).hexdigest()[:12] + '.md'5.2 评论系统选型
尝试过多种方案后的结论:
- Disqus:国内访问困难
- Gitalk:GitHub鉴权复杂
- Valine:需要LeanCloud备案
- Twikoo:自建Vercel最稳定
最终采用的Twikoo配置:
twikoo: envId: https://your-vercel-app.vercel.app region: ap-shanghai path: window.location.pathname5.3 搜索方案优化
Hexo默认搜索体验差,推荐:
- Algolia(付费但稳定)
- LocalSearch(自建方案)
- 微软Bing站内搜索
我的LocalSearch实现关键代码:
// 在generate时创建搜索索引 hexo.extend.generator.register('searchjson', function(locals) { return { path: 'search.json', data: JSON.stringify({ pages: locals.posts.map(post => ({ title: post.title, content: post.content.replace(/<[^>]+>/g, '').substring(0, 500), url: config.url + '/' + post.path })) }) } })迁移完成后,博客访问速度从CSDN的平均1.8s提升到0.4s,Google收录量三个月内反超原CSDN内容。最意外的是,当我放出"CSDN文章备份包"下载后,GitHub Star一周内涨了300+。现在每次在Hexo写新文章时,都会庆幸当初做了这个决定。