2

我想知道是否有可能有一个 .js 文件打开浏览器实例,创建新的页面/选项卡登录到网站(使用用户名/密码)并保持空闲状态。
在第二个 .js 文件中使用文件一个浏览器实例及其页面。

1.js

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({ 
        headless: true,
        args: ['--no-sandbox'], 
        ignoreDefaultArgs: ["--hide-scrollbars"]
    });

    const page = await browser.newPage();
    const response = await page.goto('https://google.com');

    console.log('Browser open in the background (headless)!');
    //await browser.close();
})();

2.js

const puppeteer = require('puppeteer');

(async () => {
    // instructions on browser instance/page from 1.js ...
})();
4

3 回答 3

5

爬虫对象保持浏览器实例的状态,无论您调用/传递该实例,它都引用“背景”中的相同铬。如果这太过分了,而您只想使用 puppeteer 连接到已经运行的 chromium,则可以使用 puppeteer.connect 来完成。看看这个: 如何将 puppeteer “挂钩”到正在运行的 Chrome 实例/选项卡中- mbit

是的,我想这对我来说太过分了:)。但是您发布的链接是我想要的,但有 2 个问题。

这是我所拥有的样本。

// 1.js
// open chromium, new tab, go to google.com, print browserWSEndpoint, disconnect
const puppeteer = require('puppeteer');

(async () => {
    var browser = await puppeteer.launch({headless: false});
    var page = await browser.newPage();
    var response = await page.goto('https://google.com');

    var browserWSEndpoint = browser.wsEndpoint();
    console.log(browserWSEndpoint); // prints: ws://127.0.0.1:51945/devtools/browser/6462daeb-469b-4ae4-bfd1-c3bd2f26aa5e

    browser.disconnect();
})();

// 2.js
// connect to the open browser with the browserWSEndpoint manualy put in, ... , disconect. 
const puppeteer = require('puppeteer');

(async () => {
    var browser = await puppeteer.connect({browserWSEndpoint: 'ws://127.0.0.1:51945/devtools/browser/6462daeb-469b-4ae4-bfd1-c3bd2f26aa5e'});

    // somehow use the tab that is open from 1.js (google.com)

    await browser.disconnect();
})();

我从 console.log 1.js 得到 browserWSEndpoint 字符串。它工作得很好,但我有两个困难。

1 - 我如何使用来自 1.js 的变量 browserWSEndpoint,这样我就不必总是将它复制粘贴到 2.js。

2-如果我在 1.js 上打开一个新页面/选项卡并去谷歌并断开连接 (browser.disconnect()),如何在 2.js 上使用该页面/选项卡。

于 2020-02-11T17:23:28.330 回答
2

工作测试代码 getEmail.js 是实际页面的导出位置。在评论中要求澄清。

获取浏览器.js

const puppeteer = require("puppeteer");
module.exports = {
browser: {},
pptr_instance_url:"",
getBrow: async function(){  try {
    console.log("line6",this.pptr_instance_url);
    this.browser = await puppeteer.connect({browserWSEndpoint: this.pptr_instance_url}).catch(async e =>{
        console.log("end point",this.pptr_instance_url);
        this.browser = await puppeteer.launch({timeout: 0});
        this.pptr_instance_url = this.browser.wsEndpoint();
        console.log("line 11",this.pptr_instance_url);
        return this.browser;
    });
    return this.browser;
}catch (e){
    console.log(e)
} }
}

pageRenderer.js

const abc = require("../getBrowsernew")
const pageRenderer = async (request) => {
const {reactProjectUrl} = constants, uuidStorageKey = uuidv4(),
    localStorageObject = {[uuidStorageKey]: request.body};

const browser = await abc.getBrow();
let url = "someurl.com"
await setLocalStorage(browser, url, localStorageObject);
const page = await browser.newPage();
const response = await page.goto(
    url,
    {
        waitUntil: "networkidle0"
    }, {waitUntil: 'load', timeout: 0}
);
return page;
}

module.exports = pageRenderer;

获取电子邮件.js

const pageRenderer = require("./pageRenderer");

const getEmail =async (request) =>{

const page = await pageRenderer(request)
const emailbody =  await page.content();
page.close();
return emailbody;
  }

module.exports = getEmail;
于 2021-09-03T00:11:45.640 回答
0

您可以通过多种方式实现这一点,例如使用具有功能的单独模块或不同的类,这取决于您的特定需求。

您可以拥有一个启动浏览器并创建页面以及一些额外功能的类。

//1.js
const puppeteer = require('puppeteer');

class Crawler {
    constructor() {
        //init with whatever values you'll need in your class
        //or throw an error if the object wasn't created through build
    }
    static async build() {
        let crawler = new Crawler();
        await crawler._init();
        return crawler;
    }
    async _init() {
        //launch the browser and keep its state
        this._browser = await puppeteer.launch({timeout: 0});
        //create a page and keep its state
        this._page = await this._browser.newPage();
    }
    //getter
    get browser() {
        return this._browser;
    }
    //getter
    get page() {
        return this._page;
    }
    async login(url) {
         await this._page.goto(url);
         //do whatever is related to the login process
    }
}

module.exports = {Crawler};

请注意,我们不能在构造函数中使用异步函数。build由于启动浏览器是异步的,我们在创建对象时使用类似函数的东西来启动浏览器。然后我们像这样创建爬虫对象:

//2.js
const {Crawler} = require('./1.js');

(async() => {
    let crawler = await Crawler.build(); 
    await crawler.login("https://example.com");
    //access crawler's page
    console.log(crawler.page.url());
})();

请记住,这只是一个示例,绝不能代表最佳实践。所以首先,你需要了解你想从这种封装中实现什么,然后采用最适合你的方法。

在此处阅读有关 JS 类的更多信息

于 2020-02-09T00:14:59.020 回答