You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Node.js和ScraperAPI抓取F1网站数据并转换为JSON时的解析问题求助

使用Node.js和ScraperAPI抓取F1网站数据并转换为JSON时的解析问题求助

看起来你已经搭好了基础的API框架,但在数据解析这一步卡壳了——返回的内容不是预期的JSON,反而像是未正确处理的原始内容对吧?让我们一步步排查问题根源,给出针对性的修复方案:

核心问题分析

从你的代码里能看到几个关键错误,这是导致解析失败的主要原因:

  1. generateApiKey函数调用错误
    你定义的generateApiKey函数需要传入apiKey参数才能生成合法的ScraperAPI前缀,但在拼接请求URL时,你直接写了${generateApiKey}——这会把函数本身的字符串表示(比如function (apiKey) { ... })拼接到URL里,而不是生成正确的请求地址。ScraperAPI接收到错误的请求格式,自然无法执行autoparse=true的解析指令。

  2. 缺少响应解析配置
    即使ScraperAPI返回了JSON格式的响应,request-promise默认不会自动把响应解析为JSON对象,需要显式配置相关选项来触发自动解析。

修正后的完整代码

下面是修复了所有问题的代码,我会标注关键修改点:

const express = require("express");
const request = require("request-promise");

const app = express();
const PORT = process.env.PORT || 5000;

// 函数定义保持不变
const generateApiKey = (apiKey) => `http://api.scraperapi.com?api_key=${apiKey}&autoparse=true`

app.use(express.json());

app.get("/f1", async (req, res) => {
  const { apiKey } = req.query;
  try {
    // 修复1:正确调用generateApiKey函数,传入用户提供的apiKey参数
    const scraperBaseUrl = generateApiKey(apiKey);
    const targetUrl = "https://www.formula1.com/en/teams/ferrari";
    // 修复2:用encodeURIComponent处理目标URL,避免特殊字符破坏请求结构
    const fullRequestUrl = `${scraperBaseUrl}&url=${encodeURIComponent(targetUrl)}`;
    
    // 调试用:开发环境可以打印完整URL,确认格式是否符合ScraperAPI要求
    console.log("完整请求URL:", fullRequestUrl);

    // 修复3:给request-promise添加json: true选项,自动解析JSON响应
    const response = await request({
      uri: fullRequestUrl,
      json: true, // 关键配置:让库自动把响应转为JSON对象
      resolveWithFullResponse: false // 只返回响应体,默认值,可显式声明
    });
    
    res.json(response);
  } catch (error) {
    console.error("数据抓取错误:", error);
    // 优化错误返回:生产环境避免暴露敏感错误细节
    res.status(500).json({ 
      error: "数据抓取或解析失败", 
      details: process.env.NODE_ENV === "development" ? error.message : undefined 
    });
  }
});

app.listen(PORT, () => console.log(`服务器运行在端口 ${PORT}`));

关键修改点说明

  1. 修复函数调用逻辑:通过generateApiKey(apiKey)生成合法的ScraperAPI请求前缀,确保请求格式符合平台要求。
  2. URL编码处理:用encodeURIComponent对目标URL进行编码,避免URL中的特殊字符(如&、=)破坏ScraperAPI的请求参数结构。
  3. 自动解析JSON配置:添加json: true选项后,request-promise会自动将响应体解析为JSON对象,无需手动调用JSON.parse。
  4. 安全的错误返回:生产环境下只返回通用错误信息,避免暴露服务器的敏感错误细节。

额外调试与优化建议

  1. 验证ScraperAPI请求格式:开发环境打印拼接后的完整URL,复制到浏览器或Postman直接访问,确认ScraperAPI是否返回了预期的JSON数据。如果直接访问也不是JSON,需要检查ScraperAPI的autoparse功能是否正常,或目标页面是否支持自动解析。
  2. 检查ScraperAPI控制台:登录ScraperAPI管理后台,查看请求的状态码和响应详情,确认请求是否成功,有没有触发反爬限制。
  3. 替换弃用的request-promise:request-promise已经被官方弃用,不再维护,推荐使用更现代的库如axios或node-fetch。下面是用axios实现的稳定版本:
const express = require("express");
const axios = require("axios");

const app = express();
const PORT = process.env.PORT || 5000;

const generateApiKey = (apiKey) => `http://api.scraperapi.com?api_key=${apiKey}&autoparse=true`

app.use(express.json());

app.get("/f1", async (req, res) => {
  const { apiKey } = req.query;
  try {
    const scraperBaseUrl = generateApiKey(apiKey);
    const targetUrl = "https://www.formula1.com/en/teams/ferrari";
    const fullRequestUrl = `${scraperBaseUrl}&url=${encodeURIComponent(targetUrl)}`;
    
    const response = await axios.get(fullRequestUrl, {
      responseType: "json" // 明确指定响应类型为JSON
    });
    
    res.json(response.data);
  } catch (error) {
    console.error("数据抓取错误:", error);
    res.status(500).json({ 
      error: "数据抓取或解析失败", 
      details: process.env.NODE_ENV === "development" ? error.message : undefined 
    });
  }
});

app.listen(PORT, () => console.log(`服务器运行在端口 ${PORT}`));

极端情况处理

如果ScraperAPI的autoparse=true仍然无法正确解析F1网站的页面(可能因为页面结构复杂或动态渲染),你可以考虑使用cheerio库手动解析HTML内容,提取需要的数据并构造自定义的JSON响应。

备注:内容来源于stack exchange,提问作者TinoOo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 14:23:00