You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Node.js网页爬取:如何提取HTML中ABCD后的JSON字符串?

最优实现思路:提取script中的ABCD字段JSON

嘿,这个需求我太熟了!爬网页遇到内嵌script里的JSON数据,其实有几种不同层级的实现方式,从快速搞定到稳健容错都有,给你拆解一下:

1. 正则表达式快速提取(适合结构稳定的场景)

如果这段script的格式不会轻易变动,正则绝对是最快的方案。我们可以精准匹配ABCD:后面的JSON数组部分,再转成对象。

代码示例:

const html = `你的HTML内容`;

// 匹配ABCD: 后面的JSON数组,兼容空格、换行的情况
const regex = /ABCD:\s*(\[.*?\])/s;
const match = html.match(regex);

if (match) {
  try {
    const abcdData = JSON.parse(match[1]);
    console.log(abcdData); // 这就是你要的JSON数组啦
  } catch (err) {
    console.error('JSON解析失败:', err);
  }
} else {
  console.log('没找到ABCD字段');
}

注意事项:

  • 正则里的s标志是让.匹配换行符,避免script代码换行导致匹配失败
  • .*?的非贪婪匹配会自动停在第一个],刚好拿到完整的数组,不会把后面的languageCode等内容包含进来

2. AST语法树解析(稳健容错,适合复杂场景)

如果怕正则因为代码格式变动(比如多了注释、变量写法调整)失效,那用JS语法解析器把script代码转成AST(抽象语法树)是更靠谱的方案,比如用acorn这个轻量库。

步骤&代码:

首先安装依赖:

npm install acorn

然后写解析逻辑:

const acorn = require('acorn');
const html = `你的HTML内容`;

// 先提取script标签里的代码内容
const scriptRegex = /<script type="text\/javascript">(.*?)<\/script>/s;
const scriptMatch = html.match(scriptRegex);

if (scriptMatch) {
  const scriptCode = scriptMatch[1];
  try {
    // 解析成AST语法树
    const ast = acorn.parse(scriptCode, { ecmaVersion: 2020 });
    
    // 遍历AST,定位到LowFareFinder构造函数的参数对象
    ast.body.forEach(node => {
      if (node.type === 'ExpressionStatement' && node.expression.type === 'CallExpression') {
        const funcExpr = node.expression.callee;
        if (funcExpr.type === 'FunctionExpression') {
          funcExpr.body.body.forEach(innerNode => {
            if (innerNode.type === 'ExpressionStatement' && innerNode.expression.type === 'NewExpression') {
              const args = innerNode.expression.arguments;
              args.forEach(arg => {
                if (arg.type === 'ObjectExpression') {
                  // 遍历对象属性,找到key为ABCD的项
                  arg.properties.forEach(prop => {
                    if (prop.key.name === 'ABCD') {
                      // 把AST节点转成JSON字符串再解析
                      const abcdJson = JSON.stringify(prop.value);
                      const abcdData = JSON.parse(abcdJson);
                      console.log('提取到的ABCD数据:', abcdData);
                    }
                  });
                }
              });
            }
          });
        }
      }
    });
  } catch (err) {
    console.error('AST解析失败:', err);
  }
}

优势:

不管script代码里有多少空格、换行、注释,只要语法正确,就能精准定位到ABCD对应的属性值,完全不怕格式变动,适合长期维护的爬虫项目。

3. 备选:Headless Browser(如果遇到动态渲染场景)

如果你的页面是需要JS渲染后才生成这段script的(不过看你提供的HTML,应该是直接返回的静态内容),那可以用Puppeteer这类无头浏览器,让页面完全渲染后再提取数据。不过这种方式性能开销大一点,适合复杂动态页。

总结

  • 要是页面结构固定不变,正则是最优解,快又简单;
  • 要是想兼顾容错性,不怕多写几行代码,AST解析是更稳健的选择。

内容的提问来源于stack exchange,提问作者אVי

火山引擎 最新活动