javascript - ubuntu 中未获取 puppeteer 脚本的内容

标签 javascript php node.js puppeteer google-chrome-headless

场景 - 我有一个 puppeteer 脚本,它接受 url 和 json 对象作为执行参数。 - 它是从 html 文件的 php 脚本调用的 - puppeteer 脚本转到 url,获取页面内容,console.log s 它,因此内容在包含上述 php 脚本的 html 中可用。

问题 - 在 Windows 上它运行完美,给出了所需的输出。然而我现在已经将我的项目转移到了 ubuntu 上,这就是麻烦开始的地方。 - 内容无法加载,以空白页结束。 - 我从控制台运行了 puppeteer 脚本,它运行良好,注销了页面内容。但是当我使用 system() 从 php 脚本调用它时,它却没有。但即使是通过 php 脚本,它也能在 Windows 上完美运行。

这是我的 php 代码

    <?php
    if(isset($_POST['url'])){
        $split_url = str_replace('.', '_', explode('/', $_POST['url']));
        $dir = "site_config/";
        $content = '';
        if( is_dir($dir) ){
            if ($dh = opendir($dir)){
                while (($file = readdir($dh)) !== false){
                    $filename = str_replace('.txt','',$file);
                    if($filename === $split_url[2]){
                        $content = file_get_contents($dir.$split_url[2].'.txt');
                    }
                }
                closedir($dh);
            }  
        }
        echo '<script>document.getElementById("website-input-form").style.display = "none";</script>';
        /*to run with phantomjs*/
        //system('phantomjs get_page_phantomjs.js "'.$_REQUEST['url'].'" '.$content);            
        /*to run with puppeteer*/
        system('node get_page_puppeteer.js "'.$_REQUEST['url'].'" '.$content); 
        // system('node sample.js "'.$_REQUEST['url'].'" '.$content);           
    }
?>

您可以在最后一行看到我正在运行另一个示例 Nodejs 脚本。它执行得很完美。

所以我不知道,也许 puppeteer 脚本有问题?

const puppeteer = require('puppeteer');

const url = process.argv[2];    //url from command line argument
const json = process.argv[3];   //config content from command line argument

/*_________________________STEP 1____________________________________*/
    async function run() {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto(url, {
                waitUntil: 'networkidle2',
                timeout: 3000000
            });
        await page.evaluate(function(json){

            //removing unwanted elements from html content
            Array.prototype.slice.call(document.getElementsByTagName("script")).filter(function(script) {
                return script.type != "application/ld+json";
            }).forEach(function(script) {
                script.parentNode.removeChild(script);
            });
            Array.prototype.slice.call(document.getElementsByTagName("style")).filter(function(style) {
                return style.type != "application/ld+json";
            }).forEach(function(style) {
                style.parentNode.removeChild(style);
            });
            Array.prototype.slice.call(document.getElementsByTagName("iframe")).filter(function(iframe) {
                return iframe.type != "application/ld+json";
            }).forEach(function(iframe) {
                iframe.parentNode.removeChild(iframe);
            });
            Array.prototype.slice.call(document.getElementsByTagName("video")).filter(function(video) {
                return video.type != "application/ld+json";
            }).forEach(function(video) {
                video.parentNode.removeChild(video);
            });
            Array.prototype.slice.call(document.getElementsByTagName("img")).filter(function(img) {
                img.setAttribute('style','max-width: 50% !important;');
                return img.src.endsWith('.svg') === true;
            }).forEach(function(img) {
                img.parentNode.removeChild(img);
            });

            //providing the site's config through an element
            var inp = document.createElement('div');
            inp.setAttribute('textcontent', json);
            inp.setAttribute('id', 'config_available');
            var XMLS = new XMLSerializer();
            var inp_xmls = XMLS.serializeToString(inp);
            document.body.insertAdjacentHTML('afterbegin', inp_xmls);

            //injecting the logic script
            inp = document.createElement('script');
            inp.setAttribute('src', './scraperJavascript.js');
            inp.setAttribute('type', 'text/javascript');
            XMLS = new XMLSerializer();
            inp_xmls = XMLS.serializeToString(inp);
            document.body.insertAdjacentHTML('afterbegin', inp_xmls);
        }, json)

        //rendering page's html
        const renderedContent = await page.evaluate(() => new XMLSerializer().serializeToString(document));
        console.log(renderedContent);

        await browser.close();
    }

    run();

