Node.js Puppeter在每次函数调用时创建一个新的浏览器实例
我正在尝试创建一些小函数,以便有人能够将它们粘合在一起,从而拥有一个更可重用的代码库 我试图在init.js文件中创建browser对象的实例。然后在login.js文件中传递该浏览器对象,然后使用我创建的相同浏览器对象,我希望导航到需要登录的2个页面 我必须遵循上面提到的3个文件,并且我已经设置了一个登录到github的示例,然后导航到“概要文件”页面,然后导航到“项目”页面 然后我在登录页面上使用它Node.js Puppeter在每次函数调用时创建一个新的浏览器实例,node.js,puppeteer,Node.js,Puppeteer,我正在尝试创建一些小函数,以便有人能够将它们粘合在一起,从而拥有一个更可重用的代码库 我试图在init.js文件中创建browser对象的实例。然后在login.js文件中传递该浏览器对象,然后使用我创建的相同浏览器对象,我希望导航到需要登录的2个页面 我必须遵循上面提到的3个文件,并且我已经设置了一个登录到github的示例,然后导航到“概要文件”页面,然后导航到“项目”页面 然后我在登录页面上使用它 // login.js 'use strict'; const _browser = r
// login.js
'use strict';
const _browser = require('./init.js');
const baseUrl = "https://github.com/login";
let user = {
username : 'johnDoe',
password : 'asdzxc123',
};
module.exports = async () => {
try {
const browser = await _browser();
var page = await browser.newPage();
await page.goto(baseUrl, {waitUntil:'networkidle2'});
await page.type('#login_field', user.username);
await page.type('#password', user.password);
const form = await page.$('input[type=submit]');
await form.evaluate( form => form.click() );
await page
.waitForSelector('.application-main')
.then(() => {
return browser;
});
}catch (err) {
console.error(err);
}
};
登录后,我想在app.js上使用同一个实例
// app.js
'use strict';
const _browser = require('./login.js');
viewProfile();
viewProjects();
async function viewProfile(){
try {
const browser = await _browser();
var page = await browser.newPage();
await page.goto("https://github.com/settings/profile", {waitUntil:'networkidle2'});
}catch (err) {
console.error(err);
}
}
async function viewProjects(){
try {
const browser = await _browser();
var page = await browser.newPage();
await page.goto("https://github.com/atragan?tab=projects", {waitUntil:'networkidle2'});
}catch (err) {
console.error(err);
}
}
这是目前的结构,
- init.js正在创建浏览器实例
- login.js正在调用init.js
- app.js正在调用login.js
Andreas这不起作用,因为您正在对登录文件调用_browser(),这将对init.js文件调用_driver.launch()。因此,无论何时从登录文件调用_browser方法,实际上每次都在创建一个新实例 这是一个循序渐进的解决方案 login.js 首先,您需要返回在此处创建的浏览器 重写以下内容
await page
.waitForSelector('.application-main')
.then(() => {
return browser;
});
对此,
await page.waitForSelector('.application-main')
return browser;
现在,您可以在其他函数中使用它
app.js
在运行viewProfile和viewProjects之前创建浏览器实例,然后将实例传递到内部
const browser = await _browser();
viewProfile(browser);
viewProjects(browser);
从内部卸下浏览器
async function viewProfile(browser){
try {
var page = await browser.newPage();
await page.goto("https://github.com/settings/profile", {waitUntil:'networkidle2'});
}catch (err) {
console.error(err);
}
}
可能的结构
您可以使用基于类的结构以获得更好的可读性和可维护性。您可以将函数拆分为文件,在constractor中使用.bind(this),等等。我将把这个留给你
举个例子
class MyCrawler{
init(){
// the code from init
}
login(){
// the code from login
// except you use this.browser or this.page instead of _browser;
}
viewProfile(){
// ... same as the login above
}
}
以后你可以这样称呼它
const crawler = new MyCrawler()
await crawler.init()
await crawler.login()
await crawler.viewProfile()
我投票结束这个问题,因为它不是一个问题。你会如何发布这个?因为我在这个问题上纠缠了几天,找不到前进的方法这个问题最适合我,但是当我查看代码时,我发现如果用不同的方式问这个问题,这可能是一个不错的问题。他只是没有问正确的问题。最正确的问题可能是“如何创建浏览器实例并在多个文件中使用它?”首先感谢您的时间,我试图更改我的文件以反映您提出的更改(我也更新了要点中的文件),但我遇到以下错误:const browser=wait require('./functions/login.js')); ^^^^^ SyntaxError:await仅在异步函数中有效是的,您需要将其包装在异步函数中,或者使用
。然后()
例如,async()=>({您的代码})了解有关async await的更多信息在这里您应该更新答案上的代码,而不是gist文件。这样的话,问题就在这样的范围内了。
const crawler = new MyCrawler()
await crawler.init()
await crawler.login()
await crawler.viewProfile()