我试图实现的目标是存储来自网站的 cookie,然后在第二时刻使用它们。这是代码:
保存cookie:
let cookie = await page.cookies();
cookie = JSON.stringify(cookie);
fs.writeFile("cookie.txt", cookie, function(err, data){
if (err) {
console.log(err);
} else {
console.log("Successfully Written to File.");
}
});
要读取 Puppeteer 中的 cookie:
await page._client.send("Network.clearBrowserCookies");
await injectCookiesFromFile("cookie.txt", page)
async function injectCookiesFromFile(file, page) {
let cb = async function (_cookies) {
console.log("Injecting cookies from file: %s", JSON.stringify(_cookies) );
//await page.setCookie(..._cookies); // method 1
await page.setCookie(_cookies); // method 2
};
fs.readFile(file, async function(err, data) {
if(err) {
throw err;
}
let cookies = JSON.parse(data);
console.log(cookies);
//await cb(cookies); // method 1
for (var i = 0, len = cookies.length; i < len; i++) {
await cb(cookies[i]); // method 2
}
});
}
读取 cookie 并将其保存到文件中的操作似乎有效。
但对网站没有任何影响,并且 setCookie()
方法似乎无法正常工作。有什么想法吗?
最佳答案
在开始之前,请务必注意,使用 Puppeteer 时通常不需要读取 Cookie 并将其写入文件。
Puppeteer 提供了一个高级 API,可以通过 DevTools 协议(protocol)控制 Chrome 或 Chromium,这意味着 Chromium 可以完成有关 Cookie 的大部分艰苦工作,而无需所有体力劳动。
Chromium 有一个名为 CookieMonster
的内置类它处理浏览器内 cookie 的存储、管理、检索、过期和驱逐。
换句话说,如果您尝试使用 Puppeteer 登录网站,通常可以使用以下简单示例来实现:
'use strict';
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.example.com/login');
await page.type('#username', 'johndoe');
await page.type('#password', 'qwerty1');
await page.click('#submit');
await page.waitForNavigation();
// You are now logged in ...
await browser.close();
})();
Note: Notice that I did not have to create a cookie file to read and write cookies (this is not
cURL
).
如果您仍决定自行管理 cookie,那么了解 Puppeteer 使用 asynchronous 至关重要。 JavaScript。
这意味着要使用 fs.writeFile
写入文件,您需要await
一个Promise
在回调函数中解决或拒绝,以确保文件在导航之前准备就绪。
const write_file = (file, data) => new Promise((resolve, reject) => {
fs.writeFile(file, data, 'utf8', error => {
if (error) {
console.error(error);
reject(false);
} else {
resolve(true);
}
});
});
fs.readFile()
也是如此。 :
const read_file = file => new Promise((resolve, reject) => {
fs.readFile(file, 'utf8', (error, data) => {
if (error) {
console.error(error);
reject(false);
} else {
resolve(data);
}
});
});
此外,最好先等待页面完全加载,然后再将 Cookie 写入文件,因此我建议在导航函数中使用 waitUntil: 'networkidle0'
选项:
await page.goto('https://www.example.com/login', {
waitUntil: 'networkidle0',
});
Note: This may require you to increase the default
timeout
option to allow for the page to completely load.
现在我们了解了 Puppeteer 背后的一些基本概念,我们可以开始手动从文件中读取和写入 cookie。
我们可以使用page.cookies()
, page.setCookie()
,和cdpSession.send()
管理我们的cookie(如下例所示):
'use strict';
const fs = require('fs');
const puppeteer = require('puppeteer');
const write_file = (file, data) => new Promise((resolve, reject) => {
fs.writeFile(file, data, 'utf8', error => {
if (error) {
console.error(error);
reject(false);
} else {
resolve(true);
}
});
});
const read_file = file => new Promise((resolve, reject) => {
fs.readFile(file, 'utf8', (error, data) => {
if (error) {
console.error(error);
reject(false);
} else {
resolve(data);
}
});
});
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const client = await page.target().createCDPSession();
// Open First Page
await page.goto('https://www.example.com/', {
waitUntil: 'networkidle0',
});
// Write All Cookies to File
await write_file('cookies.txt', JSON.stringify(await page.cookies()));
// Open Second Page
await page.goto('https://www.example.com/next-page', {
waitUntil: 'networkidle0',
});
// Clear Browser Cookies
await client.send('Network.clearBrowserCookies');
// Read All Cookies from File
await page.setCookie(...JSON.parse(await read_file('cookies.txt') || '[]'));
await browser.close();
})();
关于cookies - 为什么 Puppeteer 的 setCookie() 似乎没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49214208/