如何使用这些Node模块通过文件或URL接受HTML,然后输出JSON作为现有HTML元素的validation?

本质上,我需要做的是采取本地grader.js文件,然后在命令行中使用它inputHTML,然后将输出JSON数据到控制台validation多个HTML元素的存在。 用法看起来像这样:

./grader.js --checks checks.json --file index.html ./grader.js --checks checks.json --url http://google.com 

正在使用的Node模块是Commander(用于在命令行中工作),Cheerio(用于HTML)和Restler(用于从URL获取HTML)。

checks.json文件非常简单,只需要检查是否存在一些简单的HTML元素,以确定它们是否存在于页面上:

 ["h1", ".navigation", ".logo", ".blank", ".about", ".heading", ".subheading", ".pitch", ".video", ".thermometer", ".order", ".social", ".section1", ".section2", ".faq", ".footer"] 

grader.js文件是事情变得更复杂的地方。 下面的代码实际上起作用,因为它需要命令行参数,并且确实是否存在HTML元素的真值或假值。 但在底部添加URL检查后,它不能正常工作。 我的checkURL函数有问题,而且我使用底部的Commander代码来实现它。 即使真假值依赖于我使用的HTML文件/ URL是正确的,但我最终还是将两个检查都吐出到控制台上,即使我只想检查文件或URL,而不是两者。 我相当新,所以我很惊讶,它可以工作。 这可能与默认值有关,但是当我尝试进行这些更改时,checkURL函数似乎分解了。 在此先感谢您的帮助,我真的很感激。

 #!/usr/bin/env node var fs = require('fs'); var program = require('commander'); var cheerio = require('cheerio'); var rest = require('restler'); var HTMLFILE_DEFAULT = "index.html"; var CHECKSFILE_DEFAULT = "checks.json"; var URL_DEFAULT = "http://cryptic-spire-7925.herokuapp.com/index.html"; var assertFileExists = function(infile) { var instr = infile.toString(); if(!fs.existsSync(instr)) { console.log("%s does not exist. Exiting.", instr); process.exit(1); // http://nodejs.org/api/process.html#process_process_exit_code } return instr; }; var cheerioHtmlFile = function(htmlfile) { return cheerio.load(fs.readFileSync(htmlfile)); }; var loadChecks = function(checksfile) { return JSON.parse(fs.readFileSync(checksfile)); }; var checkHtmlFile = function(htmlfile, checksfile) { $ = cheerioHtmlFile(htmlfile); var checks = loadChecks(checksfile).sort(); var out = {}; for(var ii in checks) { var present = $(checks[ii]).length > 0; out[checks[ii]] = present; } return out; }; var checkUrl = function(url, checksfile) { rest.get(url).on('complete', function(data) { $ = cheerio.load(data); var checks = loadChecks(checksfile).sort(); var out = {}; for(var ii in checks) { var present = $(checks[ii]).length > 0; out[checks[ii]] = present; } console.log(out); }); } var clone = function(fn) { // Workaround for commander.js issue. // http://stackoverflow.com/a/6772648 return fn.bind({}); }; if(require.main == module) { program .option('-f, --file <html_file>', 'Path to index.html', clone(assertFileExists), HTMLFILE_DEFAULT) .option('-u, --url <url>', 'URL to index.html', URL_DEFAULT) .option('-c, --checks <check_file>', 'Path to checks.json', clone(assertFileExists), CHECKSFILE_DEFAULT) .parse(process.argv); var checkJson = checkHtmlFile(program.file, program.checks); var outJson = JSON.stringify(checkJson, null, 4); console.log(outJson); var checkJson2 = checkUrl(program.url, program.checks); var outJson2 = JSON.stringify(checkJson2, null, 4); console.log(outJson2); } else { exports.checkHtmlFile = checkHtmlFile; } 

根据参数调用checkHtmlFile()checkUrl()

就像是:

 if (program.url) checkUrl(program.url, program.checks); else checkHtmlFile(program.file, program.checks); 

阅读这个更多的参考: commander.js选项parsing

此外, checkJson2undefined checkUrl()没有返回任何东西。

那些指挥官的select线对我来说是错误的。

删除克隆function并修改您的选项行如下:

  .option('-f, --file <html_file>', 'Path to index.html', HTMLFILE_DEFAULT) .option('-u, --url <url>', 'URL to index.html', URL_DEFAULT) .option('-c, --checks <check_file>', 'Path to checks.json', CHECKSFILE_DEFAULT) 

这应该解决你的指挥官问题。

以下是来自@David和@ankitsabharwal的有用提示之后更新的checkUrl函数。

 var checkUrl = function(url, checksfile) { rest.get(url).on('complete', function(data) { $ = cheerio.load(data); var checks = loadChecks(checksfile).sort(); var out = {}; for(var ii in checks) { var present = $(checks[ii]).length > 0; out[checks[ii]] = present; } var outJson = JSON.stringify(out, null, 4); console.log(outJson); }); } 

下面是更新后的Commander代码:

 if(require.main == module) { program .option('-f, --file <html_file>', 'Path to index.html') .option('-u, --url <url>', 'URL to index.html') .option('-c, --checks <check_file>', 'Path to checks.json') .parse(process.argv); if (program.url) { checkUrl(program.url, program.checks); } else { checkHtmlFile (program.file, program.checks); var checkJson = checkHtmlFile(program.file, program.checks); var outJson = JSON.stringify(checkJson, null, 4); console.log(outJson); } }