Pythonで黒歴史クリーナーを作ってみた。
16509 ワード
Twitterやってる人なら一度は耳にした事があるであろう「黒歴史クリーナー」
僕も黒歴史ツイートとか消し去りたいので作ってみました。
向き合わなきゃいけないのは分かってても、
消したい過去もある。
手順
プログラム実行する前にやる事があるので、まずは準備から。
前提として、Python3
の実行環境が整っているものとします。
それ以外に、やらなきゃいけないのは以下です。
- 各種キー情報の取得(参考記事)
Consumer Key (API Key)
Consumer Secret (API Secret)
Access Token
Access Token Secret
- データ取得(参考記事)
- 過去全てのツイートデータ
- Pythonの外部ライブラリ取得
pip install pandas
pip install requests
pip install requests-oauthlib
実際のコード
deleteTweets.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
# 実行コマンド
> python deleteTweets.py {%Y} {%m} {%account_id}
#パラメータ説明
%Y: 処理終了年(未設定の場合は最初から最後までが対象)
%m: 処理終了月(未設定の場合は最初から最後までが対象)
%account_id: 対象アカウントID(特定の相手とのやりとりを消去したい場合に設定)
"""
import sys
import pandas as pd
from requests_oauthlib import OAuth1Session
from time import sleep
# 取得してきた各種キー情報を設定 ※※キー情報は他の人に教えちゃダメだよ!悪用されるよ!※※
twitter = OAuth1Session(
client_key="XXXXXXXXXX",
client_secret="XXXXXXXXXX",
resource_owner_key="XXXXXXXXXX",
resource_owner_secret="XXXXXXXXXX"
)
# ファイル食って、列['timestamp']をdatetime型にしておく
df = pd.read_csv("twieeted/tweets.csv")
df['timestamp'] = pd.to_datetime(df['timestamp'])
# 削除済みIDを読んで、DataFrameから消しておく
f = open("deleted_ids.txt")
deleted_ids = str(f.read()).split(",")
f.close()
print("started len(deleted_ids): {}".format(len(deleted_ids)))
for deleted_id in deleted_ids:
if "" != deleted_id:
df = df[df["tweet_id"] != int(deleted_id)]
deleted_ids = []
# 処理開始年月〜処理終了年月まで処理する
# - 処理終了年月が設定されてない場合は最後まで
start_y = int(min(df['timestamp']).strftime("%Y"))
start_m = int(min(df['timestamp']).strftime("%m"))
max_y = int(sys.argv[1]) if 2 <= len(sys.argv) else 0
max_m = int(sys.argv[2]) if 3 <= len(sys.argv) else 0
try:
while True:
# 処理対象年月のツイートのみに絞る(元オブジェクトに影響が及ばないように別オブジェクトに作成)
tweets = df[df["timestamp"].dt.year == start_y]
tweets = tweets[tweets["timestamp"].dt.month == start_m]
if len(tweets) <= 0:
print("bye:)")
break
print("processing... {}/{}".format(start_y, start_m))
"""
XXX ここは毎回変えないといけない。正規表現部分だけ外出しすればいいんだろうけど、面倒臭い。ごめん。
設定例:
先頭が"RT"で始まるツイート(=RT):
"^RT.*"
先頭が"RT"で始まらないツイート(=RT以外)
"^(?!RT).*"
先頭が"@"で始まるツイート(=リプライ)
"^@.*"
先頭が"@"で始まらないツイート(=リプライ以外)
"^(?!@).*"
"""
# 指定された正規表現に従って、ツイートを絞り込み
tweets = tweets[tweets["text"].str.contains("^(?!RT @).*$")] # 中の正規表現を変えて使ってね。ごめんね。
if 3 <= len(sys.argv):
tweets = tweets[tweets["text"].str.contains(sys.argv[3])]
# 1秒ごとにTwitterAPIを呼び出して削除する
# - 削除に失敗(!=200)の場合は、削除済みリストに入れないよう留意
# - すぐに削除せず、どういうツイートが取れるのか見たい時は、sleep以降をコメントアウトすると良い
if 0 < len(tweets):
for index, row in tweets.iterrows():
print("{} - {} : {}".format(row["timestamp"], row["tweet_id"], row["text"]))
sleep(1)
res = twitter.post("https://api.twitter.com/1.1/statuses/destroy/{}.json".format(int(row["tweet_id"])))
if res.status_code == 200 or res.status_code == 404:
deleted_ids.append(row["tweet_id"])
if res.status_code != 200:
print(" - [{}]: {}".format(res.status_code, res.json()))
# 処理終了年月になった場合はbye
if start_m == 12:
start_y += 1
start_m = 1
else:
start_m += 1
if start_y == max_y and start_m == max_m:
print("bye:)")
break
finally:
# 削除対象IDをファイルに書いて終了
# (元CSVをpandas.to_csv()で書き込んだら、データ型が変わってしまって再利用できなかったので苦肉の策。ごめん。)
print("finished len(deleted_ids): {}".format(len(deleted_ids)))
if 0 < len(deleted_ids):
f = open("deleted_ids.txt", "a")
f.write("{}".format(deleted_ids)
.replace("[", "")
.replace("]", "")
.replace("'", "")
.replace(" ", ""))
f.write(",")
f.close()
deleteTweets.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
# 実行コマンド
> python deleteTweets.py {%Y} {%m} {%account_id}
#パラメータ説明
%Y: 処理終了年(未設定の場合は最初から最後までが対象)
%m: 処理終了月(未設定の場合は最初から最後までが対象)
%account_id: 対象アカウントID(特定の相手とのやりとりを消去したい場合に設定)
"""
import sys
import pandas as pd
from requests_oauthlib import OAuth1Session
from time import sleep
# 取得してきた各種キー情報を設定 ※※キー情報は他の人に教えちゃダメだよ!悪用されるよ!※※
twitter = OAuth1Session(
client_key="XXXXXXXXXX",
client_secret="XXXXXXXXXX",
resource_owner_key="XXXXXXXXXX",
resource_owner_secret="XXXXXXXXXX"
)
# ファイル食って、列['timestamp']をdatetime型にしておく
df = pd.read_csv("twieeted/tweets.csv")
df['timestamp'] = pd.to_datetime(df['timestamp'])
# 削除済みIDを読んで、DataFrameから消しておく
f = open("deleted_ids.txt")
deleted_ids = str(f.read()).split(",")
f.close()
print("started len(deleted_ids): {}".format(len(deleted_ids)))
for deleted_id in deleted_ids:
if "" != deleted_id:
df = df[df["tweet_id"] != int(deleted_id)]
deleted_ids = []
# 処理開始年月〜処理終了年月まで処理する
# - 処理終了年月が設定されてない場合は最後まで
start_y = int(min(df['timestamp']).strftime("%Y"))
start_m = int(min(df['timestamp']).strftime("%m"))
max_y = int(sys.argv[1]) if 2 <= len(sys.argv) else 0
max_m = int(sys.argv[2]) if 3 <= len(sys.argv) else 0
try:
while True:
# 処理対象年月のツイートのみに絞る(元オブジェクトに影響が及ばないように別オブジェクトに作成)
tweets = df[df["timestamp"].dt.year == start_y]
tweets = tweets[tweets["timestamp"].dt.month == start_m]
if len(tweets) <= 0:
print("bye:)")
break
print("processing... {}/{}".format(start_y, start_m))
"""
XXX ここは毎回変えないといけない。正規表現部分だけ外出しすればいいんだろうけど、面倒臭い。ごめん。
設定例:
先頭が"RT"で始まるツイート(=RT):
"^RT.*"
先頭が"RT"で始まらないツイート(=RT以外)
"^(?!RT).*"
先頭が"@"で始まるツイート(=リプライ)
"^@.*"
先頭が"@"で始まらないツイート(=リプライ以外)
"^(?!@).*"
"""
# 指定された正規表現に従って、ツイートを絞り込み
tweets = tweets[tweets["text"].str.contains("^(?!RT @).*$")] # 中の正規表現を変えて使ってね。ごめんね。
if 3 <= len(sys.argv):
tweets = tweets[tweets["text"].str.contains(sys.argv[3])]
# 1秒ごとにTwitterAPIを呼び出して削除する
# - 削除に失敗(!=200)の場合は、削除済みリストに入れないよう留意
# - すぐに削除せず、どういうツイートが取れるのか見たい時は、sleep以降をコメントアウトすると良い
if 0 < len(tweets):
for index, row in tweets.iterrows():
print("{} - {} : {}".format(row["timestamp"], row["tweet_id"], row["text"]))
sleep(1)
res = twitter.post("https://api.twitter.com/1.1/statuses/destroy/{}.json".format(int(row["tweet_id"])))
if res.status_code == 200 or res.status_code == 404:
deleted_ids.append(row["tweet_id"])
if res.status_code != 200:
print(" - [{}]: {}".format(res.status_code, res.json()))
# 処理終了年月になった場合はbye
if start_m == 12:
start_y += 1
start_m = 1
else:
start_m += 1
if start_y == max_y and start_m == max_m:
print("bye:)")
break
finally:
# 削除対象IDをファイルに書いて終了
# (元CSVをpandas.to_csv()で書き込んだら、データ型が変わってしまって再利用できなかったので苦肉の策。ごめん。)
print("finished len(deleted_ids): {}".format(len(deleted_ids)))
if 0 < len(deleted_ids):
f = open("deleted_ids.txt", "a")
f.write("{}".format(deleted_ids)
.replace("[", "")
.replace("]", "")
.replace("'", "")
.replace(" ", ""))
f.write(",")
f.close()
ソースコードコメント多くてすみません。
あれこれ手探りで、やっつけで作ったので、「何でこうしたの?」って部分が多くなったので、書いといた方が親切かなと思って書いてます。。。
というか、過去ツイートの黒歴史がうじゃうじゃ出てきて気持ち悪い...
いや、ツイートしたのは自分なんだけど。
Author And Source
この問題について(Pythonで黒歴史クリーナーを作ってみた。), 我々は、より多くの情報をここで見つけました https://qiita.com/tyaunuakkia/items/5883a4571f8fd8562bce著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .