如何在Python中转换HTML为带正确换行的纯文本?
解决Telegram HTML转纯文本时的换行丢失问题
问题场景
将Telegram导出的HTML文本转换为带正确空行格式的纯文本时,现有基于BeautifulSoup的代码丢失了预期的换行结构,无法还原原始内容的段落分隔。
原始HTML文本
🧹 <b>Процесс химчистки сидений:</b> <b>1</b> - <i>Тщательно пропылесосить</i> <b>2</b> - <i>Нанести химию и немного подождать, пока она поработает</i> <i> </i><b>3</b> - <i>Пройтись щеткой, чтобы поднять загрязнения</i> <b>4</b> - <i>Тщательно прополоскать сидение экстрактором с подачей воды</i> <i> </i>#химчисткасалона #химчисткасидений
期望输出
🧹 Процесс химчистки сидений: 1 - Тщательно пропылесосить 2 - Нанести химию и немного подождать, пока она поработает 3 - Пройтись щеткой, чтобы поднять загрязнения 4 - Тщательно прополоскать сидение экстрактором с подачей воды #химчисткасалона #химчисткасидений
现有代码及问题
现有代码会移除所有空标签(包括仅含换行的<i>标签),且get_text()默认压缩空白字符,导致输出丢失空行:
from bs4 import BeautifulSoup as bs def _html_to_text(html) -> str: hrefs = [] soup = bs(html, 'lxml') for x in soup.find_all(): if len(x.get_text(strip=True)) == 0: x.extract() a_tags = soup.find_all('a', href=True) for a_tag in a_tags: href = a_tag.get('href') if href in hrefs: continue hrefs.append(href) a_tag.append(f' ({href})') return soup.get_text()
当前错误输出
🧹 Процесс химчистки сидений: 1 - Тщательно пропылесосить 2 - Нанести химию и немного подождать, пока она поработает 3 - Пройтись щеткой, чтобы поднять загрязнения 4 - Тщательно прополоскать сидение экстрактором с подачей воды #химчисткасалона #химчисткасидений
解决方案
修改后的代码
from bs4 import BeautifulSoup as bs def _html_to_text(html) -> str: hrefs = [] soup = bs(html, 'lxml') # 保留原有处理a标签的逻辑 a_tags = soup.find_all('a', href=True) for a_tag in a_tags: href = a_tag.get('href') if href in hrefs: continue hrefs.append(href) a_tag.append(f' ({href})') # 不直接移除空标签,保留其中的换行空白 for tag in soup.find_all(): tag_text = tag.get_text(strip=True) if not tag_text: tag.string = tag.get_text() # 获取带换行分隔的原始文本,不自动压缩空白 raw_text = soup.get_text(separator='\n', strip=False) # 手动整理换行结构:合并连续空白行为单个空行 lines = [] current_blank = False for line in raw_text.splitlines(): stripped_line = line.strip() if not stripped_line: if not current_blank: lines.append('') current_blank = True else: lines.append(stripped_line) current_blank = False return '\n'.join(lines)
关键修改点
- 保留空标签内的换行:不再移除仅含空白的标签,而是保留其原始空白内容,避免丢失换行结构。
- 自定义空白处理:
- 使用
get_text(separator='\n', strip=False)获取未压缩的原始文本,保留元素间的换行分隔。 - 遍历文本行,将连续的空白行合并为单个空行,同时保留内容行的独立性,最终生成符合预期的段落分隔格式。
- 使用
内容的提问来源于stack exchange,提问作者nnekkitt
相关产品推荐
相关产品推荐

