python脚本将根据从sh调用它的方式引发错误

2024-09-30 18:22:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在制作这个小工具,将skype的聊天数据库转换成一个更可读的表示形式,形式类似IRC的聊天导出。我之所以这样做是因为我保存了一些旧的skypes chats.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

Tags: 文件pathpyimportiddbpartnersys
1条回答
网友
1楼 · 发布于 2024-09-30 18:22:06

在第一种情况下(当它工作时),默认编码可能是utf-8,在第二种情况下(当UnicodeEncodeError发生时)默认编码是ascii

或许可以试试:

for row in cursor.fetchall():
    res = u"<" + row[0] + u"> " +  unicode(parser.unescape(unicode(row[1])))
    print(res.encode('utf-8'))

相关问题 更多 >