Archive for July 10th, 2006

博客网(bokee/blogchina)至WordPress搬家攻略

Monday, July 10th, 2006

摘要

Web内容集成曾经是最困难的工作之一,感谢XML/Web services,在Web 2.0的时代终于可以比较容易的实现了。目前绝大部分blog系统都支持两种方式的内容输入:标准的基于Web的方式,即用户登录、发贴;另外就是通过API利用客户端软件发贴。这两种方式可以简单的想象成WebMail和基于SMTP邮件客户端。本文实现了基于半结构化内容抽取和异构XML目标数据的集成。

实现方法

现在常用的Blog API有Blogger API, MetaWeblog API, Movable Type API等,这些API都采用了XML-RPC进行数据包装和传输。 blogchina.com目前仅支持早期的Blogger API 1.0(而且是部分支持),而WP同时支持这三种API。

为了把http://zhangling.blogchina.com 里过去两年的文章完整的搬到新系统中,我首先尝试了用Blogger API去读取blogchina里的文章,但碰到了问题。

用Java开发,我用了Apache的XML-RPC包。经尝试,发现blogchina仅支持blogger.getUserInfoblogger.getTemplateblogger.getUsersBlogs等几个有限的方法,对于关键的抽取文章内容的函数则完全不支持。这意味着所有的内容无法通过编程的方法获得,工作量一下上升了很多。

于是我在浏览器分别打开04-06年的文章列表,用下载工具将页面里所有博客文章进行批量下载(还好这个过程的工作量不是很大),然后在本地磁盘上根据年份和文章分类建立多层子目录,把对应的文章放在不同目录下面。现在的问题变成如何从HTML页面中把文章标题、内容、发贴日期和评论分别抽取出来作为XML-RPC参数发送给WP系统自动建立新文章。仔细研究了这些HTML文件,发现它们都具有相同的结构和布局,仅仅是内容上的变化,其他如布局和风格几乎完全一样。接下来就需要分析HTML代码找到文章标题、内容、日期、评论部分的特征标签以进行内容抽取。比如就标题来讲,所有的标题前都有”diaryTitle”标签;所有发贴日期都符合正则表达式”年\\S*月\\S*日.*星期\\S\\s\\d\\d:\\d\\d”,等等这些信息都对内容的正确提取提供了保证。

根据分析得到的特征标签,写了4个Java class(TitleExtractor, ContentExtractor, DateExtractor和CommentExtractor) 。对300多篇文章进行测试,抽取成功率100%(当然还写了一些字符串处理函数解决一些有变数的字串)。于是,数据源的问题得到的解决。

花费最多时间的倒是对WP的数据写入部分。我用了MetaWeblogAPI,使用XML-RPC中的XmlRpcClient类,构建好参数列表,测试发现中文出现问题。Java程序送出的XML数据包在WP系统上显示为乱码。经调试确认XML-RPC使用的是UTF-8编码,而WP也是配置成UTF-8。在调试多次失败后,我用Ethereal(已经改名成WireShark)捕获了发出去的HTTP数据包,发现Apache的XML-RPC实现把中文字符进行HTML转义,导致WP无法识别。为了验证,我装了Zoundry并尝试发贴,在捕获的HTTP请求包中,Zoundry把“中文标题”四个汉字编码成“\344\270\255\346\226\207\346\240\207\351\242\230”,而且WP正确的接受并成功显示!接下来,我下载了Apache commons codec包,尝试了里面多个编码器,始终没能成功,不得不考虑使用其他Java实现。

最终我找到了合适的包Redstone XML-RPC,它顺利的把我GB2312编码的文章上传到WP上(需要把WP缺省编码改成GB2312),于是剩下的事情就是一个for循环对目录里的所有文件做一次内容提取、参数组装和网络调用。为了简单,我把评论部分附加在正文末尾(因此可以在新博客老帖子的正文部分里看到很多老系统的影子,如黑色的头像:)

