2016-07-09 54 views
0

我想用一個restful api報廢多站點,我用express來實現它。 但我只引發噩夢成功地第一次與我的API, 當我再次打電話我的API,我不能引發惡夢更多:(使用restful api來調用噩夢刮多站點的承諾包裝

有什麼想法?

另外一個問題,在下面的情況下,我需要單獨實例化新夢魘的對象,這樣我就廢三個不同的網站,有什麼更聰明的方式實現這一

波紋管getScrap是我與快遞Router GET回調apiControler功能, 你也可以在主旨檢查? https://gist.github.com/sevenLee/7091f8c56ccad3c0551b512f725af7da

import Nightmare from 'nightmare'; 
import cheerio from 'cheerio'; 

let nightmare = Nightmare({show: false}); 
let nightmare2 = Nightmare({show: false}); 
let nightmare3 = Nightmare({show: false}); 

const urlObject = { 
    site1: 'http://www.site1.com', 
    site2: 'http://www.site2.com', 
    site3: 'http://www.site3.com' 
}; 

export function getScrap(req, res){ 
    let result = {}; 

    result.site1 = { 
    topList: [] 
    }; 
    result.site2 = { 
    topList: [] 
    }; 
    result.site3 = { 
    topList: [] 
    }; 

    const pro1 = Promise.resolve(
    nightmare 
     .goto(urlObject.site1) 
     .wait(200) 
     .evaluate(() => { 
     console.log('site1 into evaluate'); 
     return document.querySelector('.ninenine').innerHTML; 
     }) 
     .end() 
) 
    .then((html) => { 
    let $ = cheerio.load(html); 
    let tt = $('.horizontal-li'); 
    let sections = $(".section-board-title"); 

    sections.each((index, elm) => { 
     if($(elm).text() === 'TopList'){ 
     $(elm).next('ul').find('li').each((index, elm_li) => { 
      let title =$(elm_li).find('.cabinet-instruction').text(); 
      let price =$(elm_li).find('.cabinet-middle .price').text(); 
      let imgSrc = $(elm_li).find('.cabinet-img').attr('data-temp-src'); 
      if(title !== '' && price !==''){ 
      result.site1.topList.push({ 
       title, 
       price, 
       imgSrc 
      }); 
      } 
     }); 
     } 
    }); 
    }) 
    .catch((err) => { 
    console.log('site1 scrap err:', err); 
    return res.status(400).send({reason:'site1 scrap err'}); 
    }); 

    const pro2 = Promise.resolve(
    nightmare2 
     .goto(urlObject.site2) 
     .wait(200) 
     .evaluate(() => { 
     return document.querySelector('.ninenine').innerHTML; 
     }) 
     .end() 
) 
    .then((html) => { 
    let $ = cheerio.load(html); 
    let tt = $('.horizontal-li'); 
    let sections = $(".section-board-title"); 

    sections.each((index, elm) => { 
     if($(elm).text() === 'TopList'){ 
     $(elm).next('ul').find('li').each((index, elm_li) => { 
      let title =$(elm_li).find('.cabinet-instruction').text(); 
      let price =$(elm_li).find('.cabinet-middle .price').text(); 
      let imgSrc = $(elm_li).find('.cabinet-img').attr('data-temp-src'); 
      if(title !== '' && price !==''){ 
      result.site2.topList.push({ 
       title, 
       price, 
       imgSrc 
      }); 
      } 
     }); 
     } 
    }); 
    }) 
    .catch((err) => { 
    console.log('site2 scrap err:', err); 
    return res.status(400).send({reason:'site2 scrap err'}); 
    }); 

    const pro3 = Promise.resolve(
    nightmare3 
     .goto(urlObject.site3) 
     .wait(200) 
     .evaluate(() => { 
     return document.querySelector('#layout').innerHTML; 
     }) 
     .end() 
) 
    .then((html) => { 
    let $ = cheerio.load(html); 
    let sections = $(".pditem"); 

    sections.each((index, elm) => { 

     let title = $(elm).find('.name').text(); 
     let price = $(elm).find('.price').find('span').eq(1).text(); 
     let imgSrc = ['www.site3.com',$(elm).find('li').eq(1).find('img').attr('src')].join(''); 

     result.site3.topList.push({ 
     title, 
     price, 
     imgSrc 
     }); 
    }); 
    }) 
    .catch((err) => { 
    console.log('site3 scrap err:', err); 
    return res.status(400).send({reason:'site3 scrap err'}); 
    }); 


    Promise.all([pro1, pro2, pro3]) 
    .then(values => { 
    res.json(result); 
    }) 
    .catch((err) => { 
    return res.status(500).send({reason:err.toString()}); 
    }); 
} 

回答

0

(從我在segmentio/nightmare#715原來的答覆。)

但我只在第一次引發噩夢成功地與我的API, 當我再次打電話我的API我不能觸發任何噩夢更

它看起來像你定義你的實例getScrap()外面,然後調用.end()getScrap()內,這將結束,destr噩夢/電子實例。一旦他們結束,他們不能再使用。嘗試在getScrap()方法內移動創建您的夢魘實例。

另一個問題,在下面的情況下,我需要單獨實例化新的Nightmare對象,這樣我可以取消三個不同的站點,有沒有更聰明的方法來實現這個目標?

取決於你的用例是什麼。您可以使用單個夢魘實例並遍歷URL,但是這需要更多時間,因爲夢魘執行必須是纔是連續的。如果你對如何做這樣的事情感到好奇,this article from nightmare-examples可能值得一讀。

最後,可能值得指出的是,基於上述代碼,您不必使用cheerio。我想,你可以使用.evaluate()和CSS查詢來完成你想要的任務。

+0

謝謝,它現在可以工作! :) –

+0

我也會檢查惡夢樣例文章。漂亮的教程! –