【发布时间】:2020-06-28 00:45:58
【问题描述】:
我正在请求一个允许抓取网页的 API。
我使用 expressJS 和 Postman 进行测试,我使用 puppeter 和 Cheerio 进行抓取。
可以,但是用 Postman 测试时,请求的执行时间在 8s 到 13s 之间。
我发现这花费了太多时间,我想知道这是否正常,因为我还没有在生产中部署我的 API, 我现在只是在本地测试它。
我尝试连接良好。
编辑
我写了这个函数,带有 async / await 承诺,执行时间平均在 2.5s 到 4s 之间。
看起来还需要时间。
还有其他方法可以优化这个请求吗?
我在中型网站上使用的脚本示例:
const puppeteer = require('puppeteer');
const scrapURL = (req, res, next) => {
let url = req.query.url;
puppeteer.launch({ headless:true }).
then(async function(browser) {
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => {
if (request.resourceType() === 'document')
request.continue();
else
request.abort();
});
await page.goto(url);
const data = await page.$eval("h1", element => element.innerText);
await browser.close();
return res.status(201).json({ data:data});
})
.catch(error => res.status(400).json({ error:error }))
}
【问题讨论】:
-
您能否在您的代码示例中添加您的
$ = cheerio.load...是如何设置的?否则,我们将无法运行您的 sn-p。问题:使用 Promise 代替 async/await 语法有什么特别的原因吗? -
我导入了cheerio,然后我能够恢复我的url的标题h1,脚本工作只是我不明白为什么这个过程这么慢。我更新了我的帖子
-
另外两个问题:(1)你是不是故意在抓取结束时不关闭浏览器?您是否多次调用抓取脚本以便重用打开的浏览器实例? (2) 我在问为什么你更喜欢旧的 js 承诺而不是 async/await 语法,因为它会让你的爬虫脚本在 puppeteer 脚本编写时更加方便,但是如果你使用的是比 Node 8 更旧的版本,你当然没有除了旧的承诺格式之外的其他选择。那么:async/await 不是一个选项?
-
顺便说一句,你不需要有 puppeteer 的cheerio。
const data = $("h1", html).text();可以替换为const data = await page.$eval("h1", element => element.innerText);。这消除了一个依赖项和使用 Cheerio 重新解析 HTML(HTML 已经被 puppeteer 解析为 DOM)。 -
如果这2.5-4s包括打开和关闭浏览器,这似乎是一个不可避免的延迟。也许您可以保留打开的浏览器并每次都连接到它?