我正在使用这个小工具将Skype的聊天数据库转换为类似IRC的聊天导出形式的更具可读性的表示。我之所以这样做,是因为我保存了一些旧的Skype聊天记录' .db文件,现在我试图从中提取内容。那部分我开始工作了,但现在有些东西我无法弄清楚它为什么会发生。
如果我以./skype2text.py file.db chat_partner_id
调用我的脚本,它工作正常,并将指定用户ID的聊天打印到stdout
有了这个工作,我想将输出保存到文件而不是将其打印到stdout,所以我只是先将它作为echo $(./skype2text.py file.db chat_partner_id)
运行,看它是怎么回事,所以我可以将它重定向到一个文件,当奇怪的事情发生时,那就是那个。它会打印第一个聊天行并崩溃。 (并且在此之后也完全忽略换行符。)
$ echo $(./skype2text.py "main 1.db" miya)
Traceback (most recent call last):
File "./skype2text.py", line 62, in <module>
print(u"<" + row[0] + u"> " + unicode(parser.unescape(unicode(row[1]))))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 47: ordinal not in range(128)
<Luda> C'est moi <ss type="wink">;)</ss> <MiYa> None
这是代码
#!/usr/bin/env python2
# charset=utf-8
from __future__ import print_function
import sys
import sqlite3
import os.path
import HTMLParser
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def eprint_use():
eprint("usage : " + sys.argv[0] + " <file.db> <partner's skype ID> [output file]")
# actual code here
# first of all check argv and print the help message if it's wrong
if len(sys.argv) < 3 or len(sys.argv) > 4:
eprint_use()
else:
database_path = sys.argv[1]
partner_id = sys.argv[2]
output_path = sys.argv[3] if len(sys.argv) == 4 else partner_id + '.txt'
if not os.path.isfile(database_path):
sys.exit('the file %s does not exist' % (database_path))
connection = sqlite3.connect(database_path)
cursor = connection.cursor()
parser = HTMLParser.HTMLParser()
cursor.execute("SELECT from_dispname,body_xml FROM Messages WHERE dialog_partner='" + partner_id + "' ORDER BY timestamp")
for row in cursor.fetchall():
print(u"<" + row[0] + u"> " + unicode(parser.unescape(unicode(row[1]))))
我已经忽略了顶部没有任何目的的大部分评论,因此第62行指的是最后一行。
我可能在某些时候对SQL查询做错了。我还没有真正检查输入是否有效,但这并非真正重要。为什么会这样?为什么以不同的方式调用脚本会导致它崩溃,尽管它本身可以完美地运行?我也检查了sys.argv
,在两种情况下都包含相同的内容。同样是的,我有一个output_path
变量未使用,我将根据第三个参数调整输出,如果它包含一个文件名,我现在输出到文件中。最奇怪的是它为什么会导致unicode异常?
$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
$ python2 --version
Python 2.7.10
答案 0 :(得分:1)
可能默认编码在第一种情况下是utf-8(当它工作时),在第二种情况下是ascii(当发生UnicodeEncodeError时)
也许试试:
for row in cursor.fetchall():
res = u"<" + row[0] + u"> " + unicode(parser.unescape(unicode(row[1])))
print(res.encode('utf-8'))