Javascript 木偶师:如何单击其子元素中包含特定值的元素
我第一次使用木偶演员,我有以下代码来点击某个元素:Javascript 木偶师:如何单击其子元素中包含特定值的元素,javascript,puppeteer,selector,Javascript,Puppeteer,Selector,我第一次使用木偶演员,我有以下代码来点击某个元素: await page.waitForSelector('.item-table > .grid-item > .grid-item-container > .grid-table-container > .grid-option-table:nth-child(1) > .grid-option:nth-child(1) > .grid-option-selectable > div'); await
await page.waitForSelector('.item-table > .grid-item > .grid-item-container > .grid-table-container > .grid-option-table:nth-child(1) > .grid-option:nth-child(1) > .grid-option-selectable > div');
await page.click('.item-table > .grid-item > .grid-item-container > .grid-table-container > .grid-option-table:nth-child(1) > .grid-option:nth-child(1) > .grid-option-selectable > div');
因为我在页面上有很多.item table
元素,我想让它点击在其子体中有特定文本的元素(我不知道子体的级别)。
我在文档中甚至在这么多问题中寻找了一个解决方案,但我找不到任何有用的东西
我试图添加>:contains(“Foo-bar”)
,但这可能是错误的方法。事实上,它不起作用
await page.waitForSelector('.item-table > :contains("Foo Bar") > .grid-item > .grid-item-container > .grid-table-container > .grid-option-table:nth-child(1) > .grid-option:nth-child(1) > .grid-option-selectable > div');
await page.click('.item-table > :contains("Foo Bar") > .grid-item-container > .grid-table-container > .grid-option-table:nth-child(1) > .grid-option:nth-child(1) > .grid-option-selectable > div');
那么,如何与木偶演员合作呢
编辑:
以下是我正在努力获取的标记:
<div class="item-table"></div>
<div class="item-table"></div>
<div class="item-table"></div>
<div class="item-table"></div>
<div class="item-table"></div>
<div class="item-table"></div>
<div class="item-table">
<div class="grid-item">
<div class="grid-item-container">
<div class="grid-table-container>
<div class="grid-option-header">
<div class="grid-option-caption">
<div class="grid-option-name">
Foo Bar
<span>some other text</span>
</div>
</div>
</div>
<div class="grid-option-table">
<div class="grid-option">
<div class="grid-option-selectable">
<div></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="item-table"></div>
<div class="item-table"></div>
我将对您的标记稍作调整,以帮助验证代码是否有效:
你难住我了!
添加一些具有不匹配文本的相同结构同级也是一个不错的主意,以确保我们不会产生误报
我们将尝试的策略如中所述(在同一个线程中提供了替代方案,并且单独的线程是相关的):在目标父级上使用xpath进行查询,在目标文本和clickable元素之间通过子代文本相互共享,然后在该父级上查询clickable元素
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch(/*{dumpio: true}*/);
const page = await browser.newPage();
await page.goto("http://localhost:8000");
const xp = `
//div[@class="item-table"
and descendant::*[contains(text(), "Foo Bar")]]
//div[@class="grid-option-selectable"]
`;
const [el] = await page.$x(xp);
console.log(await page.evaluate(el => el.innerText, el));
await el.click();
await browser.close();
})();
输出:
You got me!
请注意,我使用的是精确的类匹配,但如果目标元素上可能有多个类,则需要使用contains
放松查询。因此,您可以编写xpath表达式,如下所示:
//div[包含(@class,“项表”)
和./*[包含(text(),“Foo-Bar”)]]
//div[包含(@class,“网格选项可选”)]
看看这个答案@ggorlen我已经编辑了我的问题,谢谢。它不起作用。原因可能是“你找到我了!”文本有一个span
作为兄弟姐妹?我确实在forEach循环中使用cheerio
获得了按钮。有没有办法将所选元素传递给Puppeter让其单击?您的实际标记必须与所显示的不同,因为此代码适用于您发布的内容。如果您有一个选择器与Cheerio一起工作,为什么不在Puppeter中使用相同的选择器呢?此外,如果Cheerio可以工作,并且标记不是动态创建的,那么为什么还要使用Puppeter呢?请更新您的帖子,以显示您正在抓取的实际标记,并解释它是否是动态的。谢谢