2017-07-26 1 views
0

私は、最初にページを破棄して航空会社の各ページに移動して、WebサイトのURLを取得することで、航空会社のリストを取得するためにwikipediaページをスクラップしようとしています。私は2つの関数でコードを分割しました。 1つはメインページをスクラップして新しいURLを取得し、2つ目の機能は作成したURLから別のページをスクラップしてそのページからウェブサイト名を取得することです。私はhtmlを取得してcheerioを取得してデータを解析するためのrequest-promiseモジュールを使用しました。promise関数から適切なデータを受け取ることができません

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; 

    }) 

ただし、親関数に応答変数を記録すると、Stringの代わりに[オブジェクトのPromise]値が得られます。この問題を解決するにはどうすればよいですか?

+0

airline_urlはオブジェクトの約束を返しますか? – error404

+0

はいコンソールにログオンすると[オブジェクトの約束]が表示されます。 –

+0

私の推測では、 'span.url'の内容をコード内の別の場所に設定しようとしていますが、リクエストは非同期で、これは約束を返しています。 url'のテキスト、成功した約束のコールバックでそれを行い、約束の値に設定しないでください。 [MDN Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)、私が約束するように設定することで、$(.. ).text(someReq());関数someReq(){...約束を返す; } ' –

答えて

1

非同期関数は約束を返します。その場合、応答を解決するか、またはawaitを使用する必要があります。 コードの他の部分が正常であればこれはうまくいくはずです。あなたのgetAirlineUrl関数が約束を返すので

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'を追加したことです。 'getAirlineUrl(wiki_url)の前にeach(...)'と 'await' ); ' –

+0

未処理の約束拒否エラーが返されました –

+0

エラーを捕捉するために、try..catch inside async関数を使用します。 – error404

0

は、あなたが約束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}`); 
    } 
    } 
} 
関連する問題