При парсинге веб-страниц с помощью BeautifulSoup разработчики часто сталкиваются с проблемой загрязнения текста лишними символами. Веб-страницы могут содержать специфические юникод-символы, эмодзи, типографские кавычки, неразрывные пробелы и другие знаки, не входящие в стандартную таблицу ASCII. Для дальнейшей обработки данных, машинного обучения или сохранения в базы данных часто требуется очистить текст, оставив только базовые символы.
В этой статье мы подробно рассмотрим различные методы удаления не-ASCII символов из строк на Python, а также научимся интегрировать эти методы с результатами работы BeautifulSoup.
Что такое ASCII и не-ASCII символы?
ASCII (American Standard Code for Information Interchange) — это таблица кодировки, включающая 128 основных символов: латинские буквы (A-Z, a-z), цифры (0-9), знаки препинания и управляющие символы. Все остальные символы (кириллица, иероглифы, диакритические знаки, эмодзи) являются не-ASCII символами.
Например, шведская буква å не является символом ASCII. Если вы попытаетесь прочитать или сохранить строку с таким символом в строгой ASCII-кодировке, возникнет ошибка или символ будет поврежден.
Способы удаления не-ASCII символов в Python
Существует несколько эффективных подходов к очистке строк. Выбор метода зависит от объема данных, требований к производительности и логики фильтрации.
Использование методов encode и decode
Самый простой и элегантный способ избавиться от не-ASCII символов — использовать кодирование строки в ASCII с игнорированием ошибок и последующим декодированием обратно в строку.
Пример:
text = "Hello, , Привет! Good bye in Swedish is Hej då"
clean_text = text.encode("ascii", errors="ignore").decode
print(clean_text)
В этом примере параметр errors="ignore" указывает Python просто отбросить все символы, которые невозможно закодировать в ASCII. Это быстрый метод, но он удалит и кириллицу, и любые другие не-латинские символы.
Регулярные выражения (модуль re)
Модуль re предоставляет мощный метод re.sub, который позволяет заменить символы, не являющиеся ASCII, на пустую строку. Это отличный выбор, если вам нужно сохранить определенные не-ASCII символы (например, точки и пробелы), удалив все остальное.
Пример:
import re
text = "Hello, , Привет!"
clean_text = re.sub(r'[^A-Za-z0-9 .]', '', text)
print(clean_text)
Использование регулярных выражений позволяет создавать сложные условия фильтрации. Вы можете настроить шаблон так, чтобы он удалял только конкретные группы символов.
Метод str.translate
Метод str.translate является одним из самых быстрых способов удаления символов в Python. Он использует таблицу трансляции, созданную с помощью str.maketrans.
Пример:
def remove_non_ascii(string):
# Создаем таблицу трансляции, где все символы с кодом > 127 заменяются на None
trans_table = {i: None for i in range(128, 256)}
return string.translate(trans_table)
my_string = "В этой, строке, есть: разные символы."
print(remove_non_ascii(my_string))
Этот метод невероятно эффективен для очень больших текстов, так как обработка происходит на уровне C-языка Python.
Функциональный подход (filter и isalpha)
Для средних объемов данных с логически сложными условиями отлично подходит функциональный подход. Вы можете использовать встроенную функцию filter в связке с лямбда-функцией.
Пример:
text = "Hello, , Привет!"
clean_text = ''.join(filter(lambda x: ord(x) < 128, text))
print(clean_text)
Производительность этого метода обычно находится между replace и translate. Он менее оптимальен для гигантских текстов, но превосходен для решения задач со сложной логикой.
Использование модуля curses.ascii
В стандартную библиотеку Python входит модуль curses.ascii, который содержит утилиты для работы с ASCII символами. Вы можете использовать его функции для проверки символов.
Интеграция с BeautifulSoup
Пример парсинга и очистки:
from bs4 import BeautifulSoup
import re
<html><body>
<p>Привет, мир! Hello, !</p>"""
raw_text = soup.find('p').get_text
clean_text = re.sub(r'[^ -]', '', raw_text)
print(clean_text.strip)
Важное замечание: Если вы работаете с русскоязычными сайтами и вам нужно сохранить кириллицу, удалив только эмодзи или специфические юникод-символы, фильтрация по ASCII не подойдет, так как кириллица не входит в ASCII. В таких случаях нужно использовать регулярные выражения, которые будут удалять только определенные диапазоны юникода или использовать методы замены конкретных символов.
Очистка текста от не-ASCII символов — это важный этап подготовки данных. В Python существует множество инструментов для этой задачи: от простого encode("ascii", "ignore") до мощных регулярных выражений и быстрого str.translate. При работе с BeautifulSoup просто применяйте выбранный метод очистки к строкам, полученным с помощью метода get_text, и ваши данные будут чистыми и готовыми к дальнейшему использованию.