# Pythonを使って古いツイートを消す
###### tags: `Blog`
誰のためにもなりませんが、自分の覚え書きとして。
## 古いツイートを消したい
10年以上ずっと同じTwitterアカウントを使っていて、そのうちやろうとは思っていました。
去年あたりにアカウント作り直す方が良かったんだろうけど、なんだかんだそのまま使い続けていたため。
## 古いツイートを消すには
手で消すのは現実的ではないので、何らかのツールを使って消していく必要があります。
しかし、全削除が可能なツールはあるものの、条件つきで削除するツールはないようです (たとえば2年以上前のツイートだけ消すとか)。
ということで、自分でツールを作る必要がありました。
具体的には、
- 古いツイート一覧を取得する
- プログラムを書いて自動で削除する
ということをやる必要があります。
## 古いツイートの取得
TwitterのWeb版からリクエストできて、暫くするとzipがダウンロードできます。
色々なファイルが入っていますが、その中のtweet.jsとtweet-part1.jsにツイートが全部入っています。
https://help.twitter.com/ja/managing-your-account/how-to-download-your-twitter-archive
## APIとPython環境
PythonでTweepyというライブラリを使うのがかんたんです。
API経由でログインした後、`API.destroy(tweet_id)`で削除できます。
ツイートのIDはtweet.jsの中に書いてあるので、それを打ち込んでいく感じです。
なお、Twitter APIを利用する場合は事前に申請が必要な場合があります。
古いアカウントは申請しないでも使える場合もあるようです(私はそうでした)。
## ソースコード
以下は実際に実行した2010年~2018年6月までを削除した時のコードです。
初歩的なプログラミングの知識があれば何やってるかはざっくり理解できると思います。
一週間ちょっとかけて対象のツイートを全部削除できました。
```python=delete_old_tweet.py
import tweepy
import pandas as pd
import re
import time
consumer_key='**************'
consumer_secret='**************'
access_token_key='**************'
access_token_secret='**************'
data_folder = './twitter_data'
def tweetjs2df(path):
with open(path) as f:
datalines = f.readlines()
regexes = [r' \"source\".*',
r' \"id_str\".*',
r' \"created_at\".*',
r' \"full_text\".*'
]
colname = ['source','id', 'created_at', 'full_text']
df = pd.DataFrame([], columns=colname)
for i, regex in enumerate(regexes):
L = []
for line in datalines:
match_obj = re.match(regex, line)
if match_obj :
L.append(match_obj.group())
df[colname[i]] = pd.Series(L)
# データ型の整形
df["created_at"] = df["created_at"].str.replace('"created_at" : ', '').str.replace('"', '').str.replace(',$', '').astype(str)
df["created_at"] = pd.to_datetime(df["created_at"])
df["id"] = df["id"].str.replace('"id_str" : ', "").str.replace('"', '').str.replace(' ', '').str.replace(',', '').astype(str)
return df
if __name__ == "__main__":
hoge = tweetjs2df(f"{data_folder}/tweet.js")
fuga = tweetjs2df(f"{data_folder}/tweet-part1.js")
df = pd.concat([hoge, fuga])
# Extract tweets to be erased
since = (df["created_at"].apply(lambda x: x.year) >= 2010)
until = (df["created_at"].apply(lambda x: x.year) <= 2018) & (df["created_at"].apply(lambda x: x.month) <= 6)
df_del = df.loc[since & until, :]
deleted_id = []
for id_ in df_del["id"]:
print("Destroying status:", id_)
try:
api.get_status(id_)
except:
print("No status for", id_)
else:
api.destroy_status(id_)
print("successed")
time.sleep(5.2)
deleted_id.append(id_)
with open("./output/deleted_id4.txt", "w") as f:
f.writelines("\n".join(deleted_id))
```
## おまけ
直近1年半のツイートだけにしたはずなんですが、7万ツイート残っていました……
そんなにツイートした記憶なんかないのに……