我正在使用puppeteer来抓取一些页面,但我很好奇如何在节点应用程序的生产中管理它。我将在一天内刮掉多达500,000页,但这些刮擦工作将随机发生,因此我不能单独排队。
我想知道的是,打开浏览器,转到页面,然后在每个作业之间关闭浏览器更好吗?我认为这会慢得多,但可能会更好地处理内存?
或者我在应用程序启动时打开一个全局浏览器,然后只是转到页面,并在我完成它时有一些方法可以转储该页面(例如关闭chrome中的所有选项卡,但不关闭chrome)然后只是我需要的时候重新打开一个新页面?这种方式看起来会更快,但可能会占用大量内存。
我从来没有使用过这个库,特别是在生产环境中,所以我不确定是否有值得注意的事情。
如果您每天要刮500,000页(大约每0.1728秒一页),那么我建议在现有的浏览器会话中打开一个新页面,而不是为每个页面打开一个新的浏览器会话。
您可以使用以下方法打开和关闭Page:
const page = await browser.newPage();
await page.close();
如果你决定为你的项目使用一个Browser,我会确保实现错误处理程序,以确保如果程序崩溃,你创建一个新的Page,Browser或BrowserContext时停机时间最短。
您可能希望使用独立浏览器创建多个Chromium实例的池。这样做的好处是,当一个浏览器崩溃时,所有其他作业都可以继续运行。一个浏览器(具有多个页面)的优点是具有轻微的内存和CPU优势,并且cookie在您的页面之间共享。
库puppteer-cluster(免责声明:我是作者)为您创建了一个浏览器或页面池。它将负责您的创建,错误处理,浏览器重启等。因此,您可以简单地对作业/ URL进行排队,并且库可以处理其他所有内容。
const { Cluster } = require('puppeteer-cluster');
(async () => {
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_BROWSER, // use one browser per worker
maxConcurrency: 4, // cluster with four workers
});
// Define a task to be executed for your data (put your "crawling code" in here)
await cluster.task(async ({ page, data: url }) => {
await page.goto(url);
// ...
});
// Queue URLs when the cluster is created
cluster.queue('http://www.google.com/');
cluster.queue('http://www.wikipedia.org/');
// Or queue URLs anytime later
setTimeout(() => {
cluster.queue('http://...');
}, 1000);
})();
您还可以直接排队函数,以防您有不同的任务要做。通常你会在通过cluster.close()
完成后关闭群集,但你可以自由地让它保持打开状态。您可以找到另一个集群的示例,该集群在repository中发出请求时获取数据。