Node.js Puppeter在每次函数调用时创建一个新的浏览器实例

Node.js Puppeter在每次函数调用时创建一个新的浏览器实例,node.js,puppeteer,Node.js,Puppeteer,我正在尝试创建一些小函数,以便有人能够将它们粘合在一起,从而拥有一个更可重用的代码库 我试图在init.js文件中创建browser对象的实例。然后在login.js文件中传递该浏览器对象,然后使用我创建的相同浏览器对象,我希望导航到需要登录的2个页面 我必须遵循上面提到的3个文件,并且我已经设置了一个登录到github的示例,然后导航到“概要文件”页面,然后导航到“项目”页面 然后我在登录页面上使用它 // login.js 'use strict'; const _browser = r

我正在尝试创建一些小函数,以便有人能够将它们粘合在一起,从而拥有一个更可重用的代码库

我试图在init.js文件中创建browser对象的实例。然后在login.js文件中传递该浏览器对象,然后使用我创建的相同浏览器对象,我希望导航到需要登录的2个页面

我必须遵循上面提到的3个文件,并且我已经设置了一个登录到github的示例,然后导航到“概要文件”页面,然后导航到“项目”页面

然后我在登录页面上使用它

// 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
问题是:

我想在所有模块中传递相同的浏览器实例。现在它正在app.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()