在Javascript中从HTML中提取文本的更好方法

Better way of extracting text from HTML in Javascript

本文关键字:取文本 更好 方法 提取 Javascript 中从 HTML      更新时间:2023-09-26

我正在尝试使用container.innerText || container.textContent从HTML字符串中抓取文本,其中container是我要从中提取文本的元素。

通常,我要提取的文本位于<p>标签中。因此,以下面的HTML为例:

<div id="container">
    <p>This is the first sentence.</p>
    <p>This is the second sentence.</p>
</div>

var container = document.getElementById("container");
var text = container.innerText || container.textContent; // the text I want

将返回This is the first sentence.This is the second sentence.,第一个句点和第二个句号的开头之间没有空格。

我的总体目标是使用 Stanford CoreNLP 解析文本,但它的解析器无法检测到这是 2 个句子,因为它们没有用空格分隔。有没有更好的方法从HTML中提取文本,使句子用空格字符分隔?

我正在解析的 HTML 将主要在<p>标签中包含我想要的文本,但 HTML 也可能包含嵌入在<p>标签之间的<img><a>和其他标签。

作为一个肮脏的黑客,尝试使用这个:

container.innerHTML.replace(/<.*?>/g," ").replace(/ +/g," ");

这将用空格替换所有标签,然后将多个空格折叠为一个空格。

请注意,如果属性值中有>,这会让您感到困惑。避免此问题将需要更复杂的解析,例如遍历所有文本节点并将它们放在一起。


更长但更稳健的方法:

function recurse(result, node) {
    var c = node.childNodes, l = c.length, i;
    for( i=0; i<l; i++) {
        if( c[i].nodeType == 3) result += c.nodeValue + " ";
        if( c[i].nodeType == 1) result = recurse(result, c[i]);
    }
    return result;
}
recurse(container);

假设我没有犯一个愚蠢的错误,这将对文本节点执行深度优先搜索,并将它们的内容附加到结果中。

jQuery具有方法text()可以执行所需的操作。这对你有用吗?

我不确定它是否适合您容器中的所有内容,但它在我的示例中有效。它还将获取 <a> -tag 的文本并将其附加到文本中。

更新 20.12.2020

如果你没有使用jQuery。你可以像这样用vanilla js实现text方法:

const nodes = Array.from(document.querySelectorAll("#container"));
const text = nodes
  .filter((node) => !!node.textContent)
  .map((node) => node.textContent)
  .join(" ");

使用 querySelectorAll("#container") 获取容器中的每个节点。使用 Array.from,因此我们可以使用 Array 方法,如 filter、map 和 join。

最后,通过过滤掉没有textContent的元素来生成文本。然后使用 map 获取每个文本,并使用联接在文本之间添加空格分隔符。

$(function() {
    var textToParse = $('#container').text();
    $('#output').html(textToParse);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
    <p>This is the first sentence.</p>
    <p>This is the second sentence.</p>
    <img src="http://placehold.it/200x200" alt="Nice picture"></img>
    <p>Third sentence.</p>
</div>
<h2>output:</h2>
<div id="output"></div>

您可以使用以下函数提取和处理文本,如下所示。它基本上会遍历目标元素的所有子节点和子节点的子节点,依此类推......在适当的点添加spaces

function getInnerText( sel ) {
    var txt = '';
    $( sel ).contents().each(function() {
        var children = $(this).children();
        txt += ' ' + this.nodeType === 3 ? this.nodeValue : children.length ? getInnerText( this ) : $(this).text();
    });
    return txt;
}

function getInnerText( sel ) {
  var txt = '';
  $( sel ).contents().each(function() {
    var children = $(this).children();
    txt += ' ' + this.nodeType === 3 ? 
      this.nodeValue : children.length ? 
      getInnerText( this ) : $(this).text();
  });
  return txt;
}
alert( getInnerText( '#container' ) );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
    Some other sentence
    <p>This is the first sentence.</p>
    <p>This is the second sentence.</p>
</div>

你可以使用 jQuery 向下遍历元素。


这是代码:

$(document).ready(function()
{
    var children = $("#container").find("*");
    var text = "";
    while (children.html() != undefined)
    {
        text += children.html()+"'n";
        children = children.next();
    }
    alert(text);
});



这是小提琴:http://jsfiddle.net/69wezyc5/