был полезен в поиске странного кодека еще раз
я есть текстовый файл, который, как утверждает издатель (Комиссия по ценным бумагам США), зашифрован в UTF-8 (https://www.sec.gov/files/aqfs.pdf, раздел 4). Я обрабатываю строки следующим кодом:
def tags(filename):
"""Yield Tag instances from tag.txt."""
with codecs.open(filename, 'r', encoding='utf-8', errors='strict') as f:
fields = f.readline().strip().split('\t')
for line in f.readlines():
yield process_tag_record(fields, line)
Я получаю следующую ошибку:
Traceback (most recent call last):
File "/home/randm/Projects/finance/secxbrl.py", line 151, in <module>
main()
File "/home/randm/Projects/finance/secxbrl.py", line 143, in main
all_tags = list(tags("tag.txt"))
File "/home/randm/Projects/finance/secxbrl.py", line 109, in tags
content = f.read()
File "/home/randm/Libraries/anaconda3/lib/python3.6/codecs.py", line 698, in read
return self.reader.read(size)
File "/home/randm/Libraries/anaconda3/lib/python3.6/codecs.py", line 501, in read
newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 3583587: invalid start byte
Учитывая, что я, вероятно, не могу вернуться к SEC и сказать им, что у них есть файлы, которые, кажется, не кодируются в UTF-8, как мне отладить и отловить эту ошибку?
Что я пробовал
Я сделал hexdump файла и обнаружил, что оскорбительным текстом был текст «ДОПОЛНИТЕЛЬНОЕ РАСКРЫТИЕ ИНВЕСТИЦИЙ НЕ НАЛИЧНЫМИ». Если я декодирую ошибочный байт как шестнадцатеричный код (то есть «U + 00AD»), это имеет смысл в контексте, поскольку это мягкий дефис. Но следующее, похоже, не работает:
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> b"\x41".decode("utf-8")
'A'
>>> b"\xad".decode("utf-8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec cant decode byte 0xad in position 0: invalid start byte
>>> b"\xc2ad".decode("utf-8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec cant decode byte 0xc2 in position 0: invalid continuation byte
Я использовалerrors='replace'
, который, кажется, проходит. Но я хотел бы понять, что произойдет, если я попытаюсь вставить это в базу данных.
Отредактировано, чтобы добавить hexdump:
0036ae40 31 09 09 09 09 53 55 50 50 4c 45 4d 45 4e 54 41 |1....SUPPLEMENTA|
0036ae50 4c 20 44 49 53 43 4c 4f 53 55 52 45 20 4f 46 20 |L DISCLOSURE OF |
0036ae60 4e 4f 4e ad 43 41 53 48 20 49 4e 56 45 53 54 49 |NON.CASH INVESTI|
0036ae70 4e 47 20 41 4e 44 20 46 49 4e 41 4e 43 49 4e 47 |NG AND FINANCING|
0036ae80 20 41 43 54 49 56 49 54 49 45 53 3a 09 0a 50 72 | ACTIVITIES:..Pr|