Roc*_*uts 13 browser cookies session local-storage puppeteer
是否可以使用 Puppeteer 脚本打开页面并与之交互,然后按原样保存该浏览器会话,然后加载另一个脚本并从那里继续?
“浏览器会话”是指当前加载的页面,包括页面状态(DOM 空间和 javascript 变量等)、cookie、本地存储、整个shebang。基本上它需要的一切都在上一个脚本停止的地方继续。
如果没有,那么至少可以导出和导入 cookie 和本地存储吗?因此,我可以重新加载特定页面并继续处理,同时保持任何登录或会话数据完整无缺。
小智 20
我不能肯定,但由于 Puppeteer “只是”Chrome DevTools Protocol (cdp) 的包装器,而 cpd 没有执行您所要求的本机“命令”,因此不可能做到对于整个shebang。
但你有选择。一个不错的选择是为下一个脚本重新使用相同的浏览器。您只需要将“ userDataDir ”选项传递给 puppeteer.launch 命令。例子:puppeteer.launch({ userDataDir: '/tmp/myChromeSession' });。每个使用它的 puppeteer 脚本都将使用相同的浏览器,因此它们将共享“永久”cookie。“会话”cookie(或那些有过期时间的)肯定会被删除,但这是 cookie 应该工作的方式。
关于用户数据目录的摘录:
用户数据目录包含配置文件数据,例如历史记录、书签和 cookie,以及其他每个安装的本地状态。
尽管这个参考没有写任何关于 Web 存储的内容,但它也保存在用户数据目录中。所以,使用这个选项你很高兴。我认为是您的情况的最佳选择。
您还有其他选择,例如仅复制 cookie 和存储(localStorage 和 sessionStorage)。
使用 puppeteer 复制 cookie
对于 puppeteer,这个过程是非常痛苦的:你必须指定你想要从中处理 cookie 的每个来源。例如,如果您的网站嵌入了第三方内容,例如 google 登录或跟踪,则您必须从“google.com”、“.google.com”、“www.google.com”等复制 cookie。这非常非常愚蠢而痛苦。无论如何,要复制 cookie 源https://abc,请发出:const abcCookies = await page.cookies('https://a.b.c');
恢复它们:await page.setCookie(...abcCookies);。由于它们是 json,您可以将它们序列化并保存到磁盘,以便稍后恢复。
使用 CDP 复制 cookie
let { cookies } = await page._client.send('Network.getAllCookies');
Run Code Online (Sandbox Code Playgroud)
要恢复它们,您可以使用Network.setCookies cdp 方法。同样,您可以序列化这些 cookie 并保存到磁盘以供稍后恢复。
复制存储(localStorage 和 sessionStorage)
您可以通过const ls = await page.evaluate(() => JSON.stringify(localStorage));和转移您自己的原始存储const ss = await page.evaluate(() => JSON.stringify(sessionStorage));。但是,出于安全原因,您无法访问其他源存储。不知道 CDP 等价物,并认为它还不存在。
网页缓存
如果您的站点有 Service Worker,那么它很可能会将内容保存在Web Cache API 上。我不知道保存这些缓存数据是否有意义,但是如果对您很重要,您也可以传输这些缓存,但不能使用 puppeteer apis 或 cdp。您必须自己使用Cache api并使用page.evaluate传输缓存。
索引数据库
如果您想复制 IndexedDB 内容,您可以使用 cdp IndexedDB域方法(如“IndexedDB.requestData”)来获取任何来源的数据,但您不能设置/恢复这些数据。:) 但是,您可以在自己的来源中使用 page.evaluate 以编程方式恢复数据。
Icrespilho的回答非常有价值。他为读者留下了两个练习,我做了一个:IndexedDB。
复制 IndexedDB
他写:
如果要复制 IndexedDB 内容,可以使用 cdp IndexedDB 域方法(如“IndexedDB.requestData”)来获取任何源的数据,但无法设置/恢复此数据。:) 但是,您可以在自己的源中使用 page.evaluate 以编程方式恢复数据。
我已经将数据读取为:
const indexedDB = await page.evaluate(async () => {
const result = {};
const databases = await window.indexedDB.databases();
const connect = (database) => new Promise(function (resolve, _) {
const request = window.indexedDB.open(database.name, database.version);
request.onsuccess = _ => resolve(request.result);
});
const getAll = (db, objectStoreName) => new Promise(function (resolve, _) {
const request = db.transaction([objectStoreName]).objectStore(objectStoreName).getAll();
request.onsuccess = _ => resolve(request.result);
});
for (i = 0; i < databases.length; i++) {
const db = await connect(databases[i])
const dbName = db.name;
result[dbName] = {}
for (j = 0; j < db.objectStoreNames.length; j++) {
const objectStoreName = db.objectStoreNames[j];
result[dbName][objectStoreName] = []
const values = await getAll(db, objectStoreName);
result[dbName][objectStoreName] = values;
}
}
return result;
});
Run Code Online (Sandbox Code Playgroud)
我希望这对任何人都有帮助。
| 归档时间: |
|
| 查看次数: |
5293 次 |
| 最近记录: |