最近我把我自己的博客从hexo搬到了halo,大部分文章迁移还算顺畅,但是主要也遇到了几个问题。
- URL规则问题:halo博客限制了部分特殊字符作为url,比如“_”,但是之前的hexo博客没有限制,这部分没啥好说的,通过H2数据库就解决,进入H2数据库之后直接通过插入SQL把URL同步修改即可;
- twikoo评论迁移至halo:这部分是个大问题,网上完全没有任何现有的教程,我是全程利用chatGPT帮我实现了这部分需求的;
- 百度收录的URL重定向到新的URL:halo博客的url必须要加一个/archive,然而我之前的hexo博客完全没这个需求,这个也是利用chatGPT帮我写了几行Nginx配置文件就解决了,然后并没有完美解决,不过也无伤大雅了。
本文主要把twikoo评论迁移至halo的思路以及操作流程全程回顾一遍。
twikoo评论迁移至halo
思路
先说我自己对迁移数据库这件事儿的思路,首先我是想找一个现成的开源的评论迁移插件,甚至也到作者的github去找了,并没有找到任何相关的插件,因为halo博客本身使用的用户都不多,从hexo转向halo的就更少了。所以找现有插件的路子是行不通了。
既然没有现成的路,那么只能自己来了。我的想法是先将hexo博客的twikoo评论导出,这一步是非常简单的,twikoo的评论类似MongoDB的数据结构,是json格式的。
导出之后第一步就是利用python把twikoo的评论json转换成excel,这一步做完之后就是打开halo的H2数据库,找到COMMENTS表,把表结构跟twikoo评论的字段一一对应;最后利用sql将修改之后的评论进行数据插入。
以上就是整个思路,下面开始一步一步的操作。
twikoo评论导出
这一步非常简单,在twikoo评论下方找到导出功能,点击导出即可。
导出后的数据格式如下:
{
"_id": "d3980ba2e097455eb8edc43565751cfc",
"uid": "119654912c9da50475ccc905ca7ce5fa",
"nick": "慧行",
"mail": "contact@liuyude.com",
"mailMd5": "7cf63f4c069815a84554d046f15b527c",
"link": "https://liuyude.com",
"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
"ip": "0.0.0.0",
"master": true,
"url": "/MacOS_uses_UnblockNeteaseMusic_to_unlock_the_netease_music_Guide.html",
"href": "https://www.liuyude.com/MacOS_uses_UnblockNeteaseMusic_to_unlock_the_netease_music_Guide.html",
"comment": "<p>测试下评论</p>\n",
"created": 1682477031313,
"updated": 1682477031313,
"meta": {
"revision": 0,
"created": 1682477031322,
"version": 0
},
"$loki": 220,
"id": "d3980ba2e097455eb8edc43565751cfc",
"ipRegion": "广东省 深圳市 电信"
}
利用chatGPT将评论数据转换成excel
直接将上面的json丢给chatGPT,并且告诉他这是一个jsonlist,把这些list中的这些数据全部转换为excel,转换完成之后见下图:
原表已经没保存了,上表有部分参数是原表处理之后的样式。
评论数据处理
首先需要打开当前网站docker根目录下的.halo
目录,找到application.yaml文件,将h2配置中的web-allow-others与enabled的值设置为true。
# H2 database configuration.
driver-class-name: org.h2.Driver
url: jdbc:h2:file:~/.halo/db/halo
username: account
password: password
h2:
console:
settings:
web-allow-others: true
path: /h2-console
enabled: true
path就是IP:port/h2-console,如果不行也可以试试域名/h2-console。
进入H2web管理端之后进入COMMENTS表,可以看到数据结构如下:
字段 | 说明 | 备注 |
---|---|---|
TYPE | 类型,1是自定义页面,2是文章 | |
ID | 评论ID | |
CREATE_TIME | 创建时间 | |
UPDATE_TIME | 更新时间 | |
ALLOW_NOTIFICATION | 允许通知 | |
AUTHOR | 作者 | |
AUTHOR_URL | 作者URL | 类似于hexo中的网址链接 |
CONTENT | 评论正文 | |
GRAVATAR_MD5 | 头像MD5值 | |
IP_ADDRESS | 评论者IP地址 | |
IS_ADMIN | 是否是管理员 | 管理员回复会添加站长图标 |
PARENT_ID | 父ID | 就是从哪一条回复的,用于盖楼,无则值为0 |
POST_ID | 文章的ID | 对应hexo博客中的URL,这部分数据等下通过URL的映射可以得到每个URL对应的ID |
STATUS | 状态 | 0跟1,分别对应是否应该展示,开启评论需要审核之后默认都是1,0为通过可展示 |
TOP_PRIORITY | 置顶 | 应该是置顶的意思,我看值全部是NULL |
USER_AGENT | 用户UA |
以上就是整个halo的COMMENTS表结构,按照这个格式把数据处理完成。
评论数据插入
数据在表格中处理好之后,通过chatGPT写了一个数据库的python插入代码,让python循环去读取这份表格,并生成可执行的插入语句。
import pandas as pd
# 从 CSV 文件读取数据
data = pd.read_csv('output4.csv')
# 构建批量插入的 SQL 语句
insert_queries = []
for index, row in data.iterrows():
# 设置默认值
status = 0
top_priority = 'NULL'
gravatar_md5 = 'c99ef5c2e9621d48634f20afd24dbaa5'
comment_type = 0
allow_notification = 'TRUE'
# 格式化时间为精确到秒的格式
create_time = pd.to_datetime(row['CREATE_TIME']).strftime('%Y-%m-%d %H:%M:%S')
update_time = pd.to_datetime(row['UPDATE_TIME']).strftime('%Y-%m-%d %H:%M:%S')
# 判断 AUTHOR_URL 是否为空
author_url = 'https://liuyude.com' if pd.isnull(row['AUTHOR_URL']) else row['AUTHOR_URL']
# 判断 PARENT_ID 是否为空
if pd.isnull(row['PARENT_ID']):
parent_id = 0
else:
parent_id = row['PARENT_ID']
# 处理 CONTENT 中的特殊字符
content = row['CONTENT'].replace("'", "''")
insert_query = f'''
INSERT INTO COMMENTS (AUTHOR, EMAIL, AUTHOR_URL, USER_AGENT, IP_ADDRESS, POST_ID, CONTENT, IS_ADMIN, CREATE_TIME, UPDATE_TIME, ID, PARENT_ID, TYPE, ALLOW_NOTIFICATION, STATUS, TOP_PRIORITY, GRAVATAR_MD5)
VALUES ('{row['AUTHOR']}', '{row['EMAIL']}', '{author_url}', '{row['USER_AGENT']}', '{row['IP_ADDRESS']}', {row['POST_ID']}, '{content}', {row['IS_ADMIN']},
'{create_time}', '{update_time}', {row['ID']}, {parent_id}, {comment_type}, {allow_notification}, {status}, {top_priority}, '{gravatar_md5}');
'''
insert_queries.append(insert_query)
# 将多个插入语句组合成一个 SQL 脚本
sql_script = '\n'.join(insert_queries)
# 打印 SQL 脚本
print(sql_script)
执行代码之后会生成可用于H2数据库插入的SQL语句:
INSERT INTO COMMENTS (AUTHOR, EMAIL, AUTHOR_URL, USER_AGENT, IP_ADDRESS, POST_ID, CONTENT, IS_ADMIN, CREATE_TIME, UPDATE_TIME, ID, PARENT_ID, TYPE, ALLOW_NOTIFICATION, STATUS, TOP_PRIORITY, GRAVATAR_MD5)
VALUES ('慧行', 'contact@liuyude.com', 'https://liuyude.com', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', '0.0.0.0', 30.0, '<p>测试下评论</p>
', True,
'2023-04-26 02:43:00', '2023-04-26 02:43:00', 200, 0, 0, TRUE, 0, NULL, 'c99ef5c2e9621d48634f20afd24dbaa5');
然后我是两百多条评论分了2次导入的,其中有一些没有导入成功,看了报错大概率跟格式有关系,但是大部分都导入成功了,所以我也没在意了。导入成功后见下图:
以上就是我折腾一个周末下午通过chatGPT彻底实现了这个需求。
网站URL重定向
解决了评论导入之后我就剩最后一个问题就可以将网站彻底迁入完成了,就是重定向,因为我前前后后用了好几个域名,有liuyude.com,有blog.liuyude.com。我现在的目的就是要把所有blog.liuyude.com/filename.html跟blog.liuyude.com/archive/filename.html全部重定向到liuyude.com/archive/filename.html,这种事当然不用自己写了,交给chatGPT,很快就给了我下面一条Nginx配置语句:
location / {
rewrite ^/archives/(.*)$ https://liuyude.com/archives/$1 permanent;
if ($request_uri ~ ^/([^/]+)\.html$) {
return 301 https://liuyude.com/archives/$1.html;
}
# 其他配置...
}
放在宝塔的网站配置规则中,立马生效了,至此,网站搬家彻底搞定!
评论区