javascript - 如何使用cheerio js检查元素是否具有重复的属性

标签 javascript node.js cheerio

我正在用cheerio解析HTML文件(稍后用Mocha进行测试),这些文件中的HTML元素可以有很多属性,我想检查这些属性是否在同一元素中重复:

包含具有重复“class”属性的元素的示例部分文件:

<div class="logo-center" data-something-very-long="something long" ... class="logo" data-more-stuff>

这是加载文件的代码:

var fileContents = fs.readFileSync(file, "utf8");
var $ = cheerio.load(fileContents);

注意:它不一定是类属性,它可以是任何其他重复的属性。

最佳答案

再次解析被测元素。为了实现这一点,您需要深入研究 Cheerio/htmlparser2 生成的原始 DOM 对象。它使用 domhandler 记录的属性,但不适用于cheerio,因此可能需要注意版本。我已经测试过

└─┬ cheerio@1.0.0-rc.1 
  ├─┬ htmlparser2@3.9.2 
  │ ├── domhandler@2.4.1 

我已经制定了这种 ES6 风格,但您可以使用更旧的、更传统的结构轻松地做到同样的事情。

不过,RegExp 可能需要一些改进,具体取决于您对正在测试的文件的期望。

const fileContents = fs.readFileSync(file, "utf8");
const $ = cheerio.load(fileContents, {
  useHtmlParser2: true,
  withStartIndices: true,
  withEndIndices: true
});

function getDuplicateAttributes ($elem) {
    const dom = $elem.get(0);

    // identify tag text position in string
    const start = dom.startIndex;
    const end = dom.children.length ? dom.children[0].startIndex : dom.endIndex + 1;
    // extract
    const html = fileContents.slice(start, end);

    // generator function loops through all attribute matches on the html string
    function* multivals (attr) {
        const re = new RegExp(`\\s${attr}="(.*?)"`, 'g');
        let match;
        while((match = re.exec(html)) !== null) {
            // yield each property value found for the attr name
            yield match[1];
        }
    }

    // the DOM will contain all attribute names once
    const doubleAttributeList = Object.keys(dom.attribs)
       // compound attribute names with all found values
      .map((attr) => {
           const matchIterator = multivals(attr);
           return [attr, Array.from(matchIterator)];
      })
      // filter for doubles
      .filter((entry) => entry[1].length > 1);

    return new Map(doubleAttributeList);
}

您还没有说明找到 double 后要做什么,因此它们只是被退回。

关于javascript - 如何使用cheerio js检查元素是否具有重复的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44336016/

相关文章:

mysql - 在 sequelize.athenticate() 上使用 await 时,Node.js 脚本不会结束

javascript - 有没有简单的方法从页面上的 td 元素获取数组? (node.js/cheerio/jQuery)

javascript - 使用cheerio获取html中的元素名称

javascript - 当用户到达页面右侧时加载新内容

javascript - 如何从数组中的外部文件加载数据

javascript - 评估以字符串形式给出的函数调用,该字符串使用 'require' 声明

javascript - NodeJS Redis session 不会通过浏览器重定向持续存在

javascript - 如何使用 microapps Node.js 模块处理 Shopify 的 API 调用限制

javascript - 在 Node 中抓取 .aspx 页面

javascript - 这个数组排序功能实际上是如何工作的?