Извлечение текстовых тегов по порядку - как это можно сделать? - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь найти весь текст вместе с родительским тегом в HTML. В приведенном ниже примере переменная с именем html содержит образец HTML, из которого я пытаюсь извлечь теги и текст. Это отлично работает и, как и ожидалось, выдает tags с text

Здесь я использовал cheerio для обхода DOM. cheerio работает точно так же, как jquery.

const cheerio = require("cheerio");

const html = `
                    <html>
                <head></head>
                <body>
                <p>
                  Regular bail is the legal procedure through which a court can direct 
                  release of persons in custody under suspicion of having committed an offence, 
                  usually on some conditions which are designed to ensure 
                  that the person does not flee or otherwise obstruct the course of justice. 
                  These conditions may require executing a “personal bond”, whereby a person
                  pledges a certain amount of money or property which may be forfeited if 
                  there is a breach of the bail conditions. Or, a court may require
                  executing a bond “with sureties”, where a person is not seen as 
                  reliable enough and may have to present 
                  <em>other persons</em> to vouch for her, 
                  and the sureties must execute bonds pledging money / property which 
                  may be forfeited if the accused person breaches a bail condition.
                </p>
                </body>
            </html>

`;

const getNodeType = function (renderedHTML, el, nodeType) {
    const $ = cheerio.load(renderedHTML)

    return $(el).find(":not(iframe)").addBack().contents().filter(function () {
        return this.nodeType == nodeType;
    });
}

let allTextPairs = [];
const $ = cheerio.load(html);
getNodeType(html, $("html"), 3).map((i, node) => {
            const parent = node.parentNode.tagName;
            const nodeValue = node.nodeValue.trim();
            allTextPairs.push([parent, nodeValue])
});

console.log(allTextPairs);

как показано ниже

введите описание изображения здесь

Но проблема в том, что извлеченные текстовые теги не в порядке. Если вы видите приведенный выше снимок экрана, в конце было сообщено о other persons, хотя это должно произойти до to vouch for her .... Почему это происходит? Как я могу этого избежать?

1 Ответ

0 голосов
/ 05 августа 2020

Возможно, вы захотите просто пройтись по дереву по глубине. Функция прогулки любезно предоставлена ​​ this gist .

function walk(el, fn, parents = []) {
  fn(el, parents);
  (el.children || []).forEach((child) => walk(child, fn, parents.concat(el)));
}
walk(cheerio.load(html).root()[0], (node, parents) => {
  if (node.type === "text" && node.data.trim()) {
    console.log(parents[parents.length - 1].name, node.data);
  }
});

Это распечатывает материал, но вы могли бы с таким же успехом поместить его в свой массив.

...