Puppeteer - 单击具有指定文本的跨度
Puppeteer - click on span with specified text
我目前正在使用 puppeteer 抓取网页。我正在尝试做一些可以加快我工作速度的东西。
我的 HTML 标记看起来像这样
<div class="inner-wrapper" style="">
<div class="style-001">
<ul role="listbox" aria-multiselectable="true" class="style-002">
<li role="option" aria-selected="false" class="style-003">
<span class="style-004">First Option</span>
</li>
<li role="option" aria-selected="false" class="style-003">
<span class="style-004">Second Option</span>
</li>
<li role="option" aria-selected="false" class="style-003">
<span class="style-004">Third Option</span>
</li>
</ul>
</div>
我试图根据 span 的文本 select 具体 'li' 。此页面是动态的,因此有时 'Third Option' 会有索引 [3],有时会有其他索引。它必须仅由 span 的文本 select 编辑,因为它在其他情况下不起作用。我不能使用 class 因为这个网站对每个 'li'.
使用相同的 classes
我研究了 google 和 Whosebug,但没有找到可行的解决方案。我尝试通过 xpath、js select 或更多 selecting。甚至我也尝试过这样的事情:
const [link] = await page.$x('//div[2]/div/div/section/div[2]/div/div/div/ul/li[2]/span[contains(text(), "First Option")]');
await link.click();
或
let selectOption = await page.waitForXPath(`//div[2]/div/div/section/div[2]/div/div/div/ul/li[contains(text(),'First Option')]`);
await selectOption.click();
如果有人能帮助我,我将不胜感激。
@编辑
如果点击任何选项很重要,本网站会将 aria-selected="false" 更改为 "true"。也许它会以任何方式帮助?
您可以尝试使用 page.evaluate
而不是使用 querySelectorAll
和 filter
通过文本 li
而不是使用 forEach
单击 il
与特定文本。
await page.evaluate(() => {
Array.from(document.querySelectorAll('li')).filter(li => {
return li.innerText == 'First Option' // filter il for specific text
}).forEach(element => {
if (element) element.click(); // click on il with specific text
});
});
如果第一个不行可以试试
await page.evaluate(() => {
Array.from(document.querySelectorAll('div > div > ul > li')).filter(li => {
return li.innerText == 'First Option' // filter il for specific text
}).forEach(element => {
if (element) element.click(); // click on il with specific text
});
});
您也可以尝试一下,我认为这是最好的方法。
await page.evaluate(() => {
const elements = [...document.querySelectorAll('div > div > ul > li')];
const targetElement = elements.find(e => e.innerText == 'First Option');
if (targetElement) targetElement.click();
});
或
await page.evaluate(() => {
const elements = [...document.querySelectorAll('li')];
const targetElement = elements.find(e => e.innerText == 'First Option');
if (targetElement) targetElement.click();
});
我目前正在使用 puppeteer 抓取网页。我正在尝试做一些可以加快我工作速度的东西。
我的 HTML 标记看起来像这样
<div class="inner-wrapper" style="">
<div class="style-001">
<ul role="listbox" aria-multiselectable="true" class="style-002">
<li role="option" aria-selected="false" class="style-003">
<span class="style-004">First Option</span>
</li>
<li role="option" aria-selected="false" class="style-003">
<span class="style-004">Second Option</span>
</li>
<li role="option" aria-selected="false" class="style-003">
<span class="style-004">Third Option</span>
</li>
</ul>
</div>
我试图根据 span 的文本 select 具体 'li' 。此页面是动态的,因此有时 'Third Option' 会有索引 [3],有时会有其他索引。它必须仅由 span 的文本 select 编辑,因为它在其他情况下不起作用。我不能使用 class 因为这个网站对每个 'li'.
使用相同的 classes我研究了 google 和 Whosebug,但没有找到可行的解决方案。我尝试通过 xpath、js select 或更多 selecting。甚至我也尝试过这样的事情:
const [link] = await page.$x('//div[2]/div/div/section/div[2]/div/div/div/ul/li[2]/span[contains(text(), "First Option")]');
await link.click();
或
let selectOption = await page.waitForXPath(`//div[2]/div/div/section/div[2]/div/div/div/ul/li[contains(text(),'First Option')]`);
await selectOption.click();
如果有人能帮助我,我将不胜感激。
@编辑 如果点击任何选项很重要,本网站会将 aria-selected="false" 更改为 "true"。也许它会以任何方式帮助?
您可以尝试使用 page.evaluate
而不是使用 querySelectorAll
和 filter
通过文本 li
而不是使用 forEach
单击 il
与特定文本。
await page.evaluate(() => {
Array.from(document.querySelectorAll('li')).filter(li => {
return li.innerText == 'First Option' // filter il for specific text
}).forEach(element => {
if (element) element.click(); // click on il with specific text
});
});
如果第一个不行可以试试
await page.evaluate(() => {
Array.from(document.querySelectorAll('div > div > ul > li')).filter(li => {
return li.innerText == 'First Option' // filter il for specific text
}).forEach(element => {
if (element) element.click(); // click on il with specific text
});
});
您也可以尝试一下,我认为这是最好的方法。
await page.evaluate(() => {
const elements = [...document.querySelectorAll('div > div > ul > li')];
const targetElement = elements.find(e => e.innerText == 'First Option');
if (targetElement) targetElement.click();
});
或
await page.evaluate(() => {
const elements = [...document.querySelectorAll('li')];
const targetElement = elements.find(e => e.innerText == 'First Option');
if (targetElement) targetElement.click();
});