选择器解析 html 时的 Cheerio 问题
Cheerio problems on parsing html by selectors
var request = require('request');
var cheerio = require('cheerio');
request('http://www.gatherproxy.com/proxylist/anonymity/?t=Elite', function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
var temp = $('#tblproxy tbody tr.loading-row')
console.log(temp.attr('class'))
}
});
网页位于http://www.gatherproxy.com/zh/proxylist/anonymity/?t=Elite
我想获取这个元素,它的选择器是#tblproxy > tbody > tr.loading-row
我在 google 控制台中尝试了同样的操作,
var s = $('#tblproxy > tbody > tr.loading-row')
undefined
s.attr('class')
"loading-row"
但它在 cheerio 的上下文中不起作用,程序的输出未定义,知道吗?
从页面的代码源来看,#tblproxy
中没有tbody
,所以从选择器中去掉:
var temp = $('#tblproxy tr.loading-row');
更新
根据bublik42的评论,如果随机出现tbody
,可以使用find()
:
var temp = $('#tblproxy').find('tr.loading-row');
我注意到您尝试查询的元素 tbody
是异步加载的。这超出了 request
模块的能力范围。您可以使用 phantomjs in simulating a web page in a headless manner and get the html from a web page module. If you want to create more customized web page modules you can refer to the phantomjs documentation
.
叉这个 github repo demo .
首先,创建一个网页模块来获取特定页面的html。
phantom/request.js
'use strict';
var page = require('webpage').create();
var system = require('system');
page.open(system.args[1], function(status) {
console.log(page.evaluate(function() {
return document.documentElement.innerHTML;
}));
phantom.exit();
});
其次,为 phantom
目录中的所有网页模块创建一个 phantomjs cli 包装器。
lib/phantom.js
'use strict';
var path = require('path');
var spawn = require('child_process').spawn;
var phantomjs = require('phantomjs');
var fs = require('fs');
var binPath = phantomjs.path;
var slice = Array.prototype.slice;
var phantomPath = path.join(
__dirname,
'..',
'phantom'
);
exports = module.exports = function() {
var args = slice.call(arguments);
var callback = args.pop();
var command = spawn(binPath, args);
command.stdout.on('data', function(data) {
callback(null, data.toString());
});
command.stderr.on('data', function(data) {
callback({ message: data.toString() }, null);
});
};
// create methods base on the ./phantom directory web page modules
fs.readdirSync(phantomPath).reduce(function(context, filename) {
var index = path.basename(filename, '.js');
context[index] = function() {
exports.apply(null, [path.join(phantomPath, filename)].concat(slice.call(arguments)));
};
}, exports);
最后,使用lib/phantom.js
脚本的request
方法获取html页面。
index.js
'use strict';
var phantom = require('./lib/phantom');
var cheerio = require('cheerio');
var address = 'http://www.gatherproxy.com/proxylist/anonymity/?t=Elite';
phantom.request(address, function(err, html) {
if(err) {
console.log('error');
return;
}
var $ = cheerio.load(html);
var temp = $('#tblproxy tbody tr.loading-row');
console.log(temp.attr('class'));
});
var request = require('request');
var cheerio = require('cheerio');
request('http://www.gatherproxy.com/proxylist/anonymity/?t=Elite', function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
var temp = $('#tblproxy tbody tr.loading-row')
console.log(temp.attr('class'))
}
});
网页位于http://www.gatherproxy.com/zh/proxylist/anonymity/?t=Elite
我想获取这个元素,它的选择器是#tblproxy > tbody > tr.loading-row
我在 google 控制台中尝试了同样的操作,
var s = $('#tblproxy > tbody > tr.loading-row')
undefined
s.attr('class')
"loading-row"
但它在 cheerio 的上下文中不起作用,程序的输出未定义,知道吗?
从页面的代码源来看,#tblproxy
中没有tbody
,所以从选择器中去掉:
var temp = $('#tblproxy tr.loading-row');
更新
根据bublik42的评论,如果随机出现tbody
,可以使用find()
:
var temp = $('#tblproxy').find('tr.loading-row');
我注意到您尝试查询的元素 tbody
是异步加载的。这超出了 request
模块的能力范围。您可以使用 phantomjs in simulating a web page in a headless manner and get the html from a web page module. If you want to create more customized web page modules you can refer to the phantomjs documentation
.
叉这个 github repo demo .
首先,创建一个网页模块来获取特定页面的html。
phantom/request.js
'use strict';
var page = require('webpage').create();
var system = require('system');
page.open(system.args[1], function(status) {
console.log(page.evaluate(function() {
return document.documentElement.innerHTML;
}));
phantom.exit();
});
其次,为 phantom
目录中的所有网页模块创建一个 phantomjs cli 包装器。
lib/phantom.js
'use strict';
var path = require('path');
var spawn = require('child_process').spawn;
var phantomjs = require('phantomjs');
var fs = require('fs');
var binPath = phantomjs.path;
var slice = Array.prototype.slice;
var phantomPath = path.join(
__dirname,
'..',
'phantom'
);
exports = module.exports = function() {
var args = slice.call(arguments);
var callback = args.pop();
var command = spawn(binPath, args);
command.stdout.on('data', function(data) {
callback(null, data.toString());
});
command.stderr.on('data', function(data) {
callback({ message: data.toString() }, null);
});
};
// create methods base on the ./phantom directory web page modules
fs.readdirSync(phantomPath).reduce(function(context, filename) {
var index = path.basename(filename, '.js');
context[index] = function() {
exports.apply(null, [path.join(phantomPath, filename)].concat(slice.call(arguments)));
};
}, exports);
最后,使用lib/phantom.js
脚本的request
方法获取html页面。
index.js
'use strict';
var phantom = require('./lib/phantom');
var cheerio = require('cheerio');
var address = 'http://www.gatherproxy.com/proxylist/anonymity/?t=Elite';
phantom.request(address, function(err, html) {
if(err) {
console.log('error');
return;
}
var $ = cheerio.load(html);
var temp = $('#tblproxy tbody tr.loading-row');
console.log(temp.attr('class'));
});