Цикл Do / while в node.js для получения общего количества твитов выполняется только один раз - PullRequest
0 голосов
/ 10 октября 2018

При отправке запроса get в твиттер-API он возвращает все твиты в массиве tweets.statuses.Мы можем найти общее количество твитов, используя tweets.statuses.length.В одном запросе он может вернуть максимум 100 твитов, даже если доступно 1000 твитов.

Аналогично, метаданные возвращаются в массиве tweets.search_metadata, который выглядит как объект, как показано ниже.Здесь count - это количество, которое передается в API Twitter, а не количество возвращенных твитов.

{ completed_in: 0.13,
  max_id: 1049894626625286100,
  max_id_str: '1049894626625286144',
  next_results: '?    max_id=1049894470475485183&q=apple&count=100&include_entities=1',
  query: 'apple',
  refresh_url: '?since_id=1049894626625286144&q=apple&include_entities=1',
  count: 100,
  since_id: 0,
  since_id_str: '0' }

В приведенных выше метаданных мы можем проверить, существует ли next_results.Если это так, это означает, что доступно больше результатов, поэтому мы можем снова и снова отправлять запрос в твиттер-интерфейс API, каждый раз передавая ему новый max_id до тех пор, пока next_results не станет нулевым, т. Е. Его не будет, когда будет возвращен последний пакет результатов.,Каждый раз, когда next_results существует, генерируется новый max_id, который можно использовать для получения следующих 100 твитов.

Чтобы решить эту проблему, я использую цикл do while, в котором блок кода, то есть запрос твиттер-API, будет выполняться по крайней мерепрежде чем проверять условие, т.е. если next_results существует.

Проблема в том, что цикл do while выполняется только один раз, хотя next_results все еще доступен и не равен нулю.Что я делаю не так!

Мой код node.js выглядит так:

require('dotenv').load();

var Twitter = require('twitter');

var client = new Twitter({
  consumer_key: process.env.TWITTER_CONSUMER_KEY,
  consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
  bearer_token: process.env.TWITTER_BEARER_TOKEN
});

var url = 'apple';
var totalCount = 0;
var resultsExist, maxid, isEqualsToLocation, andLocation;

do {
    client.get('search/tweets', {q: url, count:100, max_id: maxid})
    .then(function(tweets){
        console.log('next_results: ',tweets.search_metadata.next_results)
        console.log('totalCount: ',tweets.statuses.length)
        console.log(tweets.search_metadata)
        totalCount += tweets.statuses.length
        console.log(totalCount)
        console.log(tweets.search_metadata.next_results == null)
        if(tweets.search_metadata.next_results != null){
            resultsExist = tweets.search_metadata.next_results
            console.log('result is', resultsExist)
            isEqualsToLocation = resultsExist.indexOf('=');
            andLocation = resultsExist.indexOf('&');
            maxid = resultsExist.substring(isEqualsToLocation+1,andLocation);
            console.log(maxid)
        } else {
            resultsExist = tweets.search_metadata.next_results
        }
        console.log(resultsExist == null)
    })
}

while (resultsExist != null);

1 Ответ

0 голосов
/ 10 октября 2018

В вашем сценарии сначала будет создан клиент, затем строка "do {" execute, затем "client.get (..." line execute, затем "while (resultsExist! = Null)", то естьfalse. В конце концов, когда ваш ответ вернется из твиттера, будет выполнена функция обратного вызова "function (tweets) {". Поэтому ваш цикл do / while будет запущен только 1 раз. У меня нет ключа клиента Twitter для тестирования, но ниже код должен работать нормально

require('dotenv').load();

var Twitter = require('twitter');

var client = new Twitter({
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
bearer_token: process.env.TWITTER_BEARER_TOKEN
});

var url = 'apple';
var max_id;


async function getAllTwits(q, count, max_id){
    var totalCount = 0;
    var resultsExist, maxid, isEqualsToLocation, andLocation;
    maxid = max_id
    do {
        var tweets = await client.get('search/tweets', {q: q, count:count, max_id: maxid});

        console.log('next_results: ',tweets.search_metadata.next_results)
        console.log('totalCount: ',tweets.statuses.length)
        console.log(tweets.search_metadata)
        totalCount += tweets.statuses.length
        console.log(totalCount)
        console.log(tweets.search_metadata.next_results == null)
        if(tweets.search_metadata.next_results != null){
            resultsExist = tweets.search_metadata.next_results
            console.log('result is', resultsExist)
            isEqualsToLocation = resultsExist.indexOf('=');
            andLocation = resultsExist.indexOf('&');
            maxid = resultsExist.substring(isEqualsToLocation+1,andLocation);
            console.log(maxid)
        } else {
            resultsExist = tweets.search_metadata.next_results
        }
        console.log(resultsExist == null)
    }
    while (resultsExist != null);
}


getAllTwits(url, 100, max_id);
...