全ツイート履歴から特定のツイートを抽出して API 叩いて削除するやつ
オギャー
全ツイート履歴をダウンロードする
全ツイート履歴をダウンロードします
/root/data/js/tweets/ にある .js ファイルの一行目を削除する
cpp
#define _CRT_SECURE_NO_WARNINGS #include "bits/stdc++.h" #include <filesystem> using namespace std; namespace fs = experimental::filesystem; int main() { ios::sync_with_stdio(false); cin.tie(0); string path_tweets = "/root/data/js/tweets/"; for (auto ent : fs::recursive_directory_iterator(path_tweets)) { string path_file = ent.path().string(); ifstream ifs(path_file); string header; getline(ifs, header); // skip header string data; string line; while (getline(ifs, line)) data += line + "\n"; ifs.close(); ofstream ofs(path_file); ofs << data << endl; ofs.close(); } return 0; }
Java + Jackson で特定の条件を満たすツイートを探す
import java.io.File; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public class Main { public static void main(String[] args) throws Exception { int numTweets = 0, numTweetsWithURL = 0; String path = "/root/data/js/tweets"; File dir = new File(path); File[] files = dir.listFiles(); for(File file : files) { ObjectMapper mapper = new ObjectMapper(); JsonNode node = mapper.readTree(file); for(JsonNode tweet : node) { numTweets++; String text = tweet.get("text").toString(); if(text.matches(".*https?://.*")) { // リンクを含むツイートのみカウント numTweetsWithURL++; } } } System.out.println("TweetsWithURL: " + numTweetsWithURL + "/" + numTweets); // TweetsWithURL: 1376/6963 } }
動機としては猫画像以外のツイートを全部消したいので
google spreadsheet で tweets.csv を開いたときの列数と numTweets が一致することを確認
アクセストークンとかを得る
利用目的とかを英文で書かされるのでクソ面倒くさかった
Twitter4J でよしなに削除する
import java.io.File; import java.util.ArrayList; import java.util.List; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.ConfigurationBuilder; public class Main { public static void main(String[] args) throws Exception { int numTweets = 0, numTweetsWithURL = 0; // ID collection part String path = "C:\\Users\\my316g\\Desktop\\766013394_fcd78b43f094dfa6bdac79806c379b8f0410ef552\\data\\js\\tweets"; File dir = new File(path); File[] files = dir.listFiles(); List<Long> id_strs = new ArrayList<Long>(); for(File file : files) { ObjectMapper mapper = new ObjectMapper(); JsonNode node = mapper.readTree(file); for(JsonNode tweet : node) { numTweets++; String text = tweet.get("text").toString(); String id_str = tweet.get("id_str").toString(); if(text.matches(".*https?://.*")) { // リンクを含むツイートのみカウント numTweetsWithURL++; } else { id_strs.add(Long.parseLong(id_str.substring(1, id_str.length() - 1))); // remove quote } } } System.out.println("TweetsWithURL: " + numTweetsWithURL + "/" + numTweets); // API part ConfigurationBuilder cb = new ConfigurationBuilder(); cb.setDebugEnabled(true) .setOAuthConsumerKey("*********************") .setOAuthConsumerSecret("******************************************") .setOAuthAccessToken("**************************************************") .setOAuthAccessTokenSecret("******************************************"); TwitterFactory tf = new TwitterFactory(cb.build()); Twitter twitter = tf.getInstance(); if (!twitter.getAuthorization().isEnabled()) { System.out.println("OAuth consumer key/secret is not set."); System.exit(-1); } int destroyed = 0, total = 0; for(long id_str : id_strs) { try { Status status = twitter.destroyStatus(id_str); System.out.println("successfully destroyed the status: [" + status.getText() + "]."); destroyed++; } catch (TwitterException te) { System.out.println("Failed to destroy status: " + te.getMessage()); } total++; System.out.println(destroyed + "/" + total); } } }
クリーンになったおれを令和でもよろしく