【问题标题】:How to click a button on a website using Puppeteer without any class, id ,... assigned to it?如何使用 Puppeteer 在网站上单击没有任何类、id 等的按钮?
【发布时间】:2019-03-25 01:54:58
【问题描述】:

所以我想点击网站上的一个按钮。该按钮没有id,类,...所以我应该找到一种方法来单击带有名称的按钮。在这个例子中,我应该点击名称“Supreme®/The North Face® 皮革单肩包"

这是我在 Node.js 中的代码

const puppeteer = require('puppeteer');

let scrape = async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://www.supremenewyork.com/shop/all/bags');
await page.click(...);
browser.close();
return result;
};

这是我要点击的元素:

<a class="name-link" href="/shop/bags/a9cz4te2r/rsth86fbl">Supreme®/The 
North Face® Leather Shoulder Bag</a>

【问题讨论】:

  • 在登录页面中找不到任何此类 name-link 或此名称 Supreme®/The North Face® Leather Shoulder Bag。你从哪里得到的?
  • 我从这个链接得到它:supremenewyork.com/shop/all/bags。然后第二行的第一个包,它在
    标签下,然后在

  • 这是链接到那个包的网址https://www.supremenewyork.com/shop/bags/dd3wmsh9x/a05ivugj2吗?如果是,那么您选择了错误的元素。
  • 那个链接对我不起作用。我想这是因为你来自世界的另一个地方。
  • 我根据您上面的元素在下面提供了一个选择器。只需在脚本中使用它。

标签: html node.js web-scraping automation puppeteer


【解决方案1】:

这是收集该数据的一种方法。首先在您的浏览器控制台上尝试这些。

[...document.querySelectorAll('a.name-link')]
.filter(element => 
  element.innerText.includes('Supreme®/The North Face® Leather Shoulder Bag')
)

这是怎么回事?

  • document.querySelectorAll 查找具有该选择器的所有元素。
  • .filter 将返回与查询匹配的结果。
  • .includes 将返回包含给定字符串的数据。

如果a.name-link 不起作用,则查找a,如果不起作用,则找到父项并使用它。

一旦你在浏览器上获得了元素,你就可以将它应用到你的代码上,点击它等等。

用法:

您可以使用page.evaluate进行过滤和点击。

const query = "Supreme®/The North Face® Leather Shoulder Bag";

page.evaluate(query => {
  const elements = [...document.querySelectorAll('a.name-link')];

  // Either use .find or .filter, comment one of these
  // find element with find
  const targetElement = elements.find(e => e.innerText.includes(query));

  // OR, find element with filter
  // const targetElement = elements.filter(e => e.innerText.includes(query))[0];

  // make sure the element exists, and only then click it
  targetElement && targetElement.click();
}, query)

【讨论】:

  • 可能是一个愚蠢的问题,但我对此有点陌生,但这 3 点在文档之前是什么意思?
  • 正如我上面问的,你能分享你试图访问的页面的截图吗?否则在某处共享该页面的源代码。否则,这一切都只是猜测什么有效等等。
  • 我无意中删除了那个被接受的东西,因为你的代码有效。 .顺便说一句,这是链接supremenewyork.com/shop/all/bags
  • 不,我不是在谈论链接,而是关于屏幕截图。它不像您所看到的那样显示在这里。我也尝试过代理。只是没有在任何地方显示任何名称。
【解决方案2】:

如果我没听错的话,下面的代码应该可以让你点击那个链接:

const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://www.supremenewyork.com/shop/all/bags');
await page.click("a[href$='a05ivugj2']");
await browser.close();
})();

【讨论】:

  • 顺便说一句,如果您最终可用的元素实际上是您在上面粘贴的内容,那么请在我上面的脚本中将这部分 page.click("a[href$='a05ivugj2']") 替换为 page.click("a[href$='rsth86fbl']")
  • 如果我将 href$ 更改为 ckf2cimj7 它将对我有用。我想这是因为该网站是区域性的。但问题是我无法在商品上线之前获得该标签。在它上线之前我唯一会知道的是项目的名称。所以我需要找到一种方法来点击名为“Supreme®/The North Face® 皮革单肩包”的链接。
  • 当我通过 chrome 开发工具搜索时,您提到的名称在该页面中不可用(至少从我这边)。
  • 它是项目本身的名称。 prntscr.com/l8ahbrprntscr.com/l8ahwc
  • 这就是我看到check out this link的方式。
【解决方案3】:

下面的函数会点击第一个匹配特定文本的元素:

const clickText = text => {
    return page.evaluate(text => [...document.querySelectorAll('*')].find(e => e.textContent.trim() === text).click(), text);
};

您可以使用以下方法在您的 Puppeteer 脚本中使用该函数:

await clickText('Supreme®/The North Face® Leather Shoulder Bag');

【讨论】:

  • 我收到cannot read property click of undefined
猜你喜欢
  • 2021-07-05
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多