提取QQ聊天记录

67 views
Skip to first unread message

Perilla

unread,
Apr 19, 2012, 1:56:02 AM4/19/12
to perillar...@googlegroups.com
想尝试编写个小程序来提取QQ的聊天记录,导出成HTML格式的比较容易,TXT格式也可以。

可以用PHP来写。生成XML格式或JSON格式,或者直接存储到数据库中。

Perilla

unread,
Apr 20, 2012, 12:29:40 PM4/20/12
to perillar...@googlegroups.com
找个Python下解析HTML文件的包——pyquery

源自jquery,不知道好用不。安装费了九牛二虎之力,不熟悉python的包怎么安装,还是找到 lxml 包的exe文件安装的,源码编译太复杂,说明没看懂,编译不成功。
下载地址:
lxml的各种安装文件

安装pyquery需要下载setuptools,下载地址:setuptools

之后,安装pyquery才成功。


在 2012年4月19日星期四UTC+8下午1时56分02秒,Perilla写道:

Perilla

unread,
Apr 22, 2012, 10:58:37 AM4/22/12
to perillar...@googlegroups.com
先用正则表达式处理下txt格式单人的聊天记录,把utf8解码后匹配的。不知道unicode怎么匹配,没把字符串转成unicode。贴个代码:

# -*- coding: utf-8 -*-
'''
QQ 聊天记录
只考虑最简单的单人情况,未加入多人分析。
'''
import re
pattern = re.compile(r"^\d{4}/\d{1,2}/\d{1,2} \d{1,2}:\d{1,2}")
usermessage = file(r'example01.txt','r')
listnum = 0
entry = u''
enrty_time = u''
flag = False # 是否是消息文本
messageList=list(); # 消息保存在链表里
for line in usermessage:
    line_decode =  line.decode('utf-8')
    match = pattern.match(line_decode)
    if match:
        listnum+=1; # 新的一条消息
        entry_time = match.group()
        '''结束之前的消息'''
        if flag:
            messageList.append(u'entry {0} , time: {1}\n{2}'.format(listnum,entry_time,entry))
            entry = ''
        flag = True
    else:
        entry += u'\n'+unicode(line_decode)
print "{0} records done".format(listnum)

在 2012年4月19日星期四UTC+8下午1时56分02秒,Perilla写道:

Perilla

unread,
May 21, 2012, 4:20:46 AM5/21/12
to perillar...@googlegroups.com
利用C++ Boost的regex库写的提取txt格式的小程序。

核心代码:

    const int LIST_INCREMENT = 100;

    ifstream infile(messageFilePath.c_str());

    boost::regex pat( "^\\d{4}/\\d{1,2}/\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}" );
    boost::smatch matches;

    std::string line; // 首先统计消息条数
    int messageCount = 0;
    while(getline(infile,line))
        if(boost::regex_search(line,matches, pat))
            messageCount++;
    //cout<<"Message Total:"<<messageCount<<endl;
    //cout<<"Press enter to continue..."; cin.get();

    // 清除流状态
    infile.clear();
    // 重新定位
    infile.seekg(0,ios::beg);

    int messageNo = 0;

    messageList.reserve(LIST_INCREMENT);
    messageList.clear();

    string singleMessageText;

    // 首先找到第一个条目,getline不处理空行?
    while(getline(infile,line)&&!boost::regex_search(line,matches, pat)) {};
    // 找到第一个条目后
    while(!infile.eof())
    {
        // 新的条目
        ++messageNo;
        // 日期和昵称
        string strDate(matches[0]);
        string strName = line.substr(strDate.length()+1);
        // 消息文本,直到找到下一条目或者遇到文件尾
        singleMessageText = "";
        while(getline(infile,line)&&!boost::regex_search(line,matches, pat))
        {
            singleMessageText = singleMessageText + line + "\n";
        }
        // 更新数据集
        messageList.push_back(MessageEntry(strDate,strName,singleMessageText));
    }

    // 输出结果
    //std::copy(messageList.begin(),messageList.end(),ostream_iterator<MessageEntry>(cout,"\n"));
















































在 2012年4月19日星期四UTC+8下午1时56分02秒,Perilla写道:
Reply all
Reply to author
Forward
0 new messages