3

我想使用 CasperJS 抓取一些网络数据。数据在一个表格中,每一行都有一个链接指向一个更详细的页面。在脚本中有一个循环遍历所有表行。我希望 Casper 单击链接,在子页面上收集数据,然后返回历史记录以处理下一个表格行。问题是 click() 不起作用,我不知道为什么。有没有什么办法解决这一问题 ?(注意:javascript 函数 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();
4

2 回答 2

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+')';

在我的情况下,我使用它来单击以更改页面,无论哪种方式,您都必须将与所述 css 选择器的交互封装在this.then()第一个方法内的方法内,然后第二个子方法执行 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 循环,但我会留给你。

于 2013-10-21T21:31:19.277 回答
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 设置为空(尽管 x1 不为空):

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>正如您在标题行中找到的那样,它似乎取决于是否存在不包含 的行。这是一个测试页面:

http://jsfiddle.net/GKb2g/4/

一旦找到原因,我希望能在这里发帖,但与此同时,您最好使用 selectXPath 选择器。

于 2013-09-04T01:45:07.407 回答