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

Puppeteer仅在headless模式下报错:Cannot read properties of undefined (reading 'getProperty')

Puppeteer无头模式(headless: true)抓取失败的解决办法

问题场景

调试Puppeteer配置时,设置puppeteer.launch({ headless: false });无报错,但切换到理想的headless: true模式时,数据抓取失败,报错信息如下:

Logging into user...
Logged in!
Fetching username...
TypeError: Cannot read properties of undefined (reading 'getProperty')
    at D:\boody\Programming\blxscrape\src\index.ts:40:27
    at Generator.next (<anonymous>)
    at fulfilled (D:\boody\Programming\blxscrape\src\index.ts:5:58)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)

涉及的核心代码片段:

// username 
  await console.log('Fetching username...');
  const [el]: any = await page.$x('/html/body/div[3]/main/div[2]/div[2]/div/div[1]/div/div[2]/div[2]/div[1]/div[2]');
  let txt: any = await el.getProperty('textContent');
  const usernameTxt: string = await txt.jsonValue();

  // desc
  await console.log('Fetching description...');
  const [el2]: any = await page.$x('/html/body/div[3]/main/div[2]/div[2]/div/div[3]/div/div[1]/div[1]/div[2]/div/pre/span');
  const descTxt: string = await page.evaluate((el2: any) => el2.textContent, el2);

  // profile picture 
  await console.log('Fetching profile picture...');
  const [el3]: any = await page.$x('/html/body/div[3]/main/div[2]/div[2]/div/div[1]/div/div[2]/div[1]/span/thumbnail-2d/span/img');
  const src: any = await el3.getProperty('src');
  const pfpUrl: string = await src.jsonValue();

  const data: object = {usernameTxt, descTxt, pfpUrl};

  console.log(data);

  browser.close();
}

scrape('https://www.roblox.com/users/64004875/profile', process.env.USER, process.env.PASS);

解决办法

1. 增加元素加载等待逻辑

无头模式下页面渲染、资源加载速度和有头模式存在差异,直接获取元素可能遇到元素未加载完成的情况。在每个元素获取前,添加waitForXPath等待元素出现:

// 等待用户名元素加载
await page.waitForXPath('/html/body/div[3]/main/div[2]/div[2]/div/div[1]/div/div[2]/div[2]/div[1]/div[2]');
const [el]: any = await page.$x('/html/body/div[3]/main/div[2]/div[2]/div/div[1]/div/div[2]/div[2]/div[1]/div[2]');

// 等待描述元素加载
await page.waitForXPath('/html/body/div[3]/main/div[2]/div[2]/div/div[3]/div/div[1]/div[1]/div[2]/div/pre/span');
const [el2]: any = await page.$x('/html/body/div[3]/main/div[2]/div[2]/div/div[3]/div/div[1]/div[1]/div[2]/div/pre/span');

// 等待头像元素加载
await page.waitForXPath('/html/body/div[3]/main/div[2]/div[2]/div/div[1]/div/div[2]/div[1]/span/thumbnail-2d/span/img');
const [el3]: any = await page.$x('/html/body/div[3]/main/div[2]/div[2]/div/div[1]/div/div[2]/div[1]/span/thumbnail-2d/span/img');

2. 配置无头浏览器模拟正常环境

部分网站会检测无头浏览器特征,导致页面渲染异常或拦截请求。调整launch配置,让无头浏览器更接近正常浏览器:

puppeteer.launch({
  headless: true,
  args: [
    '--window-size=1920,1080',
    '--disable-blink-features=AutomationControlled',
    '--no-sandbox',
    '--disable-setuid-sandbox'
  ],
  defaultViewport: { width: 1920, height: 1080 },
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
});

3. 增加元素存在性判断

在调用getProperty或evaluate前,先判断元素是否存在,避免因元素未找到导致的报错:

// 用户名处理
if (el) {
  let txt: any = await el.getProperty('textContent');
  const usernameTxt: string = await txt.jsonValue();
} else {
  console.error('未找到用户名元素');
}

// 描述处理
if (el2) {
  const descTxt: string = await page.evaluate((el2: any) => el2.textContent, el2);
} else {
  console.error('未找到描述元素');
}

// 头像处理
if (el3) {
  const src: any = await el3.getProperty('src');
  const pfpUrl: string = await src.jsonValue();
} else {
  console.error('未找到头像元素');
}

4. 登录后增加等待逻辑

登录完成后,页面可能仍在跳转或加载状态,不要立刻执行抓取操作。可以等待页面导航完成,或等待某个登录后才会出现的元素:

// 登录操作完成后,等待页面导航
await page.waitForNavigation({ waitUntil: 'networkidle2' });
// 或者等待某个标志性元素
await page.waitForSelector('某个登录后显示的选择器');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:25:00