结论

虽然一些商业系统开始提供博客搬家服务(如blogbus和讯),由于可用性的限制要实现完整的系统搬家难度还是非常大(我在blogbus尝试10篇文章的搬家未获得成功)。因此,如果懂软件开发的话,自己写点搬家程序会更容易、更便捷。

参考文献

1. Apache XML-RPC: http://ws.apache.org/xmlrpc/
2. WordPress API: http://codex.wordpress.org/XML-RPC_Support
3. Ethereal Bug 894: http://bugs.ethereal.com/bugzilla/show_bug.cgi?id=894
4. PHP和JAVA的XML-RPC中文问题解决办法: http://fanqiang.chinaunix.net/program/php/2005-09-06/3586.shtml

附录(部分代码)

XmlRpcClient client = null;
try {
client = new XmlRpcClient(new URL(“http://www.zhangling.org/blog/xmlrpc.php”), true);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

for (int i = 0; i < files.length; i++) { try { filename = folder.getAbsoluteFile() + "\\" + files[i]; FileInputStream fileInput = new FileInputStream(filename); InputStreamReader reader = new InputStreamReader(fileInput,"GB2312"); BufferedReader bufferReader = new BufferedReader(reader); while (bufferReader.ready()) { content = content + bufferReader.readLine() + "\n"; } } catch (Exception e) { System.err.println(e); }

title = titleExtractor.getTitle(content);
description = contentExtractor.getContent(content)
+ commentExtractor.getComment(content);
datestring = dateExtractor.getDate(content);
content = “”;

Vector v = new Vector();
v.add(“1”);
v.add(“AAAA”);
v.add(“********”);
Hashtable hashtable = new Hashtable();
hashtable.put(“title”, title);
hashtable.put(“description”, description);
Date date = new Date(datestring);
hashtable.put(“dateCreated”, date);
String category[] = new String[1];
category[0] = “技术”;
hashtable.put(“categories”, category);
v.add(hashtable);
v.add(“true”);
try {
Object result = client.invoke(“metaWeblog.newPost”, v);
System.out.println(“received: ” + result);
} catch (Exception e) {
Logger.writeLog(filename + “:” + e);
System.out.println(e);
}

}

}

本人新博客网站架构简介

Monday, July 10th, 2006

本系统用的是dreamhost的虚拟主机服务(多谢丁峰推荐),20GB空间,支持FTP, Telnet, 可安装WordPress(当前我使用的blog系统)和其他PHP论坛等服务器端软件。服务费是一年90美元,用了网上贴的coupon code后实际第一年费用22美元。

zhangling.org是01年左右我在万网注册的,一直没怎么用,这次博客搬家派上了作用。只需要在万网的国际域名管理中把DNS服务器指向dreamhost的DNS就可以了。

现在的WordPress(WP)系统比博客网的blogdriver提升了一大步,好比Eclipse和Symantec VisualCafe的区别 。作为最流行的blog系统之一,WordPress有众多的插件(我安装了“流量统计”和“最新评论”插件。由于导致IE显示问题,“最新评论”插件尚未激活)和多种API支持。绝大多数blog client对WP都有很好的支持。

在稍微学习了WP的管理之后,更新了一些系统配置和部分页面模板;在sidebar增加了照片、日历、最新文章等内容。

博客网搬家动因

Monday, July 10th, 2006

1. 博客网(bokee.com, blogchina.com)系统不稳定,经常出现无法发贴的情况。写评论会出现多次提交的相同评论内容。最近出现的无法回复英文字符的情况,让人无法接受;

2. 博客网不支持分类的RSS,一个博客只有一个总的RSS。因为需要向CSDN Blog导出部分分类,这直接导致更换系统;

3. 博客网登录后session有效期过短,稍微长一点的帖子需要不停备份到临时打开的notepad里以免丢失;

4. 缺乏内容管理功能。内容易进不易出,提供对外的编程接口极有限。