0

向 twitter api 发出 get 请求时,它会返回数组中的所有推文tweets.statuses。我们可以使用 找到总推文计数tweets.statuses.length。在一个请求中,即使有 1000 条可用推文,它也最多只能返回 100 条推文。

类似地,元数据在数组tweets.search_metadata中返回,如下所示。这里的 count 是传递给 twitter api 的计数,而不是返回的推文计数。

{ 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存在。如果是这样,这意味着有更多可用的结果,所以我们可以一次又一次地向 twitter api 发出请求,每次都向它传递一个新的 max_id,直到 next_results 为空,即返回最后一批结果时它不存在. 每次 next_results 存在时,都会生成一个新的 max_id,可用于获取接下来的 100 条推文。

为了解决这个问题,我使用了一个 do while 循环,其中代码块(即 twitter 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);

4

1 回答 1

2

在您的场景中,首先将创建客户端,然后“do {”行执行,然后“client.get(...”行执行,然后“while (resultsExist != null)”执行,这是错误的。之后所有,当您的响应从 twitter 返回时,将执行回调函数“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);
于 2018-10-10T10:03:06.883 回答