動機
自從我把Github+Hexo的博客“交給”Google之后,每天都有幾十位的訪客2333,訪客少的原因有許多,一個是文章較少,二是百度蟲子沒有爬到我的頁面,就會導致即就算直接搜索博客里面的內容,百度都不會返回我的地址,就這個情況我已經使用百度和谷歌去處理了,至于文章較少的問題,我打算做個博客遷移!
我大三到現在的所有博客全部都在CSDN上,所以要對CSDN做一個文章導出功能,官方提供了工具,然而我昨天試了并不行。有博友自己提供了工具,是用python寫的,本來打算用的,但是自己電腦沒有裝python,一時興起決定用java寫個小程序,自己動手豐衣足食,說干就干,整體的思路如下圖:
使用Jsoup去獲取頁面并解析--->將對應html代碼轉換成MD文件存儲到本地--->最后放到對應位置,執行
hexo g
和hexo d
命令發布到Github上
過程
解析CSDN
比較慶幸的是CSDN并沒有對“爬蟲”做相關的處理,也就是說,我使用Jsoup獲取頁面并解析是沒有任何限制的(至少我沒有遇到),這里需要做個簡單的邏輯來獲取article/list
頁面的所有文章列表url包括摘要。在接著根據url將對應文章的內容結構化解析出來,代碼如下
String url = HOST_URL + username + "/article/list/" + 1;
Document parse = Jsoup.parse(new URL(url), 5000);
Element element = parse.select("div#papelist span").get(0);
String papelistInfo = element.text();
String totalPage = papelistInfo.split("共")[1].split("頁")[0]; // 有點暴力,需注意
int total = Integer.valueOf(totalPage);
System.out.println(total);
Map<String,String> map = new HashMap<>();
for (int i = 1; i <= total; i++) {
String listUrl = HOST_URL + username + "/article/list/" + i;
Document doc = Jsoup.parse(new URL(listUrl), 5000);
Elements topSelect = doc.select(TOP_XPATH);
Elements normalSelect = doc.select(NOMAIL_QUERY);
for (Element item : topSelect) {
map.put(item.select(".article_title h1 span a").get(0).attr("href"),item.select(".article_description").get(0).text());
}
for (Element item : normalSelect) {
map.put(item.select(".article_title h1 span a").get(0).attr("href"),item.select(".article_description").get(0).text());
}
}
Set<String> strings = map.keySet();
for(String item:strings){
Document doc = Jsoup.parse(new URL(HOST_URL + item), 5000);
BlogModel bm = new BlogModel();
bm.setTitle(doc.select("#article_details > div.article_title > h1 > span > a").text());
bm.setDesc(map.get(item));
bm.setPublishDate(doc.select("#article_details > div.article_manage.clearfix > div.article_r > span.link_postdate").text());
Elements select = doc.select("#article_details > div.category.clearfix > div.category_r");
List<String> cat = new ArrayList<>();
for(Element ele : select){
String text = ele.select("label span").get(0).text();
int i = text.lastIndexOf("(");
if(i>=0){
String substring = text.substring(0, i);
cat.add(substring);
}else{
cat.add(text);
}
;
}
bm.setCategories(cat);
Elements tagEles = doc.select("#article_details > div.article_manage.clearfix > div.article_l > span > a");
List<String> tags = new ArrayList<>();
for(Element ele : tagEles){
String text = ele.text();
tags.add(text);
}
bm.setTags(tags);
doc.getElementsByTag("script").remove();
bm.setContent(doc.select("#article_content").html());
try{
buildHexo(bm);
}catch (Exception e){
e.printStackTrace();
}
}
代碼可能較糙。
這里結構化我是按照Hexo的方式來定的,
---
title: {{ title }}
date: {{ date }}
categories:
tags:
---
<!--more-->
more上面為文章摘要,下面為正文。
html2md
走到這一步的時候,我并沒有打算自己去寫,我知道這不是一個簡單的程序,我在Github上找了許久,大部分是js寫的,期間我也嘗試使用java去調用js代碼去完成轉換,但是失敗了,最后決定使用這個https://github.com/pnikosis/jHTML2Md,
看來這位哥們寫這個的本意也是要搞博客遷移,因為里面有這樣一個方法
htmlToHexoMd(String htmlPath, String mdPath, String charset)
當然了我沒有用到,我用的是這個方法
String convertHtml(String html, String charset)
很順利,文章成功導出,一些文章的標題創建不了文件,也就三篇,我就沒有去管他
讓人高興的是,你只要知道一個人的博客昵稱如“u010850027”,你都可以把他的文章導出來~~~
hexo發布
按理說,將對應的md文件放在“hexodir/source/_posts”下,然后執行發布命令就ok了,然而,此次最大的問題出現了,html轉換md文件的問題!!!
對于一些簡單的html代碼,可以很完美的轉換為md文件,但是對于復雜的就不行了,單單csdn里的代碼塊,都解析不了,后來我改了下作者的源碼,然而也不行,因為CSDN有兩種代碼塊方式,一個是markdown的一個是代碼高亮,這一下問題就變的稍復雜起來。由于時間的問題,我打算先放一放,平時思考思考再看看能否解決。
后記
開始實現這個想法是周日凌晨開始的,真的,半夜聽歌喝茶寫代碼會“高潮”!不知不覺搞到了凌晨三點多,然后睡覺,腦海里一直在想著這個問題,第二天上午也花了時間去解決問題,我想要是再花再這個上面,周末就玩完了。所以就暫且放一放!
最后白板上,藍色虛線內的已經走通,紅色區域內的問題是要重點解決的,待問題解決,就一路暢通了~~~
代碼放在了這里:Github
想關注后續的歡迎star和fork
歡迎來我的博客參觀