返回
HTML逆向生成Markdown -- Part 1
前端
2024-01-29 14:26:44
序言
回想此前致力于将网页文章提取并转译为Markdown格式的Chrome插件构想,促成了“HTML逆向生成Markdown”项目的诞生。低估了解析难度的我,在耗费十余日后仅完成了一个半成品,遂决定暂时搁置。现将实现思路记录于此,待日后技艺精进再行完善。
解析过程可划分为四个阶段,现简要说明如下:
阶段一:解析HTML结构
- 利用DOM解析器获取HTML结构
- 识别并提取文章正文部分
- 清理无用标记和冗余内容
阶段二:识别文本块
- 将文章正文划分为段落、标题、列表等文本块
- 对文本块进行语义分析,识别其类型和层级关系
阶段三:提取文本内容
- 从文本块中提取纯文本内容
- 处理特殊字符和转义序列
- 移除不必要的空白和换行符
阶段四:生成Markdown语法
- 根据文本块类型和层级关系,生成相应的Markdown语法
- 添加必要的换行符和空白以提高可读性
- 完成Markdown文档生成
需要注意的是,由于HTML的复杂性和多样性,解析过程可能存在挑战。例如,某些网站可能使用复杂的布局或动态加载技术,需要采取相应的策略来处理。
阶段一:解析HTML结构
以下是阶段一中使用的关键步骤:
- 加载HTML内容: 使用外部库或内置函数加载HTML文档
- 获取DOM结构: 将HTML文档解析为DOM树
- 识别正文部分: 使用CSS选择器或特定算法识别文章正文所在的区域
- 清理无用内容: 移除导航栏、侧边栏、页脚等无关内容
示例代码:
const cheerio = require('cheerio');
const html = '<html><body><div id="main-content">...</div></body></html>';
const $ = cheerio.load(html);
const mainContent = $('#main-content').html();
阶段二:识别文本块
在阶段二中,我们将采用以下步骤:
- 划分子段落: 使用段落标记(
)将正文划分为段落
- *识别 ** 提取列表:**识别有序列表(
- )和无序列表(
- )及其子项
- 语义分析: 对文本块进行语义分析以识别其类型和层级
示例代码:
const paragraphs = $('p');
const headings = $('h1, h2, h3');
const lists = $('ol, ul');
阶段三:提取文本内容
在阶段三中,我们将:
- 提取纯文本: 从文本块中提取纯文本内容
- 处理特殊字符: 将特殊字符(如&、<)转换为实体引用
- 移除不必要内容: 移除不必要的空白和换行符
示例代码:
const text = paragraphs.text();
text = text.replace(/&/g, '&');
text = text.replace(/</g, '<');
阶段四:生成Markdown语法
最后,在阶段四中,我们将:
- *生成Markdown ** 生成Markdown段落:**生成Markdown段落(换行符+文本)
- 生成Markdown列表: 生成Markdown列表(-、*、数字)
- 完成Markdown文档: 将所有Markdown元素组合成完整的Markdown文档
示例代码:
const markdown = `# ${headings[0].text()}\n\n`;
markdown += `${paragraphs.map(p => '- ' + p.text()).join('\n')}\n`;
markdown += `${lists.map(l => '- ' + l.text()).join('\n')}`;
结语
虽然“HTML逆向生成Markdown”项目仍是一个半成品,但其思路和实现细节值得记录。期待在未来的某个时间点,能够将其完善为一个功能齐全的工具。