Cheerio 抓取只返回两行
Cheerio scraping returning only two rows
因此,在将其添加到我的 Node 应用程序之前,我在静态 HTML 文件上测试了我的抓取。
问题是它没有返回所有行。
网站上:
$('#sport tr').length
//Returns 13
在 Cheerio 中:
$('#sport tr').length
//Returns 2
我很难过,这是我正在使用的代码。我已经包含了 URL 作为证明,因此如果您愿意,可以自己访问它。
我怀疑这与 var $ = cheerio.load(html);
有关,但我没有使用 Cheerio 的经验,无法直截了当地说出问题所在。
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/scrape', function(req, res){
var url = 'http://www.olbg.com/football.php';
var json = [];
request(url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
console.log($('#sport tr').length);
var headers = [];
$('#sport tr th').each(function(i, th) {
var text = $(th).text();
if (text.trim() !== "") {
headers[i] = text.replace(/[\t\n\r\s]/mgi, '');
}
});
$('#sport tr').each(function(i, tr) {
// skip if header
if (!$(tr).is('th')) {
var temp = {};
temp["Event"] = $(tr).find('td').eq(0).text().trim();
temp["TopSelection"] = $(tr).find('td').eq(1).text().trim();
temp["BookieOdds"] = $(tr).find('td').eq(2).text().trim();
temp["OLBGRating"] = $(tr).find('td').eq(3).find('img').length;
if (temp["Event"] !== "" || temp["TopSelection"] !== ""){
json.push(temp);
}
}
});
}
// To write to the system we will use the built in 'fs' library.
// In this example we will pass 3 parameters to the writeFile function
// Parameter 1 : output.json - this is what the created filename will be called
// Parameter 2 : JSON.stringify(json, null, 4) - the data to write, here we do an extra step by calling JSON.stringify to make our JSON easier to read
// Parameter 3 : callback function - a callback function to let us know the status of our function
fs.writeFile('output.json', JSON.stringify(json), function(err){
console.log('File successfully written!');
})
// Finally, we'll just send out a message to the browser reminding you that this app does not have a UI.
res.send(json);
});
});
app.listen("8081");
console.log("Magic happens on port 8081");
exports = module.exports = app;
您没有得到预期结果的原因是该页面上的 (table) html 被损坏了。如果您查看 table#sport
的第二个 <tr>
中的第二个 <td>
,您会看到一个 "extra" </td>
。这会导致 table#sport
所在的 <td>
在某些解析器上关闭(以及 table#sport
的隐式关闭),因为这是最接近的打开 <td>
。所以这就是解析器只报告 2 <tr>
而不是 13 的原因。您期望的其他 <tr>
现在在 table#sport
.
之外
可能你最好的选择是先通过 HTML 整理 program/script(例如 this one 并启用 clean
选项)传递 html将其传递给 cheerio。之后,您的选择器应该 return 您可能期望的元素。
因此,在将其添加到我的 Node 应用程序之前,我在静态 HTML 文件上测试了我的抓取。
问题是它没有返回所有行。
网站上:
$('#sport tr').length
//Returns 13
在 Cheerio 中:
$('#sport tr').length
//Returns 2
我很难过,这是我正在使用的代码。我已经包含了 URL 作为证明,因此如果您愿意,可以自己访问它。
我怀疑这与 var $ = cheerio.load(html);
有关,但我没有使用 Cheerio 的经验,无法直截了当地说出问题所在。
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/scrape', function(req, res){
var url = 'http://www.olbg.com/football.php';
var json = [];
request(url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
console.log($('#sport tr').length);
var headers = [];
$('#sport tr th').each(function(i, th) {
var text = $(th).text();
if (text.trim() !== "") {
headers[i] = text.replace(/[\t\n\r\s]/mgi, '');
}
});
$('#sport tr').each(function(i, tr) {
// skip if header
if (!$(tr).is('th')) {
var temp = {};
temp["Event"] = $(tr).find('td').eq(0).text().trim();
temp["TopSelection"] = $(tr).find('td').eq(1).text().trim();
temp["BookieOdds"] = $(tr).find('td').eq(2).text().trim();
temp["OLBGRating"] = $(tr).find('td').eq(3).find('img').length;
if (temp["Event"] !== "" || temp["TopSelection"] !== ""){
json.push(temp);
}
}
});
}
// To write to the system we will use the built in 'fs' library.
// In this example we will pass 3 parameters to the writeFile function
// Parameter 1 : output.json - this is what the created filename will be called
// Parameter 2 : JSON.stringify(json, null, 4) - the data to write, here we do an extra step by calling JSON.stringify to make our JSON easier to read
// Parameter 3 : callback function - a callback function to let us know the status of our function
fs.writeFile('output.json', JSON.stringify(json), function(err){
console.log('File successfully written!');
})
// Finally, we'll just send out a message to the browser reminding you that this app does not have a UI.
res.send(json);
});
});
app.listen("8081");
console.log("Magic happens on port 8081");
exports = module.exports = app;
您没有得到预期结果的原因是该页面上的 (table) html 被损坏了。如果您查看 table#sport
的第二个 <tr>
中的第二个 <td>
,您会看到一个 "extra" </td>
。这会导致 table#sport
所在的 <td>
在某些解析器上关闭(以及 table#sport
的隐式关闭),因为这是最接近的打开 <td>
。所以这就是解析器只报告 2 <tr>
而不是 13 的原因。您期望的其他 <tr>
现在在 table#sport
.
可能你最好的选择是先通过 HTML 整理 program/script(例如 this one 并启用 clean
选项)传递 html将其传递给 cheerio。之后,您的选择器应该 return 您可能期望的元素。