Cheerio 直接 child 选择器
Cheerio direct child selector
大家好,女士们,首先,这是我在 Whosebug 中的第一个问题,所以不要对我太苛刻……但是 w/e:P。
我有个问题..
我对网络抓取完全陌生,目前我遇到的问题是我无法 select 正确的元素。我的代码如下所示:
var express = require('express');
var path = require('path');
var request = require('request');
var cheerio = require('cheerio');
var fs = require('fs');
var app = express();
var port = 8000;
var url = "http://www.finanzparasiten.de/html/links/awd.html";
request(url, function (err, resp, body) {
if(!err) {
var $ = cheerio.load(body)
var test = $('body table table table > tbody > tr > td > p');
console.log(test.html())
test.each(function (ii, asdf) {
var rr = $(asdf).find("table").find("tr").first().find('td:nth-child(2)').text();
console.log(asdf);
})
} else {
console.log("we encountered an error: " + err);
}
});
app.listen(port);
console.log('server is listening on ' + port);
它一直为变量 test 记录 NULL。
似乎 cheerio 对 > selector 有问题。使用 jQuery 这个 selection 将按预期工作。
感谢@logol 的解答,我可以解决第一个问题,但现在我面临的问题是我必须 select 在 body 之后引导孩子,它似乎像 tbody 一样有问题。任何人有解决方法吗?
更新:
根据@logol 的回复,我检查了 docs for Cheerio and it says its selectors are built on CSSSelect Library. Their docs have a list of selectors. Child and Parent selectors are supported and it seems to imply all element selectors are too. However, this github issue 标志 tbody 问题。
原文:
您的意思是要在您的选择器中列出重复的表格以及如何在控制台中打印出来。
试试这个:
var test = $('body table > tbody > tr > td > p');
console.log(test.innerHTML)
这个在网页上的输出是:
<span class="TDheadlinebig">AWD - Allgemeiner
Wirtschaftsdienst</span><span class="TDnormal"><br>
</span><span class="TDheadlinenormal">zweitgrößte "Strukkibude"
</span><span class="TDnormal"><br>
</span>
原文:
据我所知(当我上次使用 cheerio 时)tbody 在 cheerio 中无法识别,只需保留它并改用它:
table > tr > td
PS:thead 正在工作
更新:
它似乎有时甚至与 tbody 一起工作,在 REPL 中试试这个
const cheerio = require('cheerio');
const html = '\
<!DOCTYPE html>\
<html>\
<head>\
<title>Cheerio Test</title>\
</head>\
<body>\
<div id="#1">\
<table>\
<thead>\
<tr>\
<th>Month</th>\
<th>Savings</th>\
</tr>\
</thead>\
<tfoot>\
<tr>\
<td>Sum</td>\
<td>180</td>\
</tr>\
</tfoot>\
<tbody>\
<tr>\
<td>January</td>\
<td>100</td>\
</tr>\
<tr>\
<td>February</td>\
<td>80</td>\
</tr>\
</tbody>\
</table>\
</div>\
</body>\
</html>';
const dom = cheerio.load(html);
// not working:
let tds1 = dom('div#1 > table > tbody > tr > td').map(function () {
return dom(this).text().trim();
}).get();
// working:
let tds2 = dom('table > tbody > tr > td').map(function () {
return dom(this).text().trim();
}).get();
// not working:
let tds3 = dom('div#1 > table > tr > td').map(function () {
return dom(this).text().trim();
}).get();
console.log(tds1);
console.log(tds2);
console.log(tds3);
大家好,女士们,首先,这是我在 Whosebug 中的第一个问题,所以不要对我太苛刻……但是 w/e:P。 我有个问题.. 我对网络抓取完全陌生,目前我遇到的问题是我无法 select 正确的元素。我的代码如下所示:
var express = require('express');
var path = require('path');
var request = require('request');
var cheerio = require('cheerio');
var fs = require('fs');
var app = express();
var port = 8000;
var url = "http://www.finanzparasiten.de/html/links/awd.html";
request(url, function (err, resp, body) {
if(!err) {
var $ = cheerio.load(body)
var test = $('body table table table > tbody > tr > td > p');
console.log(test.html())
test.each(function (ii, asdf) {
var rr = $(asdf).find("table").find("tr").first().find('td:nth-child(2)').text();
console.log(asdf);
})
} else {
console.log("we encountered an error: " + err);
}
});
app.listen(port);
console.log('server is listening on ' + port);
它一直为变量 test 记录 NULL。 似乎 cheerio 对 > selector 有问题。使用 jQuery 这个 selection 将按预期工作。
感谢@logol 的解答,我可以解决第一个问题,但现在我面临的问题是我必须 select 在 body 之后引导孩子,它似乎像 tbody 一样有问题。任何人有解决方法吗?
更新:
根据@logol 的回复,我检查了 docs for Cheerio and it says its selectors are built on CSSSelect Library. Their docs have a list of selectors. Child and Parent selectors are supported and it seems to imply all element selectors are too. However, this github issue 标志 tbody 问题。
原文:
您的意思是要在您的选择器中列出重复的表格以及如何在控制台中打印出来。
试试这个:
var test = $('body table > tbody > tr > td > p');
console.log(test.innerHTML)
这个在网页上的输出是:
<span class="TDheadlinebig">AWD - Allgemeiner
Wirtschaftsdienst</span><span class="TDnormal"><br>
</span><span class="TDheadlinenormal">zweitgrößte "Strukkibude"
</span><span class="TDnormal"><br>
</span>
原文:
据我所知(当我上次使用 cheerio 时)tbody 在 cheerio 中无法识别,只需保留它并改用它:
table > tr > td
PS:thead 正在工作
更新:
它似乎有时甚至与 tbody 一起工作,在 REPL 中试试这个
const cheerio = require('cheerio');
const html = '\
<!DOCTYPE html>\
<html>\
<head>\
<title>Cheerio Test</title>\
</head>\
<body>\
<div id="#1">\
<table>\
<thead>\
<tr>\
<th>Month</th>\
<th>Savings</th>\
</tr>\
</thead>\
<tfoot>\
<tr>\
<td>Sum</td>\
<td>180</td>\
</tr>\
</tfoot>\
<tbody>\
<tr>\
<td>January</td>\
<td>100</td>\
</tr>\
<tr>\
<td>February</td>\
<td>80</td>\
</tr>\
</tbody>\
</table>\
</div>\
</body>\
</html>';
const dom = cheerio.load(html);
// not working:
let tds1 = dom('div#1 > table > tbody > tr > td').map(function () {
return dom(this).text().trim();
}).get();
// working:
let tds2 = dom('table > tbody > tr > td').map(function () {
return dom(this).text().trim();
}).get();
// not working:
let tds3 = dom('div#1 > table > tr > td').map(function () {
return dom(this).text().trim();
}).get();
console.log(tds1);
console.log(tds2);
console.log(tds3);