2017-07-26 71 views
0

我想要取消維基百科頁面以獲取航空公司列表,首先要先刪除第一頁,然後再轉到航空公司的每個單獨頁面以獲取網站網址。我已經將這些代碼分爲兩個功能。一個用於取消主頁面並獲取一個新的URL,另一個用於從創建的URL中取消另一個頁面以從該頁面獲取網站名稱。我已經使用請求承諾模塊獲取html,然後cheerio解析數據。無法接收來自承諾函數的正確數據

export async function getAirlinesWebsites(req,res) { 

let response = await request(options_mainpage); 
console.log(`Data`); 

let $ = cheerio.load(response); 
console.log('Response got'); 

$('tr').each((i,e)=>{ 
    let children = ''; 
    console.log('inside function ', i); 
     if($(e).children('td').children('a').attr('class') !== 'new') { 
      children = $(e).children('td').children('a').attr('href'); 


      let wiki_url = 'https://en.wikipedia.org' + children; 
      console.log(`wiki_url = ${wiki_url}`); 

      let airline_url = getAirlineUrl(wiki_url); 
      console.log(`airline_url = ${airline_url}`); 
     } 
}) 

然後,getAirlineUrl()函數將根據提供的url解析另一個頁面。

async function getAirlineUrl(url){ 

    const wiki_child_options = { 
     url : url, 
     headers : headers 
    } 


    let child_response = await request(wiki_child_options); 
     let $ = cheerio.load(child_response); 

     let answer = $('.infobox.vcard').children('tbody').children('tr').children('td').children('span.url').text(); 

     return answer; 

    }) 

然而,當我控制檯登錄父函數的變量答案,我得到一個[對象無極]值,而不是字符串。我該如何解決這個問題?

+0

airline_url返回對象承諾? – error404

+0

是的,它在控制檯登錄時給出[object Promise]。 –

+0

我的猜測是你想設置與代碼中其他地方的請求'span.url'的內容,但請求是異步的,這個人是返回一個承諾,所以無論你設置了'跨度。 url的文本,在成功的承諾回調中執行,不要將其設置爲promise的值。 [MDN無極(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise),擴大對我所說的設置,它看起來像'$(承諾的意思.. )的.text(someReq());函數someReq(){... return promise; }' –

回答

1

異步函數返回promise。在這種情況下,您需要使用then來獲取已解析的響應或使用await。 這應該工作,如果其他部分的代碼是好的。

export async function getAirlinesWebsites(req, res) { 
    let response = await request(options_mainpage); 
    console.log(`Data`); 

    let $ = cheerio.load(response); 
    console.log("Response got"); 

    $("tr").each(async (i, e) => { 
    let children = ""; 
    console.log("inside function ", i); 
    if ($(e).children("td").children("a").attr("class") !== "new") { 
    children = $(e).children("td").children("a").attr("href"); 

    let wiki_url = "https://en.wikipedia.org" + children; 
    console.log(`wiki_url = ${wiki_url}`); 

    let airline_url = await getAirlineUrl(wiki_url); 
    console.log(`airline_url = ${airline_url}`); 
    } 
}); 
} 
+1

對於任何人誰也說不清,斑點區別是'$(「TR」)內,除了async'箭頭功能'。每個(...)'和'await'在getAirlineUrl的'前面(wiki_url );' –

+0

它現在返回未處理的承諾拒絕錯誤 –

+0

使用try..catch內部的異步函數來捕獲錯誤。 – error404

0

由於您getAirlineUrl函數返回一個承諾,你需要await這一承諾。您不能將await嵌套在.each回調中,因爲回調不是異步函數,並且如果是這樣,它將無法繼續工作。最好的解決方法是避免使用.each,只使用一個循環。

export async function getAirlinesWebsites(req,res) { 

    let response = await request(options_mainpage); 
    console.log(`Data`); 

    let $ = cheerio.load(response); 
    console.log('Response got'); 

    for (const [i, e] of Array.from($('tr')).entries()) { 
    let children = ''; 
    console.log('inside function ', i); 
    if($(e).children('td').children('a').attr('class') !== 'new') { 
     children = $(e).children('td').children('a').attr('href'); 


     let wiki_url = 'https://en.wikipedia.org' + children; 
     console.log(`wiki_url = ${wiki_url}`); 

     let airline_url = await getAirlineUrl(wiki_url); 
     console.log(`airline_url = ${airline_url}`); 
    } 
    } 
} 
相關問題