NodeJS 如何使用puppeteer在stockX上选择尺寸(比如11号)?

rvpgvaaj  于 2023-04-20  发布在  Node.js
关注(0)|答案(1)|浏览(111)

我想做一个机器人,我需要选择一个大小。现在,我只想选择11。我该怎么做,因为所有的按钮都有相同的类?
我试过选择data-testid,但我对puppeteer和node.js都很陌生,所以有点困难。

const pt = require('puppeteer')

const url = 'https://stockx.com/buy/air-jordan-1-retro-high-og-chicago-reimagined-lost-and-found'

async function initBrowser(){
    const browser = await pt.launch({headless:false, defaultViewport: null, slowMo:10});
    const page = await browser.newPage();
    await page.goto(url,{waitUntil: 'networkidle0'});
    return page;
}

async function selectSize(){
    const page = await initBrowser();
    await page.$eval("div[data-testid='size-11'" , form => form.click() );
}

async function checkout(){
    await selectSize();
    await page.setViewport({width: 1920, height: 1080})
    await page.screenshot({path: 'test.png'})
}

checkout();

结果是这样的:

Error: Error: failed to find element matching selector "div[data-testid="#size-11"]"
    at CDPElementHandle.$eval (*filepath*)
    at async selectSize (*filepath*)
    at async checkout (*filepath*)

编辑:这是HTML:

<div title="" class="css-4tso23"><div data-component="grid-tile" data-testid="size-3.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 3.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$270</p></div></div></div><div data-component="grid-tile" data-testid="size-4" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 4</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$252</p></div></div></div><div data-component="grid-tile" data-testid="size-4.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 4.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$293</p></div></div></div><div data-component="grid-tile" data-testid="size-5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$305</p></div></div></div><div data-component="grid-tile" data-testid="size-5.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 5.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$346</p></div></div></div><div data-component="grid-tile" data-testid="size-6" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 6</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$330</p></div></div></div><div data-component="grid-tile" data-testid="size-6.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 6.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$329</p></div></div></div><div data-component="grid-tile" data-testid="size-7" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 7</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$340</p></div></div></div><div data-component="grid-tile" data-testid="size-7.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 7.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$381</p></div></div></div><div data-component="grid-tile" data-testid="size-8" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 8</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$370</p></div></div></div><div data-component="grid-tile" data-testid="size-8.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 8.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$379</p></div></div></div><div data-component="grid-tile" data-testid="size-9" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 9</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$401</p></div></div></div><div data-component="grid-tile" data-testid="size-9.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 9.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$424</p></div></div></div><div data-component="grid-tile" data-testid="size-10" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 10</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$434</p></div></div></div><div data-component="grid-tile" data-testid="size-10.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 10.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$441</p></div></div></div><div data-component="grid-tile" data-testid="size-11" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 11</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$453</p></div></div></div><div data-component="grid-tile" data-testid="size-11.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 11.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$449</p></div></div></div><div data-component="grid-tile" data-testid="size-12" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 12</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$465</p></div></div></div><div data-component="grid-tile" data-testid="size-12.5" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 12.5</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$469</p></div></div></div><div data-component="grid-tile" data-testid="size-13" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 13</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$464</p></div></div></div><div data-component="grid-tile" data-testid="size-14" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 14</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$457</p></div></div></div><div data-component="grid-tile" data-testid="size-15" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 15</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$439</p></div></div></div><div data-component="grid-tile" data-testid="size-16" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 16</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$359</p></div></div></div><div data-component="grid-tile" data-testid="size-17" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 17</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$449</p></div></div></div><div data-component="grid-tile" data-testid="size-18" variantcount="25" class="css-aw1zls"><div data-component="tile-inner" class="css-pmdaq1"><p class="chakra-text css-hoqc8t" data-component="tile-value"> 18</p><div data-component="tile-subvalue" class="css-0"><p class="chakra-text css-h7cvs">$400</p></div></div></div></div>
cedebl8k

cedebl8k1#

这里有一个简单的解决方案:只需将您的浏览器指向附加了?size=11的购买URL:https://stockx.com/buy/air-jordan-1-retro-high-og-chicago-reimagined-lost-and-found?size=11。这就是点击按钮的效果。
如果你想用更难的方法来做,循环遍历这些元素并选择带有textContent.trim() === "11"的元素。
选择元素是缺少的部分。我没有看到这样的'[data-testid="size-11"]'选择器。可能你正在被一个不同的站点服务。
以下是根据我收到的文档对我有效的方法:

const puppeteer = require("puppeteer"); // ^19.7.2

const url =
  "https://stockx.com/buy/air-jordan-1-retro-high-og-chicago-reimagined-lost-and-found";

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  const ua =
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";
  await page.setUserAgent(ua);
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const sel = '[data-component="tile-value"]';
  await page.waitForSelector(sel);
  const navP = page.waitForNavigation({waitUntil: "networkidle2"});
  await page.$$eval(
    sel,
    els => els.find(e => e.textContent.trim() === "11").click()
  );
  await navP;
  console.log(page.url());
  await page.screenshot({path: "shoe.png", fullpage: true});
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

请注意,我使用finally关闭浏览器。您使用的initBrowser是有缺陷的--browser对象丢失,您永远无法关闭它,挂起进程,直到它被手动杀死。
我建议在代码正常工作之前不要编写函数。过早的抽象会妨碍并增加复杂性。一旦代码在功能上正确,那么您可以将其分解为一个或三个整洁的函数。
另一个我没有尝试的方法是这样的:

const size = await page.waitForSelector("text/11");
await size.click();

问题是这可能会无意中指向错误的元素。XPath也是可能的。请参阅this post以获得在Puppeteer中通过文本选择元素的一般指南。
最后一点:他们使用了一些机器人检测,所以如果你被阻止了,那么可能还有更多的工作要做,但这似乎超出了这个问题的范围。

相关问题