JavaScript、Node.jsともに初心者になります。
(Windows7のコマンドプロンプトから実行しています)
やりたいこと
「特定の30分間につぶやかれた、特定のハッシュタグを含んだツイート」をすべて一気に検索
したいと思っています。
(手動で検索した限りではおよそ800~2000ツイートほどになるので、分割やスクロールなどの手間を省きたく…)
Stream APIは今年8月に廃止されたそうなので、REST APIを使うしかないようですが… こちらは一度に200件までしか検索できないようですね。
試したこと
Node.jsでTwitter検索から100件を超えるツイートを取得したい
https://qiita.com/ryo-a/items/53fe9eadcf719b817c9a
こちらを参考にしてしてみたところ、countの値をいくらにしても100件以内しか取得できませんでした。
Twitter API Timeline解説
http://nonbiri-tereka.hatenablog.com/entry/2014/03/06/220015
とりあえず検索するたびに最後のツイートのIDを格納し、次はそのIDをmax_idにして検索すればいいということはわかったのですが…
Node.js
1const Twit = require('twit'); 2 3const T = new Twit({ 4 各種キー 5 app_only_auth: true 6}); 7let lastId = ''; 8 9let params = { 10 q: '#ハッシュタグ since:2018-11-28_00:00:00_JST until:2018-11-28_00:30:00_JST', 11 count: 3, 12 max_id: lastId, 13 result_type: 'recent', 14 include_entities: false 15} 16 17for(let i=0; i<3; i++){ 18 console.log('検索開始'); 19 params.max_id = lastId; 20 T.get('search/tweets', params, (err, data, response) => { 21 data.statuses.forEach(function(val, index, ar){ 22 console.log(index); 23 console.log('@' + val.user.screen_name); 24 console.log(val.text); 25 lastId = val.id.str; 26 }); 27 }); 28 console.log('最後のIDは' + lastId); 29}
と3ツイート×3回の検索をしようとしてみると、コンソールはまず
検索開始 最後のIDは 検索開始 最後のIDは 検索開始 最後のIDは
と、まだ代入されていない状態のものが最初に3回ぶん表示されてしまい、そのあとで検索結果(3回とも同じ結果)が出てきます。
これはNode.jsゆえの、非同期だからこそ起こることでしょうか?
それともJavaScriptの何か初歩的な間違い(スコープなど)を犯しているのでしょうか?
ここさえ解決できれば、800ツイートでも2000ツイートでも(規制のかからないかぎり)検索できるとは思うのですが…
ご教授よろしくお願いいたします。
追記
やはり非同期通信が原因とのことでしたので、初めてながらasync/awaitというやつで書き換えてみましたが
何かが足りないのか、やはり検索結果は変わりません…
Node.js
1(略) 2async function main() { 3 console.log('ループ開始'); 4 for(let i=0; i<3; i++){ 5 await search(); 6 } 7} 8 9function search() { 10 return new Promise((resolve, reject) => { 11 console.log('検索開始'); 12 params.max_id = lastId; 13 T.get('search/tweets', params, (err, data, response) => { 14 data.statuses.forEach(function(val, index, ar){ 15 console.log(index); 16 console.log('@' + val.user.screen_name); 17 console.log(val.text); 18 lastId = val.id.str; 19 }); 20 }); 21 console.log('最後のIDは' + lastId); 22 resolve(); 23 }); 24} 25 26main();
動作した版
いただいた回答を元にさらに修正したところ、無事動作しました
Node.js
1const Twit = require('twit'); 2 3const T = new Twit({ 4 consumer_key: "略", 5 consumer_secret: "略", 6 access_token_key: "略", 7 access_token_secret: "略", 8 app_only_auth: true 9}); 10 11let num = 0; 12let lastId = ''; 13 14let params = { 15 q: '#ハッシュタグ since:2018-11-28_00:00:00_JST until:2018-11-28_00:30:00_JST', 16 count: 3, 17 max_id: lastId, 18 result_type: 'recent', 19 include_entities: false 20} 21 22!(async () => { 23 for(let i=1; i<=3; i++){ 24 console.log('\n\n' + i + '回目の検索開始 ID' + lastId + '以前のツイートを検索'); 25 params.max_id = lastId; 26 const result = await T.get('search/tweets', params); 27 result.data.statuses.forEach(function(val, index, ar){ 28 num++; 29 console.log(`\n${parseInt(index) + 1}個目のツイート (累計${num}個目)`); 30 console.log('@' + val.user.screen_name); 31 console.log(val.text.replace(/\r?\n/g, '')); 32 lastId = val.id_str; 33 console.log('ツイートのIDは' + lastId); 34 }) 35 console.log('\n最後のツイートのIDは' + lastId); 36 } 37})();
このままだと再検索のたびに最初と最後のツイート内容が重複してしまうので、ほんとは再検索の際にIDを-1したいところですが
なまじIDの桁数が多いため計算に誤差が生じて面倒なので、ひとまず重複をよしとしています
なぜJavaScriptで「76287755398823936」が正しく表示できないか、あるいはなぜRubyでも表せないか。
https://7io.org/2011/07/02/21:11:55/
回答2件
あなたの回答
tips
プレビュー