如何使用 Puppeteer 在网站上单击没有任何类、id 等的按钮?

Posted

技术标签:

【中文标题】如何使用 Puppeteer 在网站上单击没有任何类、id 等的按钮?【英文标题】:How to click a button on a website using Puppeteer without any class, id ,... assigned to it? 【发布时间】: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吗?如果是,那么您选择了错误的元素。 那个链接对我不起作用。我想这是因为你来自世界的另一个地方。 我根据您上面的元素在下面提供了一个选择器。只需在脚本中使用它。 【参考方案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 点在文档之前是什么意思? 这是一个传播运算符。 developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 正如我上面问的,你能分享你试图访问的页面的截图吗?否则在某处共享该页面的源代码。否则,这一切都只是猜测什么有效等等。 我无意中删除了那个被接受的东西,因为你的代码有效。 .顺便说一句,这是链接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/l8ahbr 和 prntscr.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

以上是关于如何使用 Puppeteer 在网站上单击没有任何类、id 等的按钮?的主要内容,如果未能解决你的问题,请参考以下文章

Mac上的Puppeteer / chromium长期提示“接受传入的网络连接?”

按类名收集元素,然后单击每个元素 - Puppeteer

Puppeteer:我怎样才能等到列表关闭?如何等到元素从 DOM 中消失?

已在Puppeteer中定义函数后如何调用该函数

使用 Puppeteer 和 Node.JS 在网站上的 iFrame 中找不到隐藏的输入元素

如何从 Puppeteer 将文本输入到 Flash TextArea 中?