如何利用DOM提取保留格式的文本?Chrome插件提取LinkedIn职位描述格式不符
解决LinkedIn职位描述提取格式不一致的问题
问题出在textContent和innerText会丢失LinkedIn职位描述里的段落结构、列表格式和换行逻辑,而手动复制时浏览器会自动处理这些HTML元素的格式转换。以下是两种可行的解决方法:
方法1:手动遍历DOM结构,还原格式
通过递归遍历职位描述的DOM节点,根据不同标签(p、ul、ol、br等)手动添加对应的格式符号和换行,模拟浏览器复制的效果:
function extractFormattedJobDesc(node) { let result = ''; if (node.nodeType === Node.TEXT_NODE) { // 处理文本节点,去除多余空格并保留正常空格 result += node.textContent.trim().replace(/\s+/g, ' ') + ' '; return result; } if (node.nodeType !== Node.ELEMENT_NODE) return result; switch (node.tagName.toLowerCase()) { case 'p': // 段落结束后添加两个换行,模拟手动复制的段落间距 result += extractFormattedJobDesc(node.firstChild).trim() + '\n\n'; break; case 'br': // 换行标签转换为单个换行符 result += '\n'; break; case 'ul': // 无序列表每个项前加•符号 node.childNodes.forEach(li => { if (li.tagName?.toLowerCase() === 'li') { result += '• ' + extractFormattedJobDesc(li).trim() + '\n'; } }); result += '\n'; break; case 'ol': // 有序列表添加数字序号 let index = 1; node.childNodes.forEach(li => { if (li.tagName?.toLowerCase() === 'li') { result += `${index}. ` + extractFormattedJobDesc(li).trim() + '\n'; index++; } }); result += '\n'; break; default: // 其他元素(div、span等)递归处理子节点 node.childNodes.forEach(child => { result += extractFormattedJobDesc(child); }); break; } // 清理多余的换行和空格 return result.replace(/\n\s*\n/g, '\n\n').trim(); } // 使用示例:定位LinkedIn职位描述的容器元素 const jobDescContainer = document.querySelector('.description__text.description__text--rich'); if (jobDescContainer) { const formattedText = extractFormattedJobDesc(jobDescContainer); console.log(formattedText); }
方法2:模拟手动复制,直接读取剪贴板内容
利用浏览器的复制功能,将职位描述内容复制到剪贴板后再读取,这样能完全复现手动复制的格式:
async function getCopiedJobDesc(element) { // 创建选择范围并选中目标元素 const range = document.createRange(); range.selectNodeContents(element); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); try { // 执行复制操作 await document.execCommand('copy'); // 从剪贴板读取文本 const clipboardContent = await navigator.clipboard.readText(); return clipboardContent; } catch (error) { console.error('复制操作失败:', error); return null; } finally { // 取消选中状态 window.getSelection().removeAllRanges(); } } // 使用示例 const jobDescContainer = document.querySelector('.description__text.description__text--rich'); if (jobDescContainer) { getCopiedJobDesc(jobDescContainer).then(formattedText => { if (formattedText) { console.log(formattedText); } }); }
注意事项
- LinkedIn的DOM结构可能会更新,需要定期验证选择器(如
.description__text.description__text--rich)是否有效; - 使用剪贴板方法时,Chrome扩展需要在
manifest.json中声明权限:{ "permissions": ["clipboardRead", "clipboardWrite"], "host_permissions": ["https://www.linkedin.com/*"] }
内容的提问来源于stack exchange,提问作者Rasanga Lakshith
相关产品推荐
相关产品推荐

