Javascript 在Node.js中解析不带ID或CSS选择器的HTML表
此数据来自旧系统,输出为原样。我们无法添加CSS选择器或ID。大多数node.js在线解析示例都涉及到解析表、行、数据以及一些ID或CSS类,但到目前为止,我还没有遇到任何有助于解析以下页面的内容。这包括JSDOM(AFAIK)的示例 我想要的是将每一行提取到[fileName,link,size,dateTime]元组中,然后在元组中运行一些查询,比如组中最新的时间戳是什么,等等,然后提取文件名和链接——我正在考虑使用YQL。交替的表格行属性也让它有点挑战性。node.js的新特性,因此某些术语可能是错误的。任何帮助都将不胜感激 谢谢Javascript 在Node.js中解析不带ID或CSS选择器的HTML表,javascript,jquery,html,node.js,parsing,Javascript,Jquery,Html,Node.js,Parsing,此数据来自旧系统,输出为原样。我们无法添加CSS选择器或ID。大多数node.js在线解析示例都涉及到解析表、行、数据以及一些ID或CSS类,但到目前为止,我还没有遇到任何有助于解析以下页面的内容。这包括JSDOM(AFAIK)的示例 我想要的是将每一行提取到[fileName,link,size,dateTime]元组中,然后在元组中运行一些查询,比如组中最新的时间戳是什么,等等,然后提取文件名和链接——我正在考虑使用YQL。交替的表格行属性也让它有点挑战性。node.js的新特性,因此某些术
<html>
<body>
<table width="100%" cellspacing="0" cellpadding="5" align="center">
<tr>
<td align="left"><font size="+1"><strong>Filename</strong></font></td>
<td align="center"><font size="+1"><strong>Size</strong></font></td>
<td align="right"><font size="+1"><strong>Last Modified</strong></font></td>
</tr>
<tr>
<td align="left">
<a href="/path_to_file.csv"><tt>file1.csv</tt></a></td>
<td align="right"><tt>86.6 kb</tt></td>
<td align="right"><tt>Fri, 21 Mar 2014 21:00:19 GMT</tt></td>
</tr>
<tr bgcolor="#eeeeee">
<td align="left">
<a href="/path_to_file.csv"><tt>file2.csv</tt></a></td>
<td align="right"><tt>20.7 kb</tt></td>
<td align="right"><tt>Fri, 21 Mar 2014 21:00:19 GMT</tt></td>
</tr>
<tr>
<td align="left">
<a href="/path_to_file.xml"><tt>file1.xml</tt></a></td>
<td align="right"><tt>266.5 kb</tt></td>
<td align="right"><tt>Fri, 21 Mar 2014 21:00:19 GMT</tt></td>
</tr>
<tr bgcolor="#eeeeee">
<td align="left">
<a href="/path_to_file.xml"><tt>file2.xml</tt></a></td>
<td align="right"><tt>27.2 kb</tt></td>
<td align="right"><tt>Fri, 21 Mar 2014 21:00:19 GMT</tt></td>
</tr>
</table>
</body>
</html>
我不知道JSDom,但听起来它可以将HTML文档解析为DOM(文档对象模型)。从那里,即使没有ID,也应该可以通过节点循环并通过标记名、属性或文档中的位置识别它们 谷歌搜索5秒钟,请稍候 似乎证实了这一点。它显示类似jQuery的选择器,如
窗口。$(“a.the-link”).text()
。因此,您可以选择诸如td
、th
,甚至可能是td[align=“left”]
之类的选择器,而不是添加类。使用这样的选择器和方便的方法,如.first
和.each
,遍历多个结果(如每一行),您应该能够很好地解析文档,尽管这当然比为每种不同类型的单元格使用方便的类名要麻烦一些
我仍然不认为自己是JSDom专家,但花几分钟阅读他们项目的主页已经显示了您的问题的所有答案,还有更多问题。我建议使用over JSDom,因为它速度更快、重量更轻。这就是说,您需要对每个循环执行一次操作,获取“tr”元素,然后获取它们的“td”元素。下面是一个粗略的示例(My Node.js/Cheerio已经生锈了,但是如果您在JQuery中仔细研究,您可以找到一些不错的示例):
var rawData=new Array();
var rows=document.getElementsByTagName('tr');
对于(var cnt=1;cnt
附加方式
var cheerio=require('cheerio'),
cheerioTableparser=require('cheerio-tableparser');
res.on('数据'),函数(数据){
$=cheerio.load(data.toString());
ChereIoTableParser($);
var数据=[];
var数组=$(“表”).parsetable(false,false,false)
数组[0]。forEach(函数(d,i){
var firstColumnHTMLCell=$(“”+数组[0][i]+“”);
var fileItem=firstColumnHTMLCell.text().trim();
var linkItem=firstColumnHTMLCell.find(“a”).attr(“href”);
var lastModifiedItem=$(“”+数组[2][i]+“”)。text();
变量行={
“文件名”:fileItem,
“链接”:链接项,
“LastModified”:lastModifiedItem
};
数据推送(row);
控制台日志(行);
})
});
这非常完美-唯一的变化是我必须使用.eq(N)来获得第N个孩子。[]符号似乎不适用于cheerio。是的,在解析真实数据集时,确实比jsdom快得多。谢谢激怒了德米特!
res.on('data', function(data) {
$ = cheerio.load(data.toString());
var data = [];
$('tr').each(function(i, tr){
var children = $(this).children();
var fileItem = children.eq(0);
var linkItem = children.eq(0).children().eq(0);
var lastModifiedItem = children.eq(2);
var row = {
"Filename": fileItem.text().trim(),
"Link": linkItem.attr("href"),
"LastModified": lastModifiedItem.text().trim()
};
data.push(row);
console.log(row);
});
});
var data = [];
$('tr').each(function(i, tr){
var children = $(this).children();
var row = {
"Filename": children[0].text(),
"Size": children[1].text(),
"Last Modified": children[2].text()
};
data.push(row);
});
var rawData = new Array();
var rows = document.getElementsByTagName('tr');
for(var cnt = 1; cnt < rows.length; cnt++) {
var cells = rows[cnt].getElementsByTagName('tt');
var row = [];
for (var count = 0; count < cells.length; count++) {
row.push(cells[count].innerText.trim());
}
rawData.push(row);
}
console.log(rawData);