呓语 | 杨英明的个人博客

专注于c++、Python,欢迎交流

By

博客园文章迁移脚本(xml.sax+mysqldb)

写博客系统的后期需要把之前的文章导入过来,我之前的文章都在博客园上,但是博客园只提供博文导入到有限的第三方博客系统中,这里面肯定不包括我自己写的博客系统,所以我需要自己写一个文章迁移程序。

好在博客园提供博文备份功能,导出的备份文件是 xml格式

所以文章迁移程序要完成两个步骤:

  1. 解析xml文件
  2. 执行sql导入文章

1.解析xml文件

这一步需要从xml文件中解析出每一篇文章的 标题、发布时间、文章内容、作者 这些信息。

Python中常用的xml解析库有 xml.domxml.sax,他们的主要区别是xml.dom一次性读取整个文档,将解析出来的元素树保存在内存中;xml.sax则是动态解析xml文件,一边读取一边解析。相对来说,在读取大文件的时候,sax更加节省内存。在这里我选择使用 xml.sax

xml.sax的使用方法可以看这里:Python:使用基于事件驱动的SAX解析XML

2.执行sql导入文章

这一步很简单,Python中操作mysql数据库的教程很多,随便搜一篇就可以了。

连接数据库方法:

import MySQLdb

conn= MySQLdb.connect(
        host='localhost',
        port = 3306,
        user='your_username',
        passwd='your_password',
        db ='blog',
        charset = 'utf8',       # 不声明编码导入的数据会显示出错
        )
cur = conn.cursor()

导入数据库部分代码:

sql ="insert into blog_article (`title`,`desc`,`content`,`click_count`,`is_recommend`,`date_publish`,`category_id`,`user_id`,`comment_cnt`) values('%s','%s','%s','%d','%d','%s','%d','%d','%d')"%(MySQLdb.escape_string(self.title.encode('utf8')),MySQLdb.escape_string(self.title.encode('utf8')),MySQLdb.escape_string(self.description.encode('utf8')),0,0,str(pubDate),11,1,0)

cur.execute(sql)
conn.commit()

执行效果

代码

下面是文章迁移程序的全部代码:

# -*- coding: UTF-8 -*-

import xml.sax
import MySQLdb
import datetime

conn= MySQLdb.connect(
        host='localhost',
        port = 3306,
        user='your_username',
        passwd='your_password',
        db ='blog',
        charset = 'utf8',       # 不声明编码导入的数据会显示出错
        )
print '正在连接数据库……'
cur = conn.cursor()

class MovieHandler(xml.sax.ContentHandler):
    def __init__(self):
        self.cnt = 1
        self.CurrentData = ""
        self.title = ""
        self.link = ""
        self.creator = ""
        self.author = ""
        self.pubDate = ""
        self.guid = ""
        self.description = ""

    # 元素开始事件处理
    def startElement(self, tag, attributes):
        self.CurrentData = tag
        if tag == "item":
            print "*****Article*****"

    # 元素结束事件处理
    def endElement(self, tag):
        if self.CurrentData == "title":
            print "Title:", self.title
            self.CurrentData = ""
        elif self.CurrentData == "link":
            print "Link:", self.link
            self.CurrentData = ""
        elif self.CurrentData == "dc:creator":
            print "Dc:creator:", self.creator
            self.CurrentData = ""
        elif self.CurrentData == "author":
            print "Author:", self.author
            self.CurrentData = ""
        elif self.CurrentData == "pubDate":
            print "PubDate:", self.pubDate
            self.CurrentData = ""
        elif self.CurrentData == "guid":
            print "Guid:", self.guid
        elif self.CurrentData == "description":
            # 文章末尾
            # print "Description:", self.description

            # 文章描述不为空
            if len(self.description)!=0:
                pubDate = datetime.datetime.strptime(self.pubDate, "%a, %d %b %Y %X %Z")
                sql ="insert into blog_article (`title`,`desc`,`content`,`click_count`,`is_recommend`,`date_publish`,`category_id`,`user_id`,`comment_cnt`) values('%s','%s','%s','%d','%d','%s','%d','%d','%d')"%(MySQLdb.escape_string(self.title.encode('utf8')),MySQLdb.escape_string(self.title.encode('utf8')),MySQLdb.escape_string(self.description.encode('utf8')),0,0,str(pubDate),11,1,0)
                cur.execute(sql)
                conn.commit()
                print '[%d] %s 导入数据库成功'%(self.cnt,self.title.encode('utf8'))
                self.cnt += 1

            self.description = ""


    # 内容事件处理
    def characters(self, content):
        if self.CurrentData == "title":
            self.title = content
        elif self.CurrentData == "link":
            self.link = content
        elif self.CurrentData == "dc:creator":
            self.creator = content
        elif self.CurrentData == "author":
            self.author = content
        elif self.CurrentData == "pubDate":
            self.pubDate = content
        elif self.CurrentData == "guid":
            self.guid = content
        elif self.CurrentData == "description":
            self.description += content


if (__name__ == "__main__"):
    # 创建一个 XMLReader
    parser = xml.sax.make_parser()
    # turn off namepsaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)

    # 重写 ContextHandler
    Handler = MovieHandler()
    parser.setContentHandler(Handler)

    parser.parse("note.xml")

    cur.close()
    conn.close()

原创声明

转载请注明:呓语 » 博客园文章迁移脚本(xml.sax+mysqldb)