Javascript 带承诺爬虫节点的递归循环

Javascript 带承诺爬虫节点的递归循环,javascript,node.js,loops,recursion,promise,Javascript,Node.js,Loops,Recursion,Promise,我正在尝试使用递归循环,并承诺刮一个网站。 但它失败了。。它只在第一页发出请求,在第二页程序停止给我未处理的承诺拒绝警告 我有三个JS文件: scrapeAll.js(是调用scrapeppage.js的递归循环) scrappage.js scrapcomponents.js scrapeAll.js: var indexPage = 0; scrapePage(indexPage).then((json)=>{ console.log(JSON.stringify(json,

我正在尝试使用递归循环,并承诺刮一个网站。 但它失败了。。它只在第一页发出请求,在第二页程序停止给我未处理的承诺拒绝警告

我有三个JS文件:

  • scrapeAll.js(是调用scrapeppage.js的递归循环)
  • scrappage.js
  • scrapcomponents.js
  • scrapeAll.js:

    var indexPage = 0;
    
    scrapePage(indexPage).then((json)=>{
        console.log(JSON.stringify(json, null, 4));
        if(indexPage === Number.MAX_SAFE_INTEGER){
            console.log("MAX SAFE INTEGER");
            return;
        }
        save(json);
        indexpage++;
        scrapePage(indexPage);
    }).catch((data)=>{
        console.log(data);
        if(indexPage === Number.MAX_SAFE_INTEGER){
            console.log("MAX SAFE INTEGER");
            return;
        }
        indexPage++;
        scrapePage(indexPage);
    });
    
    UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): no data found at this page
    
    scrappage.JS

    let makeRequestCounter = 0;
    
    
    function scrapePage(number) {
        return new Promise((resolve, reject) => {
    
            let url = URL + number;
    
            let options = {
                url: url,
                headers: {
                    Host: SITE,
                    Connection: "keep-alive",
                    Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
                    "Accept-Language": "it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7",
                    "Cache-Control": "max-age=0",
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36",
                    "Cookie": restoreCookieToString()
                }
            };
    
            makeRequest(options).then((jsonData) => {
                resolve(jsonData);
            }).catch((error) => {
                    //REQUEST_LIMIT_EXCEEDED
                    if (error === CONSTANTS.REQUEST_LIMIT_EXCEEDED) {
                        reject(CONSTANTS.REQUEST_LIMIT_EXCEEDED);
                    }
    
                    //ALREADY_EXIST
                    else if (error === CONSTANTS.ALREADY_EXIST) {
                        reject(CONSTANTS.ALREADY_EXIST);
                    }
    
                    else if (error === 404) {
                        reject("no data found at this page");
                    }
    
                    //error can beeconnrefused or econnreset
                    else if (error.code !== undefined) {
    
                        //econnrefused
                        if (error.code === CONSTANTS.ECONNREFUSED) {
                            reject("WRONG_URL", url);
                        }
    
                        //econnreset
                        else if (error.code === CONSTANTS.ECONNRESET) {
                            console.log("\neconnreset error\n");
                            makeRequest(options);
                        }
    
                    }
                }
            );
        });
    }
    
    function makeRequest(options) {
        return new Promise((resolve, reject) => {
    
            let json = {
                category: [],
                imgs: [],
                title: "",
                description: "",
                url: ""
            };
    
    
            if (makeRequestCounter === CONSTANTS.REQUEST_LIMIT) {
                reject(CONSTANTS.REQUEST_LIMIT_EXCEEDED);
            }
    
            makeRequestCounter++;
    
            console.log("request to: ", options.url);
    
    
            request(options, function (error, response, html) {
                if (error) {
                    //error: possible econnreset econnrefused
                    reject(error);
    
                } else {
    
                    if (response.statusCode === 200) {
                        cookieSave(response.headers);
    
    
                        //---------- check if in db the url is already saved -------------//
    
                        check(response.request.uri.href, (err) => {
                            if (!err) {
                                reject(CONSTANTS.ALREADY_EXIST);
                            }
                        });
    
                        //----------finish checking, is new -------------------//
    
    
                        //GETTING TITLE
    
                        title(html, json_recipe).then((json) => {
    
                                //GETTING category
    
                                category(html, json).then((json) => {
    
                                        //GETTING images
    
                                        imgs(html, json).then((json) => {
    
    
                                            description(html, json).then((json) => {
    
    
                                                        json.url = response.request.uri.href;
    
                                                        resolve(json);
    
                                                //description error
                                            }).catch((error) => {
                                                console.log(error);
                                            });
    
                                            //images error
                                        }).catch((error) => {
                                            console.log(error);
                                        });
    
                                    //category error
                                }).catch((error) => {
                                    console.log(error);
                                });
                                //title error
                            }
                        ).catch((error) => {
                            console.log(error);
                        });
                    }
    
                    //no data in this page
                    if (response.statusCode === 404) {
                        reject(response.statusCode);
                    }
                }
    
            });
        });
    }
    
    scrapeComponents.js

    ...
    
    function description(html, json) {
    return new Promise((resolve, reject) => {
    
        const $ = cheerio.load(html);
    
        let description = $('.submitter__description').text().trim();
    
        json.description = JSON.parse(description);
    
        resolve(json);
    
    });
    
    }
    ...
    
    错误:

    var indexPage = 0;
    
    scrapePage(indexPage).then((json)=>{
        console.log(JSON.stringify(json, null, 4));
        if(indexPage === Number.MAX_SAFE_INTEGER){
            console.log("MAX SAFE INTEGER");
            return;
        }
        save(json);
        indexpage++;
        scrapePage(indexPage);
    }).catch((data)=>{
        console.log(data);
        if(indexPage === Number.MAX_SAFE_INTEGER){
            console.log("MAX SAFE INTEGER");
            return;
        }
        indexPage++;
        scrapePage(indexPage);
    });
    
    UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): no data found at this page
    
    程序发出第一个请求,并在scrapeAll.js正确返回scrapealpage(indexPage=1)。 第二次我的程序执行与第一次完全相同的操作,但何时返回到scrapeAll.js(拒绝(“此页未找到数据”);在scrappage.js中),程序以错误结束。 这两个页面都没有数据,但程序也失败,好的页面只保存第一个。 我认为我在承诺方面犯了一个很大的错误。
    非常感谢各位。

    问题是,您对
    scrapeAll.js
    中的
    scrappage(indexPage)
    的一个或多个调用失败。您不能像对其他代码那样递归调用promise,因此在其他调用中还需要一个
    .then
    .catch
    。向其他调用添加一个
    .catch
    ,将使您能够看到故障的真正来源

    scrapePage(indexPage)
      .then((json)=>{
        console.log(JSON.stringify(json, null, 4));
        if(indexPage === Number.MAX_SAFE_INTEGER){
          console.log("MAX SAFE INTEGER");
          return;
        }
        save(json);
        indexpage++;
        scrapePage(indexPage).catch(e => console.log(e));
      })
      .catch((data)=>{
        console.log(data);
        if(indexPage === Number.MAX_SAFE_INTEGER){
          console.log("MAX SAFE INTEGER");
          return;
        }
        indexPage++;
        scrapePage(indexPage).catch(e => console.log(e));
    });
    

    问题是对
    scrapeAll.js
    中的
    scrappage(indexPage)
    的一个或多个调用失败。您不能像对其他代码那样递归调用promise,因此在其他调用中还需要一个
    .then
    .catch
    。向其他调用添加一个
    .catch
    ,将使您能够看到故障的真正来源

    scrapePage(indexPage)
      .then((json)=>{
        console.log(JSON.stringify(json, null, 4));
        if(indexPage === Number.MAX_SAFE_INTEGER){
          console.log("MAX SAFE INTEGER");
          return;
        }
        save(json);
        indexpage++;
        scrapePage(indexPage).catch(e => console.log(e));
      })
      .catch((data)=>{
        console.log(data);
        if(indexPage === Number.MAX_SAFE_INTEGER){
          console.log("MAX SAFE INTEGER");
          return;
        }
        indexPage++;
        scrapePage(indexPage).catch(e => console.log(e));
    });
    

    您对报废函数的调用只运行一次,而不是迭代调用它。您可能必须在迭代中使用函数调用它。更新您的scrapeAll.js:

        function callScrapPage() {
        var indexPage = 0;
        while (indexPage < Number.MAX_SAFE_INTEGER) {
            scrapePage(indexPage).then((json) => {
                console.log(JSON.stringify(json, null, 4));
                save(json);
                indexpage++;
             }
           }
       }
    
    函数调用报废(){
    var indexPage=0;
    while(indexPage{
    log(JSON.stringify(JSON,null,4));
    save(json);
    indexpage++;
    }
    }
    }
    
    您对报废函数的调用只运行了一次,并且您没有迭代调用它。您可能需要使用函数在迭代中调用它。更新您的scrapeAll.js:

        function callScrapPage() {
        var indexPage = 0;
        while (indexPage < Number.MAX_SAFE_INTEGER) {
            scrapePage(indexPage).then((json) => {
                console.log(JSON.stringify(json, null, 4));
                save(json);
                indexpage++;
             }
           }
       }
    
    函数调用报废(){
    var indexPage=0;
    while(indexPage{
    log(JSON.stringify(JSON,null,4));
    save(json);
    indexpage++;
    }
    }
    }
    
    我在这里看不到递归。
    scrappage().then(scrappage).catch(scrappage)
    不是递归,也不是
    makeRequest().then(…).catch(makeRequest)
    。代码将从大量修复和改进中受益。我在这里看不到递归。
    scrappage().then(scrappage).catch(scrappage)
    不是递归,也不是
    makeRequest()。然后(…).catch(makeRequest)
    。代码将从大量修复和改进中受益。