Do/while 在 node.js 中循环以获得总推文计数只运行一次
Do/while loop in node.js to get total tweet counts only runs once
当向 twitter api 发出获取请求时,它 return 获取数组 tweets.statuses
中的所有推文。我们可以使用 tweets.statuses.length
找到推文总数。在一个请求中,即使有 1000 条推文可用,它也只能 return 最多 100 条推文。
类似地,元数据在数组 tweets.search_metadata
中 returned,看起来像如下所示的对象。这里的计数是传递给推特的计数 api 而不是推文的计数 returned.
{ 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 为空,即当最后一批结果被 returned 时,它不存在。每当 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);
在您的场景中,首先会创建客户端,然后 "do {" 行执行,然后 "client.get(..." 行执行,然后 "while (resultsExist != null)" 执行,这是错误的。毕竟,当你从 Twitter 回复 return 时,回调函数 "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);
当向 twitter api 发出获取请求时,它 return 获取数组 tweets.statuses
中的所有推文。我们可以使用 tweets.statuses.length
找到推文总数。在一个请求中,即使有 1000 条推文可用,它也只能 return 最多 100 条推文。
类似地,元数据在数组 tweets.search_metadata
中 returned,看起来像如下所示的对象。这里的计数是传递给推特的计数 api 而不是推文的计数 returned.
{ 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 为空,即当最后一批结果被 returned 时,它不存在。每当 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);
在您的场景中,首先会创建客户端,然后 "do {" 行执行,然后 "client.get(..." 行执行,然后 "while (resultsExist != null)" 执行,这是错误的。毕竟,当你从 Twitter 回复 return 时,回调函数 "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);