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

使用Node.js Puppeteer爬取船舶数据返回null问题求助

问题原因
  • 页面等待时机错误:你使用waitUntil: "domcontentloaded"作为页面加载完成的判断条件,但目标网站的船舶列表是动态渲染的,DOM结构加载完成时,列表数据还没有渲染到页面上,此时选中的td元素没有对应的data-value属性,所以返回null。
  • 缺少显式等待逻辑:没有校验目标元素是否真的加载完成就执行了提取逻辑,大概率提取到的是页面初始的骨架屏占位元素。
  • 可能存在反爬识别:目标网站可能识别到爬虫请求,返回了未加载数据的空白页面。
修复方案

1. 调整页面加载与等待逻辑

将domcontentloaded替换为等待网络空闲的networkidle2,同时增加显式等待,直到目标td元素携带data-value属性渲染完成后再执行提取操作。

2. 增加反爬伪装

设置正常的浏览器User-Agent,避免被网站反爬策略拦截。

3. 增加非空判断

提取属性前判断元素是否存在,避免后续网站结构变动时报错。

修改后的核心代码(class.js的main方法)
async main() {
  // 配置正常浏览器UA,伪装成真实用户访问
  await this.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
  // 调整页面加载等待策略,等待网络空闲2次后再判定加载完成
  await this.page.goto(this.url, { waitUntil: "networkidle2", timeout: 30000 });
  // 显式等待目标元素加载完成,最多等待10秒
  await this.page.waitForSelector('tbody > tr td:nth-child(4)[data-value]', { timeout: 10000 });

  this.standings = await this.page.evaluate(() =>
    Array.from(document.querySelectorAll("tbody > tr")).map(team => {
      const col4 = team.querySelector("td:nth-child(4)");
      const col6 = team.querySelector("td:nth-child(6)");
      return [
        col4 ? col4.getAttribute("data-value") : null,
        col6 ? col6.getAttribute("data-value") : null
      ]
    })
  );
  this.writeToJson();
}
额外调试方案

如果修改后仍返回null,可在目标网站的浏览器控制台手动运行以下代码,校验选择器是否正确:

Array.from(document.querySelectorAll("tbody > tr")).map(team => [
  team.querySelector("td:nth-child(4)")?.getAttribute("data-value"),
  team.querySelector("td:nth-child(6)")?.getAttribute("data-value")
])

如果控制台运行结果正确,说明还有反爬策略未绕过,可进一步增加模拟滚动、延迟等待等逻辑;如果控制台运行结果也为null,说明网站结构已更新,调整nth-child的序号匹配实际列位置即可。

内容的提问来源于stack exchange,提问作者Afrin Gaffar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:27:04