CheerioJS 解析脚本标签上的数据

Posted

技术标签:

【中文标题】CheerioJS 解析脚本标签上的数据【英文标题】:CheerioJS to parse data on script tag 【发布时间】:2022-01-15 12:02:16 【问题描述】:

我一直在尝试使用cheerio解析脚本标签中的数据,但是由于以下原因很难。

由于 html-entities 无法解析生成为 JSON 的字符串

更多信息:

另外让我感到奇怪的是,您必须再次将内容重新加载到 Cheerio 中才能获取文本。

欢迎您分叉此副本或复制并粘贴代码以自己尝试 https://replit.com/@Graciasc/Cheerio-Script-Parse

const cheerio = require('cheerio')
const decode = require('html-entities')
const html = `
<body>

 <script type="text/javascript"src="/data/common.0e95a19724a68c79df7b.js"></script>

<script>require("dynamic-module-registry").set("from-server-context", JSON.parse("\x7B\x22data\x22\x3A\x7B\x22available\x22\x3Atrue,\x22name\x22\x3A"Gracias"\x7D\x7D"));</script> 

</body>
`;
  const $ = cheerio.load(html, 
    decodeEntities: false,
  );
  const text = $('body').find('script:not([type="text/javascript"])');
  const cheerioText = text.eq(0).html();

  //implement a better way to grab the string
  const scriptInfo = cheerio.load(text.eq(0).html()).text();
    const regex = new RegExp(/^.*?JSON.parse\(((?:(?!\)\);).)*)/);
    const testing = regex.exec(scriptInfo)[1];

  // real output: 
//\x7B\x22data\x22\x3A\x7B\x22available\x22\x3Atrue,\x22name\x22\x3A"Gracias"\x7D\x7D when logged
    console.log(testing)

    // Not Working
    const json = JSON.parse(testing)

   
    const decoding = decode(testing)
    // same output as testing
    console.log(decoding)
   
// Not working
    console.log('decode', JSON.parse(decoding))
//JSON
 Data:  available: true, name: 'Gracias'  

【问题讨论】:

【参考方案1】:

一个干净的解决方案是使用 JSDOM

repl.it 链接(https://replit.com/@Graciasc/Cheerio-Script-Parse#index.js)

const  JSDOM  = require('jsdom')

const dom = new JSDOM(`<body>

 <script type="text/javascript"src="/data/common.0e95a19724a68c79df7b.js"></script>

<script>require("dynamic-module-registry").set("from-server-context", JSON.parse("\x7B\x22data\x22\x3A\x7B\x22available\x22\x3Atrue,\x22name\x22\x3A"Gracias"\x7D\x7D"));</script> 

</body>`)


const serializedDom = dom.serialize()

const regex = new RegExp(/^.*?JSON.parse\("((?:(?!"\)\);).)*)/gm);
const jsonString = regex.exec(serializedDom)[1];


console.log(JSON.parse(jsonString))
// output:  data:  available: true, name: 'Gracias'  


【讨论】:

以上是关于CheerioJS 解析脚本标签上的数据的主要内容,如果未能解决你的问题,请参考以下文章

Cheeriojs 遍历 xml 响应

浏览器如何准确解析脚本标签?

bzoj1232[Usaco2008Nov]安慰奶牛cheer*

BZOJ1232[Usaco2008Nov]安慰奶牛cheer 最小生成树

bzoj 1232 [Usaco2008Nov]安慰奶牛cheer

洛谷 P2916 [USACO08NOV]为母牛欢呼Cheering up the C…