数据分析S101:从mht文件中提取qq用户发言

qq的聊天记录可以导出为mht文件。这次的目标就是从mht文件中提取用户的聊天记录并存入数据库之中,同时要完成根据指定用户名查出其所有发言内容的功能。

功能一:解析数据

获取记录:

这里是用的是BeautifulSoup4来对文档进行处理,首先查找所有tr标签。

[python]
with open(chatdata) as f:
soup = BeautifulSoup(f.read())
script = soup.find_all(‘tr’)
[/python]

 

分析记录:

先清空原有表,然后将日期置为None,开始遍历script。先清空原有表,然后将日期置为None,开始遍历script。
tr标签的内容可能有三种。1:一条发言记录,也就是我们要找的内容。2:一条日期,表明了直到下一个日期为止的内容的发言日期。3:无关内容,比如网页标题等。

获取日期:

对于一条记录如果i.td.div不存在,即tr标签下有td标签,td标签下没有div标签时。认为这是一条日期记录,取td下的文本内容,忽略前四个字符即可得到’yyyy-MM-dd’格式的日期。此处为了符合数据库格式,将’-‘替换为了’/‘。

获取聊天信息:
  1. 如果i.td.div存在,则可能为发言记录或者无关内容。这里直接按照发言记录来处理,同时捕获异常,如果是无关内容则会报异常,直接进入下一条的处理流程。
  2. 对于发言记录,首先取得i.td.div.div.string即发言人的名字及账号。首先判断最后一位是否为右括号,如果是则为数字型账号,否则则为邮箱型账号。通过两个正则可分别取得两种情况下的用户名和用户账户。然后通过i.td.div.contents[1]取得用户发言的时间。此时加上之前缓存的date,已经有了用户名,账号,日期,时间,只缺内容了。
  3. 通过i.td.contents[1].strings可以取得用户发言的全部文字内容。然后join合并为字符串即可。这样做可以快捷的取得所有文字内容,包括超链接等,不会有所遗漏,缺点是忽略了图片表情以及换行符。

[python]
conn.execute(‘DELETE FROM chatdb’)
date = None
for i in script:
try:
if not i.td.div:
date = i.td.string[4:].replace(‘-‘, r’/‘)
else:
speaker = i.td.div.div.string
if ‘)’ == speaker[-1]:
speaker = re.findall(r’(.?)((\d+))‘, speaker)
else:
speaker = re.findall(r’(.
?)<(.*?)&get;’, speaker)
s_name = speaker[0][0]
s_id = speaker[0][1]
time = i.td.div.contents[1]

        content = ''.join([ttt for ttt in i.td.contents[1].strings])
        conn.execute('INSERT INTO chatdb (name,usrid,date, time, contents) VALUES(?,?,?,?,?)',
                     (s_name, s_id, date, time, content))
except Exception as e:
    pass

[/python]

 

功能二:查询发言内容

首先查出该用户名最晚的一条发言记录的id,然后根据id查询出所有发言记录。最后组装成数组返回。
[python]
def someonechat(name):
conn = sqlite3.connect(db_filename)
result = conn.execute(‘SELECT usrid FROM chatdb ORDER BY date DESC,time DESC LIMIT 1 ‘)
usrid = result.fetchone()[0]
result = conn.execute(‘SELECT id,name,date,time,contents FROM chatdb WHERE usrid=?’, (usrid,))
chatlist = [{‘id’: i[2], ‘name’: i[1], ‘usrid’: usrid, ‘date’: i[2], ‘time’: i[3], ‘contents’: i[4]} for i in
result.fetchall()]
return chatlist
[/python]