Преобразовать объект байтов с шестнадцатеричными символами в строку? - PullRequest
0 голосов
/ 06 июня 2018

У меня гораздо больше проблем с этим, чем я хотел бы признать.Я проверил многочисленные сообщения уже без везения.Я пытаюсь преобразовать объект байта, как это:

b = b'%PDF-1.5\r%\xe2\xe3\xcf\xd3\r\n'

в строковую переменную.

Я уже попробовал следующее,

import codecs
codecs.decode(b, 'hex')
# Error: decoding with 'hex' codec failed (Error: Non-hexadecimal digit found)

b.decode('hex')
# LookupError: 'hex' is not a text encoding; use codecs.decode() to handle arbitrary codecs


b.unhexlify(_)
#AttributeError: 'bytes' object has no attribute 'unhexlify'


str(b)
# just gives me the same bytes object with str type


b.decode('utf-8')
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte

Может кто-нибудь сказать мне, что я здесь делаю не так?

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Что у вас там есть файл PDF;в то время как частично основанные на ASCII-тексте файлы PDF не являются простым текстом.Вы можете найти способ декодировать даже магические байты в заголовке (это должен делать iso8859-1), но как только вы попадете в поток, сжатый дефлятом, вы получите последовательности с полной энтропией 256 байтов, которые не могут быть осмысленно декодированыс любым кодеком.

IOW: нет никакого способа осмысленно декодировать все содержимое байта PDF-файла в строку Unicode, так как это не прямое представление кодовых точек Unicode любого вида.Это все равно, что пытаться декодировать файл JPEG в строку Unicode: это бессмысленно и , это невозможно.

Если вы хотите извлечь текст из файла PDF, вам нужно фактически разобратьи расшифровать его структуру, что совсем не тривиально.

0 голосов
/ 06 июня 2018

На самом деле b уже является строкой.Вы можете узнать это, проверив тип и убедившись, что он печатает все ваши специальные символы:

>>> b = b'%PDF-1.5\r%\xe2\xe3\xcf\xd3\r\n'
>>> type(b)
<type 'str'>
>>> print(b)
%ÔѤË1.5

>>>

Если у вас есть реальный объект байтов, вы конвертируете из байтов в строку, используя .decode(encoding).Плохо то, что вам нужно знать свою кодировку, чтобы сделать это.

Я пошел методом проб и ошибок с парой кодировок с этого сайта: https://docs.python.org/2.4/lib/standard-encodings.html. Он не выдает ошибок с iso8859_15, но я не могу гарантировать, что это хорошо.Вот фрагмент:

line.decode('iso8859_15')
...