0

我正在使用以下代码从 gmail 附件下载 csv 文件。生成的输出文件看起来像 ^I delimited,我不确定如何将其更改为其他分隔符,以便可以将其加载到 pandas 数据框中。

message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload'].get('parts', ''):
    if part['filename']:
        file_name = part['filename']
        att_id = part['body']['attachmentId']
        att = service.users().messages().attachments().get(userId=user_id, messageId=msg_id,
                                                               id=att_id).execute()
        data = att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
with open(path, 'wb') as f:
    f.write(file_data)

输出文件内容分隔如下 - 位置 ID^IProcessed Currency Code^IExternal MID^IDBA Name

编辑 1: 现在我使用制表符作为分隔符,但在将文件读入数据框时出现不同的错误。也许,它与 urlsafe_b64decode 或 data.encode('UTF-8') 有关,但我无法理解。gmail 中的实际附件文件是制表符分隔文件。

UnicodeDecodeError:“utf-8”编解码器无法解码位置 0 的字节 0xff:无效的起始字节

4

1 回答 1

2

这里有两个问题:

  • 列分隔符'^I'
  • 数据的编码

分隔符

'^I'是另一种表示制表符的方式。某些应用程序可能会选择以这种方式表示制表符而不是使用'\t'转义序列。例如,vim'^I'在指示显示非打印字符时显示选项卡。

编码

'0xff'字节顺序标记或 BOM 的一部分 - 一个不可见的字符序列,用于告诉应用程序用于对文本进行编码的编码。UTF-16 编码使用序列'0xfe0xff'来表示大端 UTF-16(Python 编解码器“utf-16-be”)。 '0xff0xfe'表示 little-endian UTF-16(Python 编解码器“utf-16-le”)。UTf-16 使用两个字节来编码字符,因此字节的顺序很重要。

因此,要成功打开附件,需要指定列分隔符为制表符,编码为 UTF-16(Python 可以使用 BOM 计算出哪个版本的 UTF-16):

pd.read_csv(path, header=0, sep='\t', encoding='utf-16')
于 2019-05-12T19:44:38.380 回答