我想使用CasperJS抓取一些网络数据。数据位于表格中,每行中都有一个链接,指向包含更多详细信息的页面。在脚本中有一个循环遍历所有表行。我希望Casper单击该链接,在子页面上收集数据并返回一个历史记录,以处理下一个表行。问题是click()不起作用,我不知道为什么。有没有什么办法解决这一问题 ? (注意:jref函数viewContact由href调用)
以下是代码:
var employee = {
last_name: "",
first_name: "",
position: "",
department: "",
location: "",
email: "",
phone: "",
twitter: ""
};
var employees = [];
var result_number = 50;
var start_url = 'https://www.jigsaw.com/SearchContact.xhtml?companyId=489781&orderby=0&order=0&opCode=paging&mode=0&estimatedCount=126&dead=false&rpage=1&rowsPerPage=200';
var casper = require('casper').create({
javascriptEnabled: true
});
casper.start(start_url, function() {
var js = this.evaluate(function() {
return document;
});
for (var i = 1; i <= result_number; i++)
{
// j stands for three neighbour td columns containing:
// position, name+link, location
employee.position = this.getHTML('#sortableTable tr:nth-child(' + i + ') td:nth-child(3) span');
// click link and get other data
this.click('#sortableTable tr:nth-child(' + i + ') td:nth-child(4) span a');
employee.first_name = this.getHTML('#sortableTable tr:nth-child(' + i + ') td:nth-child(4) span a');
//collect data
this.waitForSelector('#firstname', function() {
employee.first_name = this.getHTML('#firstname');
});
this.waitForSelector('#lastname', function() {
employee.last_name = this.getHTML('#lastname');
});
this.waitForSelector('#state', function() {
employee.department = this.getHTML('#state');
});
this.waitForSelector('#email', function() {
employee.email = this.getHTML('#email');
});
this.waitForSelector('#phone', function() {
employee.phone = this.getHTML('#phone');
});
//get back to previous page
this.back();
employee.location = this.getHTML('#sortableTable tr:nth-child(' + i + ') td:nth-child(5) span');
this.echo('\n\n Employee number: ' + i + " :\n");
this.echo('first name : ' + employee.first_name);
this.echo('last name : ' + employee.last_name);
this.echo('position : ' + employee.position);
this.echo('department : ' + employee.department);
this.echo('location : ' + employee.location);
this.echo('email : ' + employee.email);
this.echo('phone : ' + employee.phone);
}
});
casper.run();
答案 0 :(得分:1)
我在这里看到两件需要纠正的事情。首先,代码中的for循环似乎不在任何casperjs方法的范围内。
此:
for (var i = 1; i <= result_number; i++)
它应该在casper.then
方法内。我注意到你有结束括号,所以也许你已经通过复制方式贴出代码了。
其次,最重要的是,您要与之互动的tr:nth-child(' + i + ')
将无法以这种方式运作。我不知道为什么,但它似乎没有直接起作用。我试过做同样的事情。我的解决方案是首先将i
转换为字符串而不是像这样的数字:
pageturn = pageturn + 1;
// Collect <td> contents on each page.
var pageturnString = pageturn.toString();
var linknum = 'a.SomeLinkClass:nth-child('+pageturnString+')';
在我的情况下,我使用它来点击更改页面,无论哪种方式,您必须在第一个方法内的this.then()
方法内封装与所述css选择器的交互,然后第二个子方法执行for循环的其余部分。
示例:
casper.each(pagecount, function() {
this.then(function() {
pageturn = pageturn + 1;
// Collect <td> contents on each page.
var pageturnString = pageturn.toString();
var linknum = 'a.SomeLinkClass:nth-child('+pageturnString+')';
});
this.then(function() {
//Now run for loop here.
});
});
如果你没有在this.then()
方法中将css选择器结构封装在下一个方法中之前使用它,那么它将不起作用。我不知道为什么,但这就是交易。在我的代码中,pagecount
可能会被用来代替你的for循环,但我会把它留给你。
答案 1 :(得分:0)
我有一个页面,我在Casper中看到了这个:
[debug] [phantom] Mouse event 'mousedown' on selector: tr:nth-child(2) a
CasperError: Cannot dispatch mousedown event on nonexistent selector: tr:nth-child(2) a
由于此错误是由存在的失败引起的,它依赖于querySelectorAll,我已经玩过它并发现以下内容将x2设置为null(尽管x1不为null):
this.evaluate(function() {
var x1 = document.querySelector('tr:nth-child(2) a');
var x2 = document.querySelector('tr:nth-child(2) a');
alert(x1 + ', ' + x2);
});
它似乎取决于有一行不包含<a>
,正如您在标题行中找到的那样。这是一个测试页面:
我希望在找到原因之后回复这里,但与此同时,你最好使用selectXPath选择器。