2015-02-24 51 views
0

我想湊一個頁面中單擊,然後返回所有的數據作爲JSON。這個過程是,我首先打開www.domain.com,我將各種信息放到「節點」數組中,但是對於每個節點,還有一個頁面我想從節點中提取附加數據並將其存儲在節點中陣列。我需要在循環中完成此操作,或者至少能夠傳遞「x」變量,以便我知道將數據推送到數組的位置。CasperJS,複式單元刮

我剝奪這個代碼右後衛,並沒有檢查它的工作原理,但主要版本,人有我精的作品

任何幫助是極大的讚賞。謝謝

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

你必須將您的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'then*函數是異步的。

如果casper.back()不適用於您,您將需要重新加載主頁面casper.thenOpen()

+0

我不知道這將作爲get_rows()函數的工作,因爲這是一個評估的呼叫中CasperJS超出範圍內的叫什麼? – mattis2k 2015-02-24 11:04:24

+0

這就是爲什麼你必須將它分成多個步驟,並且大部分都必須在頁面上下文之外執行。 – 2015-02-24 11:07:48

+0

謝謝Artjom,我將有一個發揮,看看什麼給 – mattis2k 2015-02-24 13:25:30

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"); 
    });