Работа с нечитаемыми символами в текстовых файлах
- В файлах встречаются символы, нечитаемые ни в одной кодировке.
Например, есть csv файл с табличными данными и со столбцом, содержащим текстовую информацию, например, чат. В чате могут встретится символы (например, смайлик), которые не читаются с помощью библиотеки Pandas ни в одной кодировке. Прочитаем файл с нечитаемыми символами и разделим его на части.
# Импортируем необходимые библиотеки:
import io
import itertools
import csv
import pandas as pd
# Создадим пустые списки для данных и для заголовков:
data, head = [ ] , [ ]
href_f = ‘primer.csv’ # Ссылка на файл
k = len(open(href_f,encoding='utf-8-sig', errors = 'ignore').readlines()) # количество строк в файле
result_df=pd.DataFrame()
with io.open(href_f, encoding = 'utf-8-sig', errors = 'ignore') as f:
mycsv=csv.reader( f , delimiter="~")
for raw in itertools.islice(mycsv,0,1,1): # итерация для извлечения заголовка
raw_text='~'.join(raw)
head.append(raw_text.split('~'))
for raw in itertools.islice(mycsv,0,k,1): # цикл чтения файла построчно, с шагом и с определённого
# места. На данном шаге если файл большой, можно разбивать его на части.
raw_text='~ '.join(raw)
data.append(raw_text.split('~'))
result_df=pd.DataFrame(data)
result_df.columns=head
result_df
При таком способе нечитаемые символы игнорируются, а для дальнейшей обработки создаются несколько датафреймов
- В тексте встречаются символы, читаемые в одной кодировке, но не читаемые в другой.
Примерами таких символов могут быть смайлики или греческие буквы. Такая задача может встретится, когда требуется из кодировки Юникода перекодировать в СР-1251 для импорта данных на Microsoft SQL Server. Ниже код, с помощью которого можно перекодировать символы.
Для начала определим две функции: первая заменяет один нечитаемый символ, вторая заменяет группу символов. Каждая функция обрабатывает одну из ошибок декодирования:
А) codec can’t encode character…
В таком случае для замены одного символа функция принимает строку и текст первой возможной ошибки, возникшей при декодировании.
Перед определением функции объявим глобальную переменную.
global replace_parts # глобальная переменная для хранения непечатных символов
replace_parts = []
def ex(e, line):
to_replace = re.findall(r"codec can't encode character\s(.*?)\s", str(e)) [0]
if to_replace not in replace_parts:
replace_parts.append(to_replace) # добавляем в список не печатный символ
for to_replace in replace_parts: # бежим по всему спиcку и делаем замену
line = re.sub('\\'+to_replace.replace('\\', '').replace("'", ''), '', line)
return lin
Б) codec can’t encode characters in position…
Для замены группы символов функция принимает строку и текст второй возможной ошибки, возникшей при декодировании.
def ex2(e,line):
to_replace = re.findall(r"codec can't encode characters in position\s(.*?)\s", str(e))[0]
to_replace_arr = to_replace.replace(':', '').split('-')
line = line[:int(to_replace_arr[0])] + line[int(to_replace_arr[1])+1:]
return line
Ниже приведён сам код, который перекодирует построчно файл из utf-8 в cp1251
file_csv_name = ‘primer.csv’ # Ссылка на исходный файл
file_end_name = ‘out.txt’ # Ссылка на новый файл
with open(file_csv_name, 'r', encoding = 'utf-8') as rp: # открытие исходного файла для чтения
with open(file_end_name, 'w', encoding = 'cp1251') as fw: # открытие нового файла для записи
for tgt_line in rp: # построчный цикл
q = 0
line = tgt_line
while q == 0: цикл работает, пока не избавимся от ошибок
try: # декодирование строки, если ошибки нет, идем дальше
line = bytes(line, 'cp1251').decode('cp1251', 'ignore')
fw.writelines(line) # записываем строку в новый файл
q = 1
i = i + 1
except Exception as e: # если одна из двух ошибок произошла
if 'characters in position' in str(e):
try:
line = ex2(e,line)
line = bytes(line, 'cp1251').decode('cp1251', 'ignore')
fw.writelines(line)
q = 1
except:
q = 0
else:
try:
line = ex(e,line)
line = bytes(line, 'cp1251').decode('cp1251', 'ignore')
fw.writelines(line)
q = 1
except:
q = 0
Для демонстрации работы кода покажем, какие строчки в файле поменяются. Строка в текстовом файле «……Қ12…..» Строка ошибки: ‘charmap’ codec can’t encode character ‘\xcb’ in position 326: character maps to <undefined>. В итоге символ Қ у нас заменится на пустое место.
Итак, в этом посте были рассмотрены несколько способов чтения текстовых файлов формата csv, при наличии в них нечитаемых или не декодируемых символов.
https://t.me/python_job_interview – python собеседование