Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Puppeter中运行page.screenshot in page.evaluate?_Javascript_Node.js_Web Scraping_Puppeteer_Headless - Fatal编程技术网

Javascript 如何在Puppeter中运行page.screenshot in page.evaluate?

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

我正在创建一个屏幕刮板,需要刮一个页面的内容,并采取它的截图。为此,我使用了木偶演员,但我遇到了一个障碍。当我试图调用一个在page.evalate内运行page.screenshot的函数时,我得到一个错误,该函数没有定义

这是我的密码:

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;
}