我正在尝试抓取一个页面,并将所有数据作为JSON返回。这个过程是我首先打开www.domain.com,我将各种信息提取到"节点"数组,但是对于每个节点,还有另一个页面,我想从节点数组中提取附加数据并存储。我需要在循环中执行此操作,或者至少能够通过" x"变量周围所以我知道将数据推送到数组的位置。
我已经删除了这个代码,并且没有检查它是否有效,但主要版本我工作正常
非常感谢任何帮助......谢谢
var nodes = {};
var casper = require('casper').create({
pageSettings: {
loadImages: false,
},
verbose: true
});
var url = "http://www.domain.com";
function get_rows()
{
var nodes = {};
var el = document.querySelectorAll(".rows");
nodes["rows"] = {};
for(var x = 0; x < el.length; ++x)
{
// Set the arrays
nodes["rows"][x] = {};
nodes["rows"][x] = el[x].innerHTML;
// THIS DATA IS ON A SEPARATE PAGE
// el[x].click IS HOW YOU'D VISIT THAT PAGE
nodes["rows"][x]["data"] = {};
}
return nodes;
}
function get_data()
{
casper.echo("get_data");
rows = casper.evaluate(get_rows);
casper.echo(JSON.stringify(rows));
}
casper.start(url, function()
{
this.echo('Starting...' + this.getTitle());
});
casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:35.0) Gecko/20100101 Firefox/35.0');
casper.viewport(320, 480);
casper.waitFor
(
function check()
{
return this.evaluate(function()
{
return $('.content').is(':visible');
});
},
function then()
{
this.capture("/work/screen.png");
// Lets go get the data
this.echo("About to get_data()");
get_data();
},
function timeout()
{
// step to execute if check has failed
this.echo("Timeout: page did not load in time...").exit();
}
);
casper.run();
答案 0 :(得分:0)
您必须将get_rows
功能拆分为多个功能。第一个将检索.rows
个元素的数量。 casper.getElementsInfo()
为每个匹配元素提供html
属性,并且可以在页面上下文之外调用。
var nodes;
var x = require('casper').selectXPath;
casper.then(function(){
nodes = {
rows: {}
};
var elements = this.getElementsInfo(".rows");
for(var i = 0; i < elements.length; i++) {
nodes.rows[i] = {
html: elements[i].html
};
(function(i){
// TODO: click on the correct link
casper.thenClick(x("(//*[contains(@class,'rows')])["+(i+1)+"]//a"));
casper.then(function(){
nodes.rows[i].data = this.evaluate(function(){
return { stuff: "whatever" }; // scrape here
});
});
casper.back(); // assumes this works for your page
})(i);
}
}).then(function(){
this.echo(JSON.stringify(nodes.rows, undefined, 4));
});
IIFE((function(i){...})(i);
)很重要,否则只会填充最后一个i
。这是因为JavaScript具有功能级别范围和CasperJS&#39; then*
函数是异步的。
如果casper.back()
不适合您,则需要使用casper.thenOpen()
重新加载主页。
答案 1 :(得分:0)
这是我到目前为止的地方......第一个评估返回一个对象并完美地工作,但在每个“夹具”中我想要获取另一个数据页面,要点击的元素只是一个重复的类称为“.Fixture”,所以我使用nth-child()来尝试定位相关元素。代码实际上永远不会创建捕获
fixtures = casper.evaluate(get_fixtures);
casper.echo("Fixtures: "+Object.keys(fixtures).length );
casper.then(function()
{
Object.keys(fixtures).forEach(function(key)
{
casper.echo(fixtures[key]["competition"]);
(function(key)
{
casper.echo(".Fixture:nth-child("+key+")");
var pageturnString = key.toString();
var linknum = 'div.Fixture:nth-child('+pageturnString+')';
casper.thenClick(linknum);
casper.then(function()
{
casper.capture('/work/screen_click.png');
});
casper.back(); // assumes this works for your page
})(key);
});
}).then(function()
{
casper.echo("END");
});