【问题标题】:Scraping amazon with puppeteer用 puppeteer 刮亚马逊
【发布时间】:2021-02-01 02:49:08
【问题描述】:

我目前正在处理一些个人项目,我只是想进行一些亚马逊抓取,以便获取产品详细信息,例如名称和价格。

我发现使用相同 id 的产品名称和价格最一致的视图是移动视图,这就是我使用它的原因。

问题是我无法得到价格。

我已经对价格中的名称(有效)进行了完全相同的查询选择器,但没有成功。

const puppeteer = require('puppeteer');

const url = 'https://www.amazon.com/dp/B01MUAGZ49';

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.setViewport({ width: 360, height: 640 });
  await page.goto(url);

  let producData = await page.evaluate(() => {
    let productDetails = [];

    let elements = document.querySelectorAll('#a-page');

    elements.forEach(element => {
      let detailsJson = {};

      try {
        detailsJson.name = element.querySelector('h1#title').innerText;
        detailsJson.price = element.querySelector('#newBuyBoxPrice').innerText;
      } catch (exception) {}

      productDetails.push(detailsJson);
    });

    return productDetails;
  });

  console.dir(producData);
})();

我应该在 console.dir 中获得名称和价格,但现在我只能获得

[ { name: 'Nintendo Switch – Neon Red and Neon Blue Joy-Con ' } ]

【问题讨论】:

  • 由于该 id 仅在移动视图中可见,您应该模拟移动设备(使用 page.emulate() 方法)。见这里github.com/GoogleChrome/puppeteer/blob/v1.6.2/docs/…
  • 我已经在用puppeteer的宽度和高度做了,id为“title”的产品名称只出现在手机上,但价格有点被亚马逊屏蔽了。编辑:只是没有,仍然不起作用我将isMobile: true 添加到 setViewport 选项中
  • 你是对的,但由于我的位置,#newBuyBoxPrice 不存在。谢谢!

标签: javascript node.js puppeteer


【解决方案1】:

仅设置视口高度和重量不足以完全模拟移动浏览器。现在该页面假定您只有一个非常小的浏览器窗口。

模拟移动设备的最简单方法是使用函数page.emulate 和默认的DeviceDesriptors,其中包含有关大量移动设备的信息。

引用 page.emulate 的文档:

模拟给定的设备指标和用户代理。该方法是调用两个方法的快捷方式:

为了帮助模拟,puppeteer 提供了一个设备描述符列表,可以通过require('puppeteer/DeviceDescriptors') 命令获得。 [...]


示例

这是一个如何在访问页面时模拟 iPhone 的示例。

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];

const url = '...';

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.emulate(iPhone);
  await page.goto(url);

  // Simlified page.evaluate
  let producData = await page.evaluate(() => ({
    name: document.querySelector('#a-page h1#title').innerText,
    price: document.querySelector('#a-page #newBuyBoxPrice').innerText
  }));

  console.dir(producData);
})();

我还稍微简化了您的page.evaluate,但您当然也可以在page.goto 之后使用您的原始代码。这为我返回了产品的名称和价格。

【讨论】:

  • 我刚刚尝试了这个,使用简化的 productData 我得到了Error: Evaluation failed: TypeError: Cannot read property 'innerText' of null,用我的相同代码修改我仍然只是得到[ { name: 'Nintendo Switch – Neon Red and Neon Blue Joy-Con' } ],这只是名称,价格似乎是空白的。跨度>
  • 我刚刚想通了,在我的位置亚马逊不发货,所以没有#newBuyBoxPrice。我更改了选择器,现在它可以工作了。你知道如何设置地理位置吗?
  • @AlexeiRodriguez 您可以通过page.setGeolocation 设置地理位置,但亚马逊也可能会使用您的 IP 地址来估计您的位置。
猜你喜欢
  • 1970-01-01
  • 2020-07-02
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 2016-11-26
相关资源
最近更新 更多