如何使用 jsdom 从文件中获取 DOM?

How to get DOM from a file using jsdom?

我正在使用 Node.js,它的插件 Request 和 FS 将网页保存在我的硬盘上。这是通过以下代码完成的:

function loadURL(url, file_path, handler) {
    request.get(url).on('error', (error) => handler(error)).pipe(fs.createWriteStream(file_path, {'flags' : 'w'}))
}

我现在想从这个本地文件中获取 HTML DOM 多亏了 Node.JS 插件 JSDOM.

因此:

  1. 感谢 FS 插件,我必须阅读此文件;
  2. 当读取所有文件的HTML代码时,我必须将后者存储到一个字符串中;
  3. 最后,我必须打电话给:jsdom.jsdom(the_string_containing_HTML_code)

第 3 步很简单。第二个也可能。 但是......我怎么能使用 FS 异步读取本地文件? read 根据文档不应使用函数;相反,我应该使用 pipe... 但后者只是将 WritableStream 附加到 ReadableStream... 它不能满足我的要求。

注意:我真的很想使用异步方法。

对于您的用例 (AFAIK),fs.readFile() 是完全可以接受的。该方法是异步的。同步且不明智的方法称为 fs.readFileSync()。

我建议使用不处理流的 request 调用,而只是 returns 数据回调:

function loadURL(url, file_path, handler) {
    request.get(url,(error,response,body) => {
        if (error) {
            handler(error,null);
        }
        fs.writeFile(file_path,body,'utf8',(err) => {
            if (err) {
                handler(err,null);
            }
            // now you can safely assume your file is written to disk
            // you still have $body in memory, but let's pretend you don't
            // for sake of this exersise
            fs.readFile(file_path,'utf8',(err,html) => {
                if (err) handler(err,null);
                jsdom.env(html,(err,window) => {
                    if (err) handler(err,null);
                    // SUCCESS!
                    handler(null,window);
                });
            });
        });
    });
}

这适用于低成本工作负载。如果你想要更细微的控制流,流是好的。但我建议先尝试这种方式。

此代码假定 handler() 具有签名 handler(err,window)