我正在使用Jeff's demo code来使用YouTube API和Python与我的视频的字幕进行互动。而且我的英语视频效果非常好。不幸的是,当我尝试将我的视频用于西班牙语的自动成绩单,其中包含á¡等字符时,我收到编码错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 25: ordinal not in range(128)
我的Python脚本顶部有# -*- coding: utf-8 -*-
,我已将CAPTIONS_LANGUAGE_CODE
更改为'es'
,但似乎脚本仍将其下载的.srt文件解释为{ {1}}而不是ascii
。下载.srt文件的行是:
utf-8
如何让Python将srt文件视为if response_headers["status"] == "200":
self.srt_captions = SubRipFile.from_string(body)
,以免它产生编码错误?
谢谢!
答案 0 :(得分:3)
看起来这根本不是Youtube API问题,而是Python问题。请注意,您的错误不是编码错误,而是解码错误;你偶然发现了Python的工作方式(无论好坏)。 Python中的许多函数将unicode数据转换为8位字符串而不是本机unicode对象,使用带有十六进制数的\ x来表示大于127的字符。(一种这样的方法是SubRipFile对象的“from_string”方法你'使用。)因此数据仍然是unicode,但对象是一个字符串。因此,当您强制转换为unicode对象(通过使用您提供的示例代码中的unicode对象的'join'方法触发)时,Python将假定为ascii编解码器(8位字符串的默认值) ,无论数据编码如何)处理数据,然后在这些十六进制字符上抛出错误。
有几种解决方案。
1)你可以明确告诉Python当你运行你的join方法时不假设一个ascii编解码器,但我总是很难做到这一点(并且在每种情况下都这样做)。所以我不会尝试一些示例代码。
2)你可以放弃原生的unicode对象,只需使用8位字符串来处理你的unicode数据;这只需要你改变这一行:
body = u'\n'.join(lines[2:])
对此:
body = '\n'.join(lines[2:])
这种方法存在潜在的缺点,但是,你必须确保在每种情况下都这样做;你也不会利用Python原生的unicode对象(这可能会或可能不会在你的代码中出现问题)。
3)您可以使用低级“编解码器”模块来确保数据从一开始就被转换为本机unicode对象,而不是使用8位字符串。通常,您以这种方式完成这样的任务:
import codecs
f=codecs.open('captions.srt',encoding='utf-8')
l=f.readlines()
f.close()
type(l[0]) # will be unicode object rather than string object
当然,你有使用SubRipFile对象返回字符串的复杂性,但你可以通过StringIO对象发送它来解决这个问题(因此编解码器模块可以将翻录的数据视为文件),使用codecs.encode()方法等.PDF文档在所有这些方面都有相当不错的部分。
祝你好运。