但是如果脚本有问题,为什么可以从控制台(在 ubuntu 和 windows 上)和 php 脚本(在 windows 上)成功运行,但不能从 php 脚本(在 ubuntu 上)运行

更新 我对 puppeteer 操纵者端进行了异常检查。确实发生了异常,这是它的消息 错误:无法启动 Chrome! [0608/095818.625603:错误:icu_util.cc(133)]收到的 ICU 数据的文件描述符无效。 [0608/095818.625662:致命:content_main_delegate.cc(57)]检查失败:错误。 #0 0x55dc5336182c 基::调试::StackTrace::StackTrace() #1 0x55dc532e8290 日志记录::LogMessage::~LogMessage() #2 0x55dc51598de3 内容::ContentMainDelegate::TerminateForFatalInitializationError() #3 0x55dc53017941 内容::ContentMain RunnerImpl::Initialize() #4 0x55dc53021c12 service_manager::Main() #5 0x55dc53016184 content::ContentMain() #6 0x55dc571eea39 headless::(匿名命名空间)::RunContentMain() #7 0x55dc571eeac2 headless::HeadlessBrowserMain() #8 0x55dc5301ef8f headless::HeadlessShellMain() #9 0x55dc515971ac ChromeMain #10 0x7f5204329830 __libc_start_main #11 0x55dc5159702a _start 故障排除:https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting .md 在onClose(/var/www/html/master/scraper_puppeteer/node_modules/puppeteer/lib/Launcher.js:255:14)在Interface.helper.addEventListener(/var/www/html/master/scraper_puppeteer/node_modules/puppeteer/lib/Launcher.js:244:50)在emitNone(events.js:111: 20)在Interface.emit(events.js:208:7)在Interface.close(readline.js:370:8)在Socket.onend(readline.js:149:10)在emitNone(events.js:111:20)在Socket.emit(events.js:208:7)在endReadableNT(_stream_readable.js:1055:12)在_combinedTickCallback(inter nal/process/next_tick.js:138:11)

最佳答案

您的服务器可能不允许使用系统功能。如何检查:

<?php echo ini_get('disable_functions');

这是可能的结果:

exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source

<小时/> 另一个可能的原因:如果启用了安全模式,则只能执行此模式的特殊目录内的文件:

<?php 

    if(ini_get("safe_mode")) {
        echo "Can only execute files inside of this dir: " . ini_get("safe_mode_exec_dir");
    }
<小时/>

如果上述检查成功,则可能存在权限问题。修改您的系统调用以获取退出代码,如果它非零,则存在问题:

system('node get_page_puppeteer.js "'.$_REQUEST['url'].'" '.$content, $return_code);
var_dump($return_code);

0 — no error
126 — command is found but is not executable source
127 — system doesn't know a file you're calling source

<小时/>

更新 来自你的 puppeteer 师错误

Failed to launch chrome! [...] Invalid file descriptor to ICU data received

根据this issue权限可能有问题。该用户的解决方案是

cd /usr/local/lib/node_modules/puppeteer/.local-chromium
find . -type d | xargs -L1 -Ixx sudo chmod 755 xx
find . -type f -perm /u+x | xargs -L1 -Ixx sudo chmod 755 xx
find . -type f -not -perm /u+x | xargs -L1 -Ixx sudo chmod 644 xx

关于javascript - ubuntu 中未获取 puppeteer 脚本的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50742081/

相关文章:

javascript - 更改亮度滤镜

javascript - Ajax 出错,每页显示 3 个用户

php - 如何使用php从url读取xml文件

node.js - 查询/扫描 DynamoDB 的结果不一致 - NodeJS

javascript - 如何使用 react-google-maps 通过点击在 map 上添加标记?

php - 动态传递 PHP 变量

javascript - 无法在 PHP 中捕获 POST 变量

javascript - HTML5 到 iOS 应用程序

javascript - nodejs 二进制 websocket mimetype 处理

node.js - nodejs Sequelize orm model.validation 不是函数