2017-02-20 42 views
0

我正在使用一些如下代碼的Node.js web scraper應用程序,並試圖在功能上定位我的代碼。請看下圖:傳遞一系列函數中數據的最佳方法?

const Promise = require('bluebird'); 
const fetch = require('node-fetch'); 
const cheerio = require('cheerio'); 

const scrapeUri = uri => fetch(uri); // how should i pass the uri from here 
const fetchURIs = URIs => Promise.all(URIs.map(scrapeUri)); 
const getBodies = pages => Promise.all(pages.map(page => page.text())); 
const toSource = source => cheerio.load(source); 
const shouldScrape = ($) => { 
    const shouldIndex = $('meta[name="robots"]').attr('content'); 
    if (['noindex', 'nofollow'].indexOf(shouldIndex) !== -1) { 
    return false; 
    } 
    return true; 
}; 

const objectifyContent = ($) => { // to be accessed here 
    return { 
    meta: { 
     index_timestamp: new Date(), 
     title: $('title').html(), 
     // TODO: this will totally fail in some instances, need to pass uri from initial instance 
     uri: $('link[rel="canonical"]').attr('href'), 
     description: $('meta[name="description"]').attr('content'), 
    }, 
    }; 
}; 

objectifyContent,這將是從最初的scrapeUri訪問的URI,而不是試圖通過訪問規範獲得頁面的URL的途純?我知道我可以設置一個變量並讓它沿着範圍繼承的一些方法,但我想知道在Node.js的上下文中是否有更清晰,更實用的方法來執行此操作。

主叫方將類似於: fetchUris(myUris).then(values => getBodies(values).then(sources => res.send(sources.map(toSource).filter(shouldScrape).map(objectifyContent));)

+0

爲什麼不能簡單地把它添加到'objectifyContent'的簽名?這個簽名是由某個框架決定的嗎?如果沒有,你不能只是使它成爲'($,uri)=> {...}'或'($)=>(uri)=> {...}'? (或者是相反的順序,這取決於你的口味,哪一個最有可能改變。) –

+0

我想問題是,這些函數被用在一系列'objectifyContent'在一系列'map'的末尾,而'filter's。我如何存儲每個陣列的uri以便以後在系列中使用? – LA1CH3

+0

您必須向我們展示您使用'.map()'和'.filter()'的實際代碼,以便我們在該上下文中提供最佳答案。也許你想積累的是具有多個屬性的對象數組,而不是僅僅過濾一個值。他們可以爲每個單位存儲多個信息。 – jfriend00

回答

0

修改此scrapeUri通過承諾,通過URI,並修改相應的處理程序

const scrapeUri = uri => fetch(uri).then(
    webpage => [uri, webpage] 
) 
+0

這實際上是我用過的想法,只是我使用了'Promise.props'並使用了對象而不是數組。 – LA1CH3

相關問題