2013-02-05 19 views
0

我正在嘗試使用RequestCheerio來構建一個簡單的webscraper。推送到節點請求內的數組()

現在的目標是抓取目標頁面(在這種情況下爲http://bukk.it),從頁面上的目標選擇器中抓取文本,並將其推送到可用於其他函數的數組。

據我所知,request()異步執行,但不知道如何在函數外部可見的刮除數據。

example.js

// dependencies 
var request = require('request') 
, cheerio = require('cheerio'); 

// variables 
var url = 'http://bukk.it/'; // url to scrape 
var bukkits = []; // hold our scraped data 

request(url, function(err, resp, body){ 

    if (err) { 
    return 
    } 

    $ = cheerio.load(body); 
    // for each of our targets (within the request body)... 
    $('td a').each(function(){ 
    content = $(this).text(); 
    // I would love to populate the bukkits array for use later... 
    bukkits.push(content); 
    }) 
    console.log(bukkits.length); // everything is working inside request 
}); 

console.log(bukkits.length); // nothing, because request is asynchronous? 

// that's cool but... how do I actually get the data from the request into bukkits[] ? 

回答

2

實質上,您的整個程序現在必須在回調中進行。該回調之後沒有任何代碼可以訪問異步檢索並傳遞給回調的數據。

這並不像聽起來那麼糟糕。您可以使用命名函數,如下所示:

request(url, onRequestDone); 

function onRequestDone(err, resp, body) { 
    var bukkits = []; // not global, make it local 

    // as above 

    doMoreWork(bukkits); 
} 

function doMoreWork(bukkits) { 
    // stuff after the parsing goes here. 
} 
+0

啊,我很害怕:)我的意圖是將此代碼作爲基於快件的應用程序的一部分;我不知道如何包裹我的頭。 –

+0

一般來說,基於表達式的應用程序的大部分工作都是在路由處理程序內部進行的,這些處理程序從我所記得的所有異步處理完成時調用的「下一個」函數開始。在所有工作完成之前,簡單地不要調用'next'。 – Domenic

1

請求完成之前,您的代碼結束。

使用永久版的代理

request = require('request').forever; 

的使用的setTimeout讓您的程序運行。

setTimeout(function(){}, 1000000); 

要稍後使用這些值,它還需要在請求調用完成後完成。