Кодек utf-8 не может декодировать байт 0xe2: недопустимая ошибка продолжения байта - PullRequest
0 голосов
/ 05 июня 2019

Я пытаюсь прочитать все файлы PDF из папки, чтобы найти число с помощью регулярного выражения.При проверке кодировка для PDF-файлов - «UTF-8».

Выдает эту ошибку:

Кодек «utf-8» не может декодировать байт 0xe2 в позиции 10: недействительнобайт продолжения

Пробовал читать в двоичном режиме, пробовал кодировку Latin-1, но он показывает все специальные символы, поэтому в поиске ничего не появляется.

import os
import re
import pandas as pd
download_file_path = "C:\\Users\\...\\..\\"
for file_name in os.listdir(download_file_path):
    try:
        with open(download_file_path + file_name, 'r',encoding="UTF-8") as f:
          s = f.read()
          re_api = re.compile("API No\.\:\n(.*)")
          api = re_api.search(s).group(1).split('"')[0].strip()
          print(api)
    except Exception as e:
        print(e)

Ожидается найти номер API из файлов PDF

Ответы [ 2 ]

2 голосов
/ 05 июня 2019

Когда вы открываете файл с open(..., 'r', encoding='utf-8'), вы в основном гарантируете, что это текстовый файл , не содержащий байтов, которые не являются UTF-8.Но, конечно, эта гарантия не распространяется на файл PDF - это двоичный формат, который может содержать или не содержать строк в UTF-8.Но это не так, как вы читаете.

Если у вас есть доступ к библиотеке, которая читает PDF и извлекает текстовые строки, вы могли бы сделать

# Dunno if such a library exists, but bear with ...
instance = myFantasyPDFlibrary('file.pdf')
for text_snippet in instance.enumerate_texts_in_PDF():
    if 'API No.:\n' in text_snippet:
        api = text_snippet.split('API No.:\n')[1].split('\n')[0].split('"')[0].strip()

более реалистично, но более пешеходноВы можете прочитать PDF-файл как двоичный файл и найти зашифрованный текст.

with open('file.pdf', 'rb') as pdf:
    pdfbytes = pdf.read()
if b'API No.:\n' in pdfbytes:
    api_text = pdfbytes.split(b'API No.:\n')[1].split(b'\n')[0].decode('utf-8')
    api = api_text.split('"')[0].strip()

Необработанный обходной путь - врать Python о кодировке и утверждать, что на самом деле это Latin-1.Эта конкретная кодировка имеет привлекательную особенность, заключающуюся в том, что каждый байт отображается точно в свою собственную кодовую точку Unicode, поэтому вы можете читать двоичные данные в виде текста и получать от этого удовольствие.Но тогда, конечно, любой фактический UTF-8 будет преобразован в mojibake (поэтому "hëlló" будет отображаться как "hëlló" например).Вы можете извлечь фактический текст UTF-8, преобразовав текст обратно в байты, а затем расшифровав его с правильной кодировкой (latintext.encode('latin-1').decode('utf-8')).

0 голосов
/ 05 июня 2019

PDF-файлы хранятся в байтах. Поэтому для чтения или записи файла PDF вам необходимо использовать rb или wb.

with open(file, 'rb') as fopen:
    q = fopen.read()
    print(q.decode())

'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte может произойти из-за your editor или PDF не имеет кодировки utf (как правило).

Поэтому используйте,

with open(file, 'rb') as fopen:
        q = fopen.read()
        print(q.decode('latin-1')) #or any encoding which is suitable here.

Если ваш editor console несовместим, вы также не сможете увидеть какой-либо вывод.

A ПРИМЕЧАНИЕ : вы не можете использовать encoding param при использовании rb, поэтому вам нужно декодировать после чтения файла.

...