Puppeteer - 如何自动接受任何 URL 的 cookie 同意提示?
Pupeteer - how can I accept cookie consent prompts automatically for any URL?
使用 pupeteer 对网站进行截图时,会显示 cookie 同意提示。我想在截取屏幕截图之前关闭或接受这些提示。我面临的问题是大多数网站以不同的方式呈现 cookie 提示,因此很难将它们隔离开来。
如何使用 pupeteer 最好地定位和消除这些提示?
我认为没有通用的方法来执行此操作,因为这些提示是与页面中所有其他元素一样的元素。话虽如此,有一些尝试使用扩展名或过滤器列表来阻止它们,您可以尝试:
我没有测试过这些,不知道它们是否有效。
请记住 headless chrome 不支持扩展。在 puppeteer 中加载扩展:
const browser = await puppeteer.launch({
headless: true,
args: [
'--disable-extensions-except=/path/to/manifest/folder/',
'--load-extension=/path/to/manifest/folder/',
]
});
更新:用无头傀儡来对抗 cookie 同意的更通用方法
这种方法也远未完成,但展示了一种以不太具体的方式消除 cookie 同意弹出窗口的有效方法。它使用 语言 和通用的 选择器 来检测同意按钮和链接,而不是仅仅依赖于每个网站的确切选择器。
在下面的示例中,我的目标是容器中的元素 a, button
,该容器在 id, class
中使用名称 cookie。我在这方面限制了按钮,所以我不会无意中随意点击网站。
此外,它使用正则表达式来识别通常用于接受 cookie 的按钮文本,可以用 ^(Accept all|Accept|I understand|Agree|Okay|OK)$
替换或翻译成您选择的任何语言 (不区分大小写).
await page.evaluate(_ => {
function xcc_contains(selector, text) {
var elements = document.querySelectorAll(selector);
return Array.prototype.filter.call(elements, function(element){
return RegExp(text, "i").test(element.textContent.trim());
});
}
var _xcc;
_xcc = xcc_contains('[id*=cookie] a, [class*=cookie] a, [id*=cookie] button, [class*=cookie] button', '^(Alle akzeptieren|Akzeptieren|Verstanden|Zustimmen|Okay|OK)$');
if (_xcc != null && _xcc.length != 0) { _xcc[0].click(); }
});
旧答案:
确实没有通用的方法来处理 cookie 同意弹出窗口,因为它们差异很大,甚至 chrome 扩展程序也无法处理所有问题。但是,您可以复制扩展程序的功能并管理您自己的列表,方法是在截取屏幕截图之前评估目标站点上的 JS 代码。
在我的例子中,我只是全部接受它们,尝试在无头模式下进行。在识别它们时添加更多选择器。如果您愿意,可以改用关闭按钮选择器。
接下来您会发现一些真实世界的场景,应该有助于您继续前进:
- 处理 ids、类 和自定义 数据属性
- 隐藏 iframes,因为无法评估不同域上的代码
await page.evaluate(_ => {
var xcc
// ids
var xcc_id = [
'borlabsCookieOptionAll',
'cookie-apply-all',
'cookie-settings-all',
// add ids here
];
for (let i = 0; i < xcc_id.length; i++) {
xcc = document.getElementById(xcc_id[i]);
if (xcc != null) {
xcc.click();
}
}
// classes
var xcc_class = [
'accept-all',
'accept-cookies-button',
'avia-cookie-select-all',
// add classes here
];
for (let i = 0; i < xcc_class.length; i++) {
xcc = document.getElementsByClassName(xcc_class[i]);
if (xcc != null && xcc.length != 0) {
xcc[0].click();
}
}
// custom data attributes
xcc = document.querySelectorAll('[data-cookieman-accept-all]'); if (xcc != null && xcc.length != 0) { xcc[0].click(); }
// hide iframes, can't eval
xcc = document.querySelectorAll("iframe[src*=eurocookie]"); if (xcc != null && xcc.length != 0) { xcc[0].style.display = 'none'; }
xcc = document.querySelectorAll("iframe[src*=eurocookie]"); if (xcc != null && xcc.length > 1) { xcc[1].style.display = 'none'; }
});
肯定是一种更优雅的方式,但通过这种方式我能够快速组织我的列表,即时进行更改,排序和删除重复项代码编辑器,将它们保持为一行或数组。
或者,只需使用 { headless: false }
选项并加载一个扩展程序,按照建议为您执行此操作。干杯。
旁注:如果页面重新加载,与 cookie 同意弹出窗口的交互可能会导致您的代码中断(页面导航错误) .为了避免这种情况,我在 await page.evaluate( ... );
之后使用了 3000-4000 毫秒的固定时间延迟
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
await delay(3500);
它还捕获大量元刷新、JS 重定向并为大型资源加载提供一些额外时间。
使用 pupeteer 对网站进行截图时,会显示 cookie 同意提示。我想在截取屏幕截图之前关闭或接受这些提示。我面临的问题是大多数网站以不同的方式呈现 cookie 提示,因此很难将它们隔离开来。
如何使用 pupeteer 最好地定位和消除这些提示?
我认为没有通用的方法来执行此操作,因为这些提示是与页面中所有其他元素一样的元素。话虽如此,有一些尝试使用扩展名或过滤器列表来阻止它们,您可以尝试:
我没有测试过这些,不知道它们是否有效。
请记住 headless chrome 不支持扩展。在 puppeteer 中加载扩展:
const browser = await puppeteer.launch({
headless: true,
args: [
'--disable-extensions-except=/path/to/manifest/folder/',
'--load-extension=/path/to/manifest/folder/',
]
});
更新:用无头傀儡来对抗 cookie 同意的更通用方法
这种方法也远未完成,但展示了一种以不太具体的方式消除 cookie 同意弹出窗口的有效方法。它使用 语言 和通用的 选择器 来检测同意按钮和链接,而不是仅仅依赖于每个网站的确切选择器。
在下面的示例中,我的目标是容器中的元素 a, button
,该容器在 id, class
中使用名称 cookie。我在这方面限制了按钮,所以我不会无意中随意点击网站。
此外,它使用正则表达式来识别通常用于接受 cookie 的按钮文本,可以用 ^(Accept all|Accept|I understand|Agree|Okay|OK)$
替换或翻译成您选择的任何语言 (不区分大小写).
await page.evaluate(_ => {
function xcc_contains(selector, text) {
var elements = document.querySelectorAll(selector);
return Array.prototype.filter.call(elements, function(element){
return RegExp(text, "i").test(element.textContent.trim());
});
}
var _xcc;
_xcc = xcc_contains('[id*=cookie] a, [class*=cookie] a, [id*=cookie] button, [class*=cookie] button', '^(Alle akzeptieren|Akzeptieren|Verstanden|Zustimmen|Okay|OK)$');
if (_xcc != null && _xcc.length != 0) { _xcc[0].click(); }
});
旧答案:
确实没有通用的方法来处理 cookie 同意弹出窗口,因为它们差异很大,甚至 chrome 扩展程序也无法处理所有问题。但是,您可以复制扩展程序的功能并管理您自己的列表,方法是在截取屏幕截图之前评估目标站点上的 JS 代码。
在我的例子中,我只是全部接受它们,尝试在无头模式下进行。在识别它们时添加更多选择器。如果您愿意,可以改用关闭按钮选择器。
接下来您会发现一些真实世界的场景,应该有助于您继续前进:
- 处理 ids、类 和自定义 数据属性
- 隐藏 iframes,因为无法评估不同域上的代码
await page.evaluate(_ => {
var xcc
// ids
var xcc_id = [
'borlabsCookieOptionAll',
'cookie-apply-all',
'cookie-settings-all',
// add ids here
];
for (let i = 0; i < xcc_id.length; i++) {
xcc = document.getElementById(xcc_id[i]);
if (xcc != null) {
xcc.click();
}
}
// classes
var xcc_class = [
'accept-all',
'accept-cookies-button',
'avia-cookie-select-all',
// add classes here
];
for (let i = 0; i < xcc_class.length; i++) {
xcc = document.getElementsByClassName(xcc_class[i]);
if (xcc != null && xcc.length != 0) {
xcc[0].click();
}
}
// custom data attributes
xcc = document.querySelectorAll('[data-cookieman-accept-all]'); if (xcc != null && xcc.length != 0) { xcc[0].click(); }
// hide iframes, can't eval
xcc = document.querySelectorAll("iframe[src*=eurocookie]"); if (xcc != null && xcc.length != 0) { xcc[0].style.display = 'none'; }
xcc = document.querySelectorAll("iframe[src*=eurocookie]"); if (xcc != null && xcc.length > 1) { xcc[1].style.display = 'none'; }
});
肯定是一种更优雅的方式,但通过这种方式我能够快速组织我的列表,即时进行更改,排序和删除重复项代码编辑器,将它们保持为一行或数组。
或者,只需使用 { headless: false }
选项并加载一个扩展程序,按照建议为您执行此操作。干杯。
旁注:如果页面重新加载,与 cookie 同意弹出窗口的交互可能会导致您的代码中断(页面导航错误) .为了避免这种情况,我在 await page.evaluate( ... );
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
await delay(3500);
它还捕获大量元刷新、JS 重定向并为大型资源加载提供一些额外时间。