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

使用Puppeteer获取亚马逊商品页全新商品卖家数量时,点击.olp-text-box选择器报错的问题咨询

Puppeteer无法找到亚马逊商品页面的.olp-text-box选择器,报错"No node found for selector"

我正尝试用Puppeteer获取亚马逊商品页面中仅售全新商品的卖家数量,但点击第一个按钮选择器.olp-text-box时总是报错:Puppeteer Error: No node found for selector: .olp-text-box。以下是我的代码,希望能得到解决思路:

const pupUrl = 'https://www.amazon.com/dp/' + req.body.asinIdInput;
async function configureBrowser(){ 
  const browser = await puppeteer.launch(); 
  const page = await browser.newPage(); 
  await page.goto(pupUrl , {waitUntil: 'load', timeout: 0}); 
  await page.click('.olp-text-box'); 
  await page.click('#aod-filter-string'); 
  await page.click('.a-size-base.a-color-base') 
  return page; 
} 
async function checkSellers(page){ 
  await page.reload(); 
  let html = await page.evaluate(()=> document.body.innerHTML); 
  $('#aod-filter-offer-count-string',html).each(function(){ 
    var numberOfSellers = $(this).text(); 
    console.log(numberOfSellers); 
  }); 
} 
async function monitor(){ 
  let page = await configureBrowser(); 
  await checkSellers(page); 
} 
monitor();

解决思路与优化方案

遇到这个问题通常是元素加载时机不对、选择器失效或者页面结构更新导致的,下面一步步帮你排查和优化:

1. 先确认选择器是否还有效

亚马逊的页面结构经常迭代,.olp-text-box这个类名可能已经被替换了。你可以手动打开目标商品页面,用浏览器开发者工具(F12)的元素搜索功能,确认这个选择器是否还能定位到"查看其他卖家"的入口。如果找不到,就得重新抓取新的选择器——比如现在亚马逊的卖家入口可能用了#aod-pinned-offer-show-more-button这类新的标识。

2. 优化页面等待策略,确保元素完全加载

你当前用的waitUntil: 'load'只是等待页面基本资源加载完成,但卖家模块这类动态内容可能在load事件之后才渲染。建议换成更稳妥的等待方式:

// 替换原page.goto代码
await page.goto(pupUrl, { waitUntil: 'networkidle2', timeout: 0 });
// 等待目标元素可见后再点击,避免操作过早
await page.waitForSelector('.olp-text-box', { visible: true, timeout: 10000 });
await page.click('.olp-text-box');

networkidle2会等待页面网络请求稳定(只剩2个以内的请求),waitForSelectorvisible: true能确保元素不仅存在,还处于可点击状态。

3. 处理亚马逊的反爬机制

亚马逊对爬虫敏感度很高,可能会弹出人机验证、登录提示,或者直接隐藏内容。你可以在代码里加个截图,看看页面实际加载的是什么:

await page.screenshot({ path: 'amazon-check.png' });

如果截图里是验证页面,就得调整浏览器配置,比如设置真实的UA、启用无头模式时加参数:

const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"'
  ]
});

4. 重构checkSellers函数,避免不必要的操作

你代码里的page.reload()完全没必要,反而可能触发反爬;另外不要在Node环境用jQuery解析HTML,直接在浏览器环境操作DOM更可靠:

async function checkSellers(page){ 
  if (!page) return;
  // 等待卖家数量元素加载完成
  await page.waitForSelector('#aod-filter-offer-count-string', { visible: true });
  let numberOfSellers = await page.evaluate(() => {
    const element = document.querySelector('#aod-filter-offer-count-string');
    return element ? element.textContent.trim() : '无法获取卖家数量';
  });
  console.log('仅售全新商品的卖家数量:', numberOfSellers);
}

5. 完整优化后的代码示例

const pupUrl = 'https://www.amazon.com/dp/' + req.body.asinIdInput;
async function configureBrowser(){ 
  const browser = await puppeteer.launch({
    headless: 'new',
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"'
    ]
  }); 
  const page = await browser.newPage(); 
  await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36');
  
  await page.goto(pupUrl, { waitUntil: 'networkidle2', timeout: 0 }); 

  // 检查是否遇到人机验证
  const hasCaptcha = await page.$('#captchacharacters') !== null;
  if (hasCaptcha) {
    console.log('遇到人机验证,请手动处理或添加验证码识别逻辑');
    await browser.close();
    return null;
  }

  // 优先尝试原选择器,失败则用备用选择器
  try {
    await page.waitForSelector('.olp-text-box', { visible: true, timeout: 10000 });
    await page.click('.olp-text-box');
  } catch (e) {
    console.log('.olp-text-box找不到,尝试备用选择器');
    await page.waitForSelector('#aod-pinned-offer-show-more-button', { visible: true, timeout: 10000 });
    await page.click('#aod-pinned-offer-show-more-button');
  }

  // 点击筛选全新商品选项
  await page.waitForSelector('#aod-filter-string', { visible: true });
  await page.click('#aod-filter-string');
  await page.waitForSelector('.a-size-base.a-color-base', { visible: true });
  await page.click('.a-size-base.a-color-base');

  return page; 
} 

async function checkSellers(page){ 
  if (!page) return;
  await page.waitForSelector('#aod-filter-offer-count-string', { visible: true, timeout: 10000 });
  let numberOfSellers = await page.evaluate(() => {
    const element = document.querySelector('#aod-filter-offer-count-string');
    return element ? element.textContent.trim() : '无法获取卖家数量';
  });
  console.log('仅售全新商品的卖家数量:', numberOfSellers);
} 

async function monitor(){ 
  let page = await configureBrowser(); 
  await checkSellers(page); 
  // 记得关闭浏览器,避免资源泄漏
  await page.browser().close();
} 
monitor();

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

火山引擎 最新活动