Javascript 如何在Puppeter中运行page.screenshot in page.evaluate?
我正在创建一个屏幕刮板,需要刮一个页面的内容,并采取它的截图。为此,我使用了木偶演员,但我遇到了一个障碍。当我试图调用一个在page.evalate内运行page.screenshot的函数时,我得到一个错误,该函数没有定义 这是我的密码:Javascript 如何在Puppeter中运行page.screenshot in page.evaluate?,javascript,node.js,web-scraping,puppeteer,headless,Javascript,Node.js,Web Scraping,Puppeteer,Headless,我正在创建一个屏幕刮板,需要刮一个页面的内容,并采取它的截图。为此,我使用了木偶演员,但我遇到了一个障碍。当我试图调用一个在page.evalate内运行page.screenshot的函数时,我得到一个错误,该函数没有定义 这是我的密码: async function getContent(clink, ce, networkidle, host, filepath) { let browser = await puppeteer.launch(); let c
async function getContent(clink, ce, networkidle, host, filepath) {
let browser = await puppeteer.launch();
let cpage = await browser.newPage();
await cpage.goto(clink, { waitUntil: networkidle });
let content = await cpage.evaluate((clink, ce, networkidle, host, filepath, pubDate) => {
let results = '';
let enclurl = clink;
takeScreenshot(enclurl, filepath, networkidle)
.then(() => {
console.log("Screenshot taken");
})
.catch((err) => {
console.log("Error occured!");
console.dir(err);
});
results += '<title><![CDATA[' + 'test' + ']]</title>';
results += '<description><![CDATA[' + '<img src="' + host + filepath.slice(1) + '">' + document.querySelector(ce).innerHTML + ']]</description>';
results += '<link>' + clink + '</link>';
results += '<guid>' + clink + '</guid>';
results += '<pubDate>' + pubDate + '</pubDate>';
return results;
}, clink, ce, networkidle, host, filepath, pubDate);
await cpage.close();
await browser.close();
return content;
}
在页面外调用Take screenshot时效果很好。我得到的确切错误是“takeScreenshot未定义”。我有另一个函数,可以解析RSS提要并获取源URL的屏幕截图,但它根本不使用page.evaluate
在调用getContent()之前,我已经将对takeScreenshot的调用添加到了代码的前面部分,但现在看来getContent()总是以未定义的形式返回。我的新getContent()内容如下:
我也没有看到console.log('ce='+ce)被写入日志。将console.log移出page.evaluate循环后,它记录了内容的适当值,即具有指定类的元素的HTML。尽管返回内容的值尚未定义。Page.evaluate有一种奇怪且不直观的工作方式: 函数的代码(在您的情况下:(clink、ce、networkidle、host、filepath、pubDate)=>{…})不会在脚本中执行。此函数在序列化后,发送到无头浏览器,里面有木偶师 如果要从evaluate函数内部调用函数,通常(但不是在本例中)可以使用以下技巧之一: 但在这种情况下。。。有个问题! 在takeScreenshot中还有另外一个功能不能在Puppeter的无头浏览器中使用,那就是puppeter.launch();此函数需要很多依赖项(和相同的可执行文件)。。。而且不能通过 要执行所需操作,请将代码的屏幕截图部分移出:
async function getContent(clink, ce, networkidle, host, filepath) {
let browser = await puppeteer.launch();
let cpage = await browser.newPage();
await cpage.goto(clink, { waitUntil: networkidle });
let content = await cpage.evaluate((clink, ce, networkidle, host, filepath, pubDate) => {
let results = '';
let enclurl = clink;
results += '<title><![CDATA[' + 'test' + ']]</title>';
results += '<description><![CDATA[' + '<img src="' + host + '{REPL_ME}' + '">' + document.querySelector(ce).innerHTML + ']]</description>';
results += '<link>' + clink + '</link>';
results += '<guid>' + clink + '</guid>';
results += '<pubDate>' + pubDate + '</pubDate>';
return results;
}, clink, ce, networkidle, host, filepath, pubDate);
await takeScreenshot(enclurl, filepath, networkidle);
content = content.replace('{REPL_ME}', filepath)
await cpage.close();
await browser.close();
return content;
}
异步函数getContent(clink、ce、networkidle、host、filepath){
let browser=wait puppeter.launch();
让cpage=wait browser.newPage();
wait cpage.goto(clink,{waitUntil:networkidle});
让content=wait cpage.evaluate((clink、ce、networkidle、host、filepath、pubDate)=>{
让结果=“”;
让Enclur=叮当声;
结果+=”;
结果+=”;
结果+=''+叮当声+'';
结果+=''+叮当声+'';
结果+=''+pubDate+'';
返回结果;
},clink,ce,networkidle,host,filepath,pubDate);
等待截图(enclurl、filepath、networkidle);
content=content.replace(“{REPL_ME}”,文件路径)
等待cpage.close();
等待浏览器关闭();
返回内容;
}
谢谢,我一直在这样做,所以现在我在主函数中获取内容之前调用takeScreenshot,只使用RSS项目中图像URL的文件路径。现在我正在研究一个新问题,涉及到当class属性有多个类时,querySelector()的使用,例如class=“text left p-2”。到目前为止,我用类似的类来选择元素的结果是空的。我的英语说得不太好。如果您想选择例如:
和
选择器是:“.c1、.c2”>如果您想选择
选择器是“.c1.c2”>如果我不明白,很抱歉!看来我说我的解决方案太快了。现在截图拍摄得很好,但是无论类值是什么,getContent()的结果总是未定义的。我将用新版的getContent()更新我的问题。你看不到console.log,原因相同:你是在无头浏览器上登录,而不是在控制台上。尝试返回ce并将其从evaluate函数中打印出来以进行调试,这可能有助于解决您的问题。
async function getContent(clink, ce, networkidle) {
let browser = await puppeteer.launch();
let cpage = await browser.newPage();
await cpage.goto(clink, { waitUntil: networkidle });
let content = await cpage.evaluate((ce) => {
let cefc = ce.charAt(0);
if (cefc != '.') {
ce = '#' + ce;
}
console.log('ce=' + ce);
let results = document.querySelector(ce).innerHTML;
return results;
}, ce);
await cpage.close();
await browser.close();
return content;
}
async function getContent(clink, ce, networkidle, host, filepath) {
let browser = await puppeteer.launch();
let cpage = await browser.newPage();
await cpage.goto(clink, { waitUntil: networkidle });
let content = await cpage.evaluate((clink, ce, networkidle, host, filepath, pubDate) => {
let results = '';
let enclurl = clink;
results += '<title><![CDATA[' + 'test' + ']]</title>';
results += '<description><![CDATA[' + '<img src="' + host + '{REPL_ME}' + '">' + document.querySelector(ce).innerHTML + ']]</description>';
results += '<link>' + clink + '</link>';
results += '<guid>' + clink + '</guid>';
results += '<pubDate>' + pubDate + '</pubDate>';
return results;
}, clink, ce, networkidle, host, filepath, pubDate);
await takeScreenshot(enclurl, filepath, networkidle);
content = content.replace('{REPL_ME}', filepath)
await cpage.close();
await browser.close();
return content;
}