2012-12-14 47 views
2

pjscrape非常適合刮臉,但是我很難弄清楚如何將參數傳遞給我的刮刀。如何將參數傳遞給pjscrape?

它需要配置文件的命令行參數,但我不知道我的配置功能/變量的範圍是什麼。

我很想配置每個域,其中包括基本的URL,選擇器等,並建立一個通用的刮板,可以從這個配置讀取。

我該怎麼做?

回答

4

Pjscrape將評估所有參數作爲全局範圍中的配置文件,並且您可以根據需要傳入任意數量的配置文件。因此,在一個或多個文件中配置每個域的刮刀應該很簡單。例如:

base_config.js

var myConfigs = []; 

my_site.js

myConfigs.push({ 
    title: 'My Site', 
    url: 'http://www.example.com', 
    scraper: 'div#my-site-info' 
}); 

scraper.js

myConfigs.forEach(function(config) { 
    pjs.addSuite({ 
     title: config.title, 
     url: config.url, 
     scraper: config.scraper 
    }) 
}); 

然後調用像:

~> phantomjs /path/to/pjscrape.js base_config.js my_site.js <...> scraper.js 

這裏棘手的部分是當你想使用刮刀功能,而不僅僅是選擇器。 PhantomJS在「沙箱」環境中運行鏟運機,不是可以訪問您的全局作用域變量。因此這將工作:

myConfigs.forEach(function(config) { 
    pjs.addSuite({ 
     scraper: function() { 
      // will fail - config is undefined! 
      return $(config.selector).text(); 
     } 
    }) 
}); 

這是一個簡單的例子,但你的想法。 PhantomJS現在支持將參數傳入page.evaluate,但這些內容尚未內置到Pjscrape中。基本上有兩種處理方法:

  • 總是處理不需要訪問外部作用域的函數。所以每個站點配置文件都會指定完整的刮板函數,而不僅僅是可插入的變量。

  • new Function("...")創建你的刮板,在創建字符串時傳入你的變量。這就是Pjscrape如何在引擎蓋下做到這一點,但公平的警告 - 除了最簡單的情況外,它可以很快變得醜陋。我在這裏使用的一種方法是使用Function#toString並傳入參數。這可能是這樣的:

    function makeFunc(f, args) { 
        return new Function('return (' + f.toString() + ')' + 
         '.apply(null, ' + JSON.stringify(args) + ');'); 
    } 
    
    myConfigs.forEach(function(config) { 
        pjs.addSuite({ 
         scraper: makeFunc(function(selector) { 
          // works - config.selector is passed in as the "selector" arg 
          return $(selector).text(); 
         }, [config.selector]) 
        }) 
    }); 
    
+0

感謝詳細的解答,但我希望能在刮板函數中使用「配置變量」。讓我看看我能做些什麼,然後我會把它發佈回來。 – ankimal

+0

@ankimal你會發現如何將參數作爲配置變量傳遞? 我也需要它... –

+0

@DanieleB我認爲nrabinowitz的迴應是上面的路要走。我結束了使用casperjs作爲我的刮削範圍減少。 – ankimal