【问题标题】:EISDIR error when using fs writeFile, but the folder does exist使用 fs writeFile 时出现 EISDIR 错误,但该文件夹确实存在
【发布时间】:2017-11-19 06:06:53
【问题描述】:

我使用 request 来获取一个页面,该页面在我使用cheerio 解析的表格中包含一堆锚标签(100)。

我获取每个锚标记的 href 属性值并请求每个页面。

然后我使用cheerio 解析每个页面。因此,新页面中 h1 标记中的文本成为我的文件名。

所以当我想使用 fs write 向这个特定的文件名写入一些内容时,我得到了

{ 错误:EISDIR:对目录进行非法操作,打开“/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/samples/” 在错误(本机) 错误号:-21, 代码:'EISDIR', 系统调用:'打开', 路径:'/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/samples/' }

但是,有些文件已创建,但绝大多数未创建。示例文件夹确实存在。除了这个错误,我还收到了一个 Cheerio 解析错误

/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/node_modules/cheerio/lib/parse.js:69 var oldParent = node.parent ||节点根, ^

TypeError:无法读取未定义的属性“父级” 在 Function.exports.update (/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/node_modules/cheerio/lib/parse.js:69:25) 在 module.exports (/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/node_modules/cheerio/lib/parse.js:19:11) 在 Function.exports.load (/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/node_modules/cheerio/lib/static.js:27:14) 在 Request._callback (/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/scrape.js:19:24) 在 self.callback (/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/node_modules/request/request.js:188:22) 在 emitOne (events.js:96:13) 在 Request.emit (events.js:188:7) 在 Request.onRequestError (/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/node_modules/request/request.js:884:8) 在 emitOne (events.js:96:13) 在 ClientRequest.emit (events.js:188:7)

这是我的代码

 request(seed, function (error, response, html) {
    if (!error && response.statusCode == 200) {
       var $ = cheerio.load(html);

       $('td:first-child a').each(function(i, element){

          var fullUrl = seed + element.attribs.href.substring(1);
          request(fullUrl, function(error, response, body) {

              var $$ = cheerio.load(body);

              var title = $$('h1[property="dc:title"]').text();

              fs.writeFile('/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/samples/' + title, 'some random text', function (err) {
                  if (err) {
                      return console.log(err)
                  }
              });

          });
      });
   }
 });

编辑:我根据罗伯特的建议添加了一些检查。现在我没有收到 EISDIR 错误,但是许多确实具有有效标题的文件仍未创建。解析问题仍然存在。

request(seed, function (error, response, html) {
    if (!error && response.statusCode == 200) {
       var $ = cheerio.load(html);

       $('td:first-child a').each(function(i, element){

          var fullUrl = seed + element.attribs.href.substring(1);
          request(fullUrl, function(error, response, body) {

              if(body === undefined || body === '' || body === null) {
                console.log('wonky');
                console.log(element.attribs.href.substring(1));// Every execution of the program prints something different
              }
              var $$ = cheerio.load(body);

              var title = $$('h1[property="dc:title"]').text();

              if(title !== '' && title !== undefined && title !== null) {
             fs.writeFile('/Users/dhruvprakash/Desktop/Projects/simple-node-scraper/samples/' + title, 'some random text', function (err) {
                  if (err) {
                      return console.log(err)
                  }
              });
             }
          });
      });
   }
 });

【问题讨论】:

    标签: javascript node.js fs


    【解决方案1】:

    您没有检查title 是否确实包含正确的文件名。

    我的猜测是它是空的,这意味着您正在尝试 writeFile 到目录本身,这也是错误状态:“对目录的非法操作”

    【讨论】:

    • 嗯,现在我添加了对标题的检查,确保在执行 writeFile 之前它没有未定义。我在帖子中没有提到的一件事是,在这些 EISDIR 错误之后,我还收到了来自 Cheerio 的解析错误。所以我添加了一个检查来查看加载到 $$ 中的主体是否未定义,你瞧,有时它是未定义的。然后我打印出 element.attribs.href.substring(1) 以找到罪魁祸首,但是对于程序的每次执行,我得到了不同的罪魁祸首!我认为这个问题与发生的一些异步不稳定的事情有关。
    • 值改变并不奇怪,因为您将它记录在内部异步函数的处理程序中。您基本上启动了 100 个并发 HTTP 请求,并且您无法假设它们完成的顺序。堆栈跟踪不是很清楚,但是您应该在自己的代码中查找出现在其中的位置(而不是库中的位置)。它们可能会提供您收到错误的线索(尽管对于嵌套的request 调用,您仍在调用cheerio.load(),而正文可能“不稳定”)。另外,在嵌套的request 调用中检查error
    • 嗨!检查内部请求的错误和 response.statusCode 让我对问题所在有了一些了解。事实证明,我正在抓取的网站正在发送状态码为 503 的响应。这可能是因为我正在发出多个请求,它们之间没有延迟。为了解决这个问题,你有什么建议?如果出现 503 则继续重试或在每个请求之间引入延迟?
    • @DhruvPrakash 看看async.queue(),你可以使用它来限制并发请求的数量。这个想法是在.each() 循环中,您将 URL 推送到队列中,并且您将拥有一个执行请求的队列处理程序。
    猜你喜欢
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 2012-01-07
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多