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

使用Puppeteer爬取HTML列表时无法获取指定元素值的问题

问题:Puppeteer爬取HTML列表时无法获取指定元素值

问题详情

尝试使用Puppeteer从HTML列表提取字符串,可成功爬取第一个div内的前两个p元素,但始终无法获取第二个div中值为“3 st”的p元素。调整CSS选择器、添加延时均无效,怀疑是选择器使用错误。

目标HTML结构

<button class="css-4od5c4 e1ttybed2">
<div class="css-1tkalz1 e3whs8q0">
<p class="css-iqfm9l enp2lf70">Sisjön</p>
<p class="css-1cwtvfm enp2lf70">Askim</p>
<div class="css-7omsg3 e3whs8q0">
<p class="css-1n26c6q enp2lf70">Välj butik</p>
</div></div>
<div class="css-177ui4i e3whs8q0">
<p class="css-iqfm9l enp2lf70">3 st</p></div>
</button>

<button class="css-4od5c4 e1ttybed2">
<div class="css-1tkalz1 e3whs8q0">
<p class="css-iqfm9l enp2lf70">random address...</p>
<p class="css-1cwtvfm enp2lf70">some city...</p>
<div class="css-7omsg3 e3whs8q0">
<p class="css-1n26c6q enp2lf70">Välj butik</p>
</div></div>
<div class="css-177ui4i e3whs8q0">
<p class="css-iqfm9l enp2lf70">3 st</p></div>
</button>

原代码

//Wait for list to stores to load then map store content

await page.waitForSelector('.css-4od5c4');

const storesData = await page.evaluate(async () => {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  
  const stores = Array.from(document.querySelectorAll('.css-4od5c4 .css-1tkalz1'));
  const data = stores.map((item) => {
      const address = item.querySelector('.css-1tkalz1 .css-iqfm9l').textContent.trim();
      const city = item.querySelector('.css-1tkalz1 .css-1cwtvfm').textContent.trim();
      const amountElement = item.querySelector('.css-177ui4i.e3whs8q0 p.css-iqfm9l.enp2lf70');
      const amount = amountElement ? amountElement.textContent.trim() : 'no value';

      return {
          address,
          city,
          amount
      };
  });

  return data;
});

console.log(storesData)

当前返回结果

[
 {
    address: 'random address...',
    city: 'some city...',
    amount: 'no value'
  },
  {
    address: 'random address...',
    city: 'some city...',
    amount: 'no value'
  },
]

期望结果

[ 
 {
    address: 'random address...',
    city: 'some city...',
    amount: '3 st'
  },
  {
    address: 'random address...',
    city: 'some city...',
    amount: '3 st'
  },
]

问题原因与解决方案

核心错误

  1. 选择器范围错误:原代码中stores选中的是.css-4od5c4 .css-1tkalz1(每个按钮下的第一个div),但目标数量元素所在的.css-177ui4i是和.css-1tkalz1同级的元素(都属于按钮节点),因此在item(即.css-1tkalz1元素)内部无法找到.css-177ui4i元素。
  2. 冗余选择器:获取地址和城市时,item本身就是.css-1tkalz1元素,选择器无需重复添加.css-1tkalz1前缀。

修正后的代码

await page.waitForSelector('.css-4od5c4');

const storesData = await page.evaluate(() => {
  // 直接选中每个按钮元素,而非按钮内的子div
  const stores = Array.from(document.querySelectorAll('.css-4od5c4'));
  const data = stores.map((item) => {
      // 从按钮内的信息div中提取地址和城市
      const infoContainer = item.querySelector('.css-1tkalz1');
      const address = infoContainer.querySelector('.css-iqfm9l').textContent.trim();
      const city = infoContainer.querySelector('.css-1cwtvfm').textContent.trim();
      
      // 从按钮内的数量div中提取数值
      const amountElement = item.querySelector('.css-177ui4i .css-iqfm9l');
      const amount = amountElement ? amountElement.textContent.trim() : 'no value';

      return {
          address,
          city,
          amount
      };
  });

  return data;
});

console.log(storesData);

额外优化说明

  • 移除了page.evaluate内部的setTimeout:page.waitForSelector('.css-4od5c4')已经确保所有按钮元素加载完成,无需额外延时等待。
  • 简化了选择器逻辑,避免冗余前缀,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:37:27