- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图实现的目标是存储来自网站的 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/
我对java有点陌生,所以如果我犯了一个简单的错误,请原谅我,但我不确定我哪里出错了,我收到的错误是“预期的.class,预期的标识符,而不是声明, ';'预期的。”我尝试了不同的方法,并从这些方法中
This question already has answers here: chai test array equality doesn't work as expected (3个答案) 3年前
我正在学习 Java(对不起,我的英语很差,这不是我的母语),当我在 Eclipse (JavaSE-1.7) 中在我输入的每个“try”中执行“try-finally” block 时,会出现以下消
我收到两个错误,指出 token 上的语法错误,ConstructorHeaderName expected instead & token “(”上的语法错误,< expected 在线: mTM.
我找不到错误。 Eclipse 给我这个错误。每个 { } 都是匹配的。请帮忙。 Multiple markers at this line - Syntax error on token “)”,
代码: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class DoubleIt extends
我正在用 python(Vs 代码)编写代码,但出现此错误: Expected ")" Pylance 错误发生在:def main() 我试着运行我的 main 并将它打印到我的屏幕上。我用谷歌搜
我正在尝试按照 documentation 中的建议使用异步函数。但我收到此错误 意外的 token ,预期 ( async function getMoviesFromApi() { try
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
第一行包含一个表示数组长度的整数p。第二行包含用空格分隔的整数,这些整数描述数组中的每个元素。第三行打印一个整数,指示负数组的数量。 package asgn3; import java.util.*
好的,我是初学者,我必须修复此 java 表达式语言代码才能在我的系统 (Windchill) 中工作,但看起来我在语法中遗漏了一些内容: LWCNormalizedObject lwc =
我无法编译我的程序! 我想我缺少一个花括号,但我怎么也看不出在哪里! import javax.swing.*; import java.awt.*;
我的 jQuery 代码有问题,我的 Firebug 向我发出警告:需要选择器。 这是代码: $("img[id$='_tick']").each(function() { $(this).c
我的新类(class) Fountainofyouth 遇到了问题。尝试构建整个项目后,调试器显示 warning: extended initializer lists only available
我已经从 Java 转向 CPP,并且正在努力围绕构造构造函数链进行思考,我认为这是我的问题的根源。 我的头文件如下: public: GuidedTour(); GuidedTour(string
鉴于以下 for(var i=0; i< data.cats.length; i++) list += buildCategories(data.cats[i]); jsLint 告诉我 Expect
我有这个 json,但 Visual Studio Code 在标题中给了我警告。 [ { "title": "Book A", "imageUrl": "https:
我正在尝试编写一个有条件地禁用四个特殊成员函数(复制构造、移动构造、复制赋值和移动赋值)的包装类,下面是我用于测试目的的快速草稿: enum class special_member : uint8_
所以我用 F# 编写了一个非常简单的程序,它应该对 1000 以下的所有 3 和 5 的倍数求和: [1..999] |> List.filter (fun x -> x % 3 = 0 || x %
我是一名优秀的程序员,十分优秀!