Puppeteer - 按类名删除元素

15

我尝试通过类名来移除元素,但是它没有起作用。

这是我使用的代码:

await page.screenshot({path: 'pic.png'});   //for testing purposes
    let div_selector_to_remove= ".xj7.Kwh5n";
    var thingToRemove = document.querySelectorAll(div_selector_to_remove);
    var number_of_elements = thingToRemove.length;
    for (var i = 0; i < number_of_elements.length; i++) {
        thingToRemove[i].parentNode.removeChild(thingToRemove);
    }

浏览器加载并获取了已加载元素的屏幕截图。 然后什么都没有发生。 元素仍然存在。


你如何测试它们没有被移除?在执行代码之前,您需要先截屏。您确定元素在代码评估时存在吗?您尝试过调试thingToRemove吗? - Estus Flask
我使用了非无头版本的Puppeteer。我可以在Chromium中看到元素仍然存在。 - user1584421
5个回答

33

page.evaluate中运行document.querySelector。这是我的答案:

await page.goto('<url_here>');
let div_selector_to_remove= ".xj7.Kwh5n";
await page.evaluate((sel) => {
    var elements = document.querySelectorAll(sel);
    for(var i=0; i< elements.length; i++){
        elements[i].parentNode.removeChild(elements[i]);
    }
}, div_selector_to_remove)

再一次...你救了我...非常感谢。我是puppeteer的新手,对page.evaluate()还没有真正掌握。 - user1584421

5

可能更容易...

删除第一个匹配 selector 的节点:

await page.$eval(selector, el => el.remove());

删除所有与选择器匹配的节点:

await page.$$eval(selector, els => els.forEach(el => el.remove()));

等待选择器,然后删除它:

const el = await page.waitForSelector(selector);
await el.evaluate(el => el.remove());

如果有必要在控制台中选择并删除:

const selector = ".foo";

// single
await page.evaluate(`
  document.querySelector("${selector}").remove()
`);

// multiple
await page.evaluate(selector =>
  document.querySelectorAll(selector).forEach(el => el.remove()),
  selector
);

您可以将选择器硬编码到 eval 字符串/函数中,但我认为以两种不同的方式从变量中显示它会很有用。

对于 Puppeteer 中的任何内容,了解哪些代码运行在 Node/Puppeteer-land 和哪些代码运行在浏览器/控制台-land 中非常重要。经验法则是:如果是回调或字符串化的函数体,则在浏览器中运行,您只能使用浏览器/DOM概念,如 HTMLElement.remove()windowdocument,否则它在 Node 中运行,您只能调用 Puppeteer API 函数。在 OP 的情况下,看起来我们在 Node-land 的回调之外,所以document不是一个东西,只有 Puppeteer page.函数。


2

首先,number_of_elements是一个数字。

但是你调用了number_of_elements.length

接下来,thingToRemove[i].parentNode.removeChild(thingToRemove)thingToRemove[i].parentNodethingToRemove[i]的父元素,而不是thingToRemove

所以你无法从thingToRemove[i].parentNode中移除thingToRemove

我认为这段代码可能会有用。

await page.screenshot({path: 'pic.png'});   //for testing purposes
let div_selector_to_remove= ".xj7.Kwh5n";
var thingToRemove = document.querySelectorAll(div_selector_to_remove);
var number_of_elements = thingToRemove.length;
for (var i = 0; i < number_of_elements; i++) {
    thingToRemove[i].parentNode.removeChild(thingToRemove[i]);
}

2
    //Wait for the element with id="xe7COe" to show up
    await page.waitForSelector('#xe7COe');
    //delete the element with id="xe7COe"  
    await page.evaluate(() => document.querySelector('#xe7COe').remove());

waitForSelector 返回它找到的节点,因此您可以简化您的代码为 const el = await page.waitForSelector('#xe7COe'); 然后使用 await el.evaluate(el => el.remove()) 而不是重新查询它。如果你 想要 重新查询它,或者不需要等待它,建议使用 page.$eval 而不是 page.evaluate()page.$eval 是一个缩写,用于在 evaluate 中作为第一件事运行 document.querySelector 的常见模式。 - ggorlen

1

最佳方案page.evaluate 中运行 document.querySelector。这是我的答案。

    await page.goto('<url_here>');
let div_selector_to_remove= ".xj7.Kwh5n";
await page.evaluate((sel) => {
    var elements = document.querySelectorAll(sel);
    for(var i=0; i< elements.length; i++){
        elements[i].parentNode.removeChild(elements[i]);
    }
}, div_selector_to_remove)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接