我正在express/node/ubuntu上运行puppeteer,如下所示:
var puppeteer = require('puppeteer');
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
(async () => {
headless = true;
const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']});
const page = await browser.newPage();
url = req.query.url;
await page.goto(url);
let bodyHTML = await page.evaluate(() => document.body.innerHTML);
res.send(bodyHTML)
await browser.close();
})();
});
多次运行此脚本会留下数百个僵尸:
$ pgrep chrome | wc -l
133
阻塞了SRV,
我该怎么解决这个问题?
从Express JS脚本运行kill
可以解决这个问题吗?
除了 puppet 戏和Headless Chromium ,有没有更好的方法来获得同样的效果?
8条答案
按热度按时间xa9qqrwz1#
啊!这是一个简单的疏忽。如果发生错误,你的
await browser.close()
永远不会执行,从而给你留下僵尸怎么办?使用
shell.js
似乎是解决这个问题的一种很好的方法。更好的做法是使用
try..catch..finally
。原因是您希望浏览器无论是否出现满意的流或抛出错误都关闭。与其他代码片段不同,您不必尝试同时在catch
块和finally
块中关闭浏览器。无论是否抛出错误,finally
块始终执行。所以,你的代码应该看起来像,
希望这有帮助!
s71maibg2#
像这样将代码 Package 在try-catch中,看看是否有帮助
vdgimpew3#
根据我的经验,调用close后,浏览器关闭过程可能需要一段时间,无论如何,可以检查浏览器进程属性,查看是否还没有关闭,强制杀死它。
我也在下面发布了我的 puppet 师资源管理器的完整代码。
bq8i3lrv4#
我用https://www.npmjs.com/package/shelljs来解
sxissh065#
尝试在发送响应之前关闭浏览器
lnxxn5zx6#
我遇到了同样的问题,虽然你的shelljs解决方案确实有效,但它会杀死所有chrome进程,这可能会中断一个正在处理请求的进程。
8e2ybdfx7#
使用
这种情况的发生是因为浏览器所包含的是一个你必须解决它的承诺,我为此遭受了很多我希望它有帮助
idfiyjo88#
我使用以下基本设置运行Puppeteer:
在这里,
finally
块保证浏览器将正确关闭,而不管是否抛出错误。错误被记录(如果需要)。我喜欢.catch
和.finally
作为链接调用,因为主线Puppeteer代码更扁平,但这完成了同样的事情:没有理由调用
newPage
,因为Puppeteer从打开的页面开始。至于Express,您只需要将上面的整个代码(包括
let browser;
,不包括require("puppeteer")
)放置到您的路线中,就可以开始了,尽管您可能希望使用async middleware error handler。你问:
除了 puppet 戏和Headless Chromium ,有没有更好的方法来获得同样的效果?
这取决于你在做什么以及你所说的“更好”是什么意思。如果你的目标是得到
document.body.innerHTML
,并且你感兴趣的页面内容被烘焙到静态HTML中,你可以完全转储Puppeteer,只请求得到资源,然后使用Cheerio提取所需的信息。另一个注意事项是,您可能不需要为每个请求加载和关闭整个浏览器。如果可以为每个请求使用一个新页,请考虑以下策略:
最后,确保不要将任何超时设置为0(例如,
await page.setDefaultNavigationTimeout(0);
),因为这可能会导致脚本永远挂起,如果您需要一个较宽的超时,最多将其设置为几分钟--足够长,不会触发误报。另见: