Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/437.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 节点-发出axios请求,直到条件为真_Javascript_Node.js_Axios_Instagram - Fatal编程技术网

Javascript 节点-发出axios请求,直到条件为真

Javascript 节点-发出axios请求,直到条件为真,javascript,node.js,axios,instagram,Javascript,Node.js,Axios,Instagram,我试图使用一个变量在while循环中调用一个方法。我的目标是获取所有图像,直到具有下一页变量为真。此参数在来自联机api的每个请求之后返回。不幸的是,代码没有按预期工作 类刮刀{ 构造函数(){} 问题(下){ rl.setPrompt(输入文本); rl.prompt(); 返回新承诺((解决、拒绝)=>{ 让我们回答; rl.on('行',(输入)=>{ 答案=输入; rl.close(); }); rl.on('关闭',()=>{ 决心(回答); }); }) } startFetch(用

我试图使用一个变量在
while
循环中调用一个方法。我的目标是获取所有图像,直到
具有下一页
变量为真。此参数在来自联机api的每个请求之后返回。不幸的是,代码没有按预期工作

类刮刀{
构造函数(){}
问题(下){
rl.setPrompt(输入文本);
rl.prompt();
返回新承诺((解决、拒绝)=>{
让我们回答;
rl.on('行',(输入)=>{
答案=输入;
rl.close();
});
rl.on('关闭',()=>{
决心(回答);
});
})
}
startFetch(用户名){
this.username=字符串(用户名);
返回新承诺((解决、拒绝)=>{
axios({
网址:`https://www.instagram.com/${this.usernamee}/?\uu a=1`
})。然后((响应)=>{
//response.data.graphql.user);
userId=response.data.graphql.user.id;
//totalMedia=response.data.graphql.user.edge\u owner\u to\u timeline\u media.count
if(response.data.graphql.user.edge\u owner\u to\u timeline\u media.page\u info.has\u next\u page){
currCursor=response.data.graphql.user.edge\u owner\u to\u timeline\u media.page\u info.end\u cursor;
}
has_next_page=response.data.graphql.user.edge_owner_to_timeline_media.page_info.has_next_page;
//让节点=response.data.graphql.user.edge\u owner\u to\u timeline\u media.edges.length;
response.data.graphql.user.edge\u owner\u to\u timeline\u media.edges.map((项目,索引)=>{
this.processLink(item.node.display\uURL,索引);
});
解决();
});
});
}
fetchNextPage(用户ID){
axios({
方法:“GET”,
baseURL:'https://www.instagram.com/graphql/query/',
参数:{
查询_散列:“42323D648861228307BE10013AD2DC44”,
变量:{
id:userId,
第一:“12”,
之后:currCursor
} 
}
})。然后((响应)=>{
console.log(response.data.data.user.edge\u owner\u to\u timeline\u media.edges[0]。节点)
//totalMedia=response.data.data.user.edge\u owner\u to\u timeline\u media.count
if(response.data.data.user.edge\u owner\u to\u timeline\u media.page\u info.has\u next\u page){
currCursor=response.data.graphql.user.edge\u owner\u to\u timeline\u media.page\u info.end\u cursor;
}
});
}
processLink(imageURI,n){
让filename=path.format({dir:destinationPath,base:`${n}.jpg`});
让file=fs.createWriteStream(文件名);
https.get(imageURI,(res)=>{
res.pipe(文件);
});
}
}
const ig=新刮刀();
//参考网址:https://www.instagram.com/profile/?__a=1
//我觉得下一个代码部分有点混乱?
ig.question('Username:')。然后((profileURI)=>{
//从ig api获取第一个光标,如果has_next_page为true,则获取next page
ig.startFetch(profileURI)。然后(()=>{
//而会导致内存错误吗?
while(有下一页){
ig.fetchNextPage(userId);
}
});
});
我在node cli脚本中创建了一个简单的类。如何正确调用
fetchNextPage()
直到定义的变量为true?我有一个内存错误

<--- Last few GCs --->

[38139:0x105002a00]    66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 


<--- Last few GCs --->

[38139:0x105002a00]    66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 


<--- Last few GCs --->

[38139:0x105002a00]    66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 


<--- JS stacktrace --->


<--- Last few GCs --->

[38139:0x105002a00]    66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 
[38139:0x105002a00]    66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms  (average mu = 0.711, current mu = 0.384) allocation failure 


<--- JS stacktrace --->


<--- JS stacktrace --->

FATAL ERROR: MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory

<--- JS stacktrace --->

FATAL ERROR: MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory
Segmentation fault: 11
这是经过修改的代码


#!/usr/bin/env node

const axios = require('axios');
const path = require('path');
const https = require('https');
const fs = require('fs');
const rl = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
});

const destinationPath = path.format({dir: __dirname, base: 'scraped-profiles'});
let collectedLinks = [];

class Scraper {

    constructor() {}

    question(inputText) {
        rl.setPrompt(inputText);
        rl.prompt();
        return new Promise( (resolve, reject) => {
            let answer;
            rl.on('line', (input) => {
                answer = input;
                rl.close();
            });
            rl.on('close', () => {
                resolve(answer);
            });
        })
    }

    startFetch(username) {
        this.username = String(username); 
        return axios({
                url: `https://www.instagram.com/${this.username}/?__a=1`
            }).then( (response) => {
                console.log(response.data.graphql);

                this.user_id = response.data.graphql.user.id;
                this.has_next_page = response.data.graphql.user.edge_owner_to_timeline_media.page_info.has_next_page;
                response.data.graphql.user.edge_owner_to_timeline_media.edges.map( (item) => {
                    collectedLinks.push(item.node.display_url);
                });
                if( this.has_next_page ){
                    this.currCursor = response.data.graphql.user.edge_owner_to_timeline_media.page_info.end_cursor;
                    this.fetchNextPage();
                } else {
                    console.log('Completed');
                }
            });
        
    }

    fetchNextPage() {
        return axios({
            method: 'GET',
            baseURL: 'https://www.instagram.com/graphql/query/',
            params: {
              query_hash: '42323d64886122307be10013ad2dcc44',
              variables: { 
                id: this.user_id, 
                first: "12",  
                after: this.currCursor
              } 
            }
        }).then( (response) => {
            console.log(response.data.data)

            if( typeof response.data.data !== 'undefined' ){
                if( response.data.data.user.edge_owner_to_timeline_media.page_info.has_next_page ){
                    this.currCursor = response.data.data.user.edge_owner_to_timeline_media.page_info.end_cursor;
                
                    response.data.data.user.edge_owner_to_timeline_media.edges.map( (item) => {
                        collectedLinks.push(item.node.display_url);
                    });
                    return this.fetchNextPage();
                }
            }
        });
    }

    processLink() {
        collectedLinks.forEach( (link, i) => {
            let filename = path.format({dir: destinationPath, base: `${i}.jpg`});
            let file = fs.createWriteStream(filename);
            https.get(link, (res) => {
                res.pipe(file);
            });
        });
    }
}

const ig = new Scraper();

// https://www.instagram.com/username/?__a=1

ig.question('Username: ').then( (answer) => {
    return ig.startFetch(answer).then( () => {
        return ig.fetchNextPage();
    });
}).then( () => {
    ig.processLink();
    console.log('All done');
});

问题在于axios请求是异步的,
while
循环在发出请求时不会暂停。因此,您几乎有一个无限循环,并且可能会发出数百个请求

更好的方法是从
axios中递归调用
fetchNextPage()
,然后
直到满足
具有下一页的条件。我想你有一个问题,想让它不是真的,但这是一个假设

为了简洁起见,使用了一些伪代码:

fetchNextPage(userId) {
      // return the axios promise so it can create promise chain
      return  axios({
            ....
          }).then( (response) => {
              // store current data from this response

              // decide what to do next
              if(!nextPageConditionMet){
                  // return another axios promise for another page to current `then()`
                  return this.fetchNextPage(userId)
              }else{
                 // finally return all the pages
                 return storedPageCollection
              }                
          });
    }


ig.question('Username: ').then((profileURI) => {
  // keep returning promises to each `then()
  return ig.startFetch(profileURI).then(() => {
    //Remove while loop

    // return promise that won't be resolved until the next page 
    // condition is met in recursive calls made inside the function 
    return ig.fetchNextPage(userId);

  });
}).then((pageCollection) => {
        // do something with  the final pageCollection
        // that was returned in final `then()` of `fetchNextPage()`
        console.log('All done!')
 }).catch(err => console.log('Ooops something failed in the chain', err))

的has_nex_页面
由ig api提供,因此这是条件。它将是真的或假的,直到它是真的,我需要获取网页的内容。如果这是使用
设置的!“下一页”中的条件是否只有在为false时才会调用?
!false
为true。我不明白,对不起。如果api在传递到
If(!has\u next\u page)
时返回
has\u next\u page:true
,它将求值为
If(!true)
这意味着不正确。是否执行后续块?忘记
和反转执行块,如果它让您感到困惑,我将使用一个简单的
if(has\u next\u page)
,因此只有在
has\u next\u page的值为true时才会调用获取其他页面的方法
fetchNextPage(userId) {
      // return the axios promise so it can create promise chain
      return  axios({
            ....
          }).then( (response) => {
              // store current data from this response

              // decide what to do next
              if(!nextPageConditionMet){
                  // return another axios promise for another page to current `then()`
                  return this.fetchNextPage(userId)
              }else{
                 // finally return all the pages
                 return storedPageCollection
              }                
          });
    }


ig.question('Username: ').then((profileURI) => {
  // keep returning promises to each `then()
  return ig.startFetch(profileURI).then(() => {
    //Remove while loop

    // return promise that won't be resolved until the next page 
    // condition is met in recursive calls made inside the function 
    return ig.fetchNextPage(userId);

  });
}).then((pageCollection) => {
        // do something with  the final pageCollection
        // that was returned in final `then()` of `fetchNextPage()`
        console.log('All done!')
 }).catch(err => console.log('Ooops something failed in the chain', err))