こんにちは。最近は、SNSデータをもっと自由に分析できるようになりたいなぁということで関連した記事をよく書いていますが、今回もそのシリーズになります!
前回書いたTwitterデータの分析記事でご紹介した方法の発展形として、今回は、TwitterAPIで取得したデータをデータベースに逐次保存していけるような仕組みを作ってみようと思います。
テキストデータの管理に相性が良いMongoDBをローカルに構築した状態でPythonコードを書いていきます。
Contents
前提となるステップ
まず、PythonでTwitterデータを取得できるようになっていること。
そして、ローカルにMongoDBがインストールされていること。
TweetデータをMongoDBに保存する方法
参考にした記事
今回、以下の記事を参考にさせていただきました。
スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その1
「停電」に関するツイートをpythonで収集して、WordCloudで可視化してみた
PythonからMongoDBにアクセスするためのドライバをインストール
はじめに、PythonからMongoDBを操作するためのドライバをインストールしておきます。
conda install -c anaconda pymongo
ツイートを取得してMongoDBに保存するコード
以下が、コードになります。
何度もコードを実行することを想定して、2回目以降同じコードを実行した場合には、MongoDBに入っているツイートデータの最大IDを取得してきて、それよりも最新のデータのみを取得して保存するようにしました。
import pymongo
from pymongo import MongoClient
from collections import defaultdict
connect = MongoClient('localhost', 27017)
db = connect.tweetDB #データベース名
tweetdata = db.MachineLearning #ツイートデータを格納するコレクション(テーブル)名
def getTwitterData_DB(key_word, repeat):
url = "https://api.twitter.com/1.1/search/tweets.json"
params ={'q': key_word, 'count':'100','lang':'ja', 'result_type':'recent'}
tweets = []
mid = -1
break_flag = 0
## MongoDBに保存されている最新のIDを取得(差分のみを取得)
if tweetdata.count() == 0:
max_id = -1
print("a")
else:
max_id = tweetdata.aggregate([{'$sort': {'id': -1 }}, {'$limit': 1}]).next()["id"]
print(max_id)
for i in range(repeat):
params['max_id'] = mid
params['since_id'] = max_id
res = twitter.get(url, params = params)
if res.status_code == 200:
sub_tweets = json.loads(res.text)['statuses']
limit = res.headers['x-rate-limit-remaining'] if 'x-rate-limit-remaining' in res.headers else 0
# print("API残接続可能回数:%s" % len(limit))
tweet_ids = []
for tweet in sub_tweets:
tweet_ids.append(int(tweet['id']))
tweets.append(tweet)
## Mongo DBに保存
tweetdata.insert(tweet)
if len(tweet_ids) > 0:
min_tweet_id = min(tweet_ids)
mid = min_tweet_id - 1
else:
break_flag = 1
break;
## 終了判定
if break_flag == 1:
break;
else:
print("Failed: %d" % res.status_code)
break_flag = 1
## MongoDBに登録したツイートデータの日付更新
for d in tweetdata.find():
tweetdata.update({'_id' : d['_id']}, {'$set' : {'created_at_localized' : str_to_date_jp(d['created_at'])}})
print("ツイート取得数:%s" % len(tweets))
return tweets
# 文字列を日本時間2タイムゾーンを合わせた日付型で返す
def str_to_date_jp(str_date):
dts = datetime.datetime.strptime(str_date,'%a %b %d %H:%M:%S +0000 %Y').replace(tzinfo=datetime.timezone.utc)
dts = dts.astimezone(pytz.timezone('Asia/Tokyo'))
return str(dts)
直近のpymongoバージョンでは、上のpymongoのいくつかの構文が廃止されて使えなくなっているようです。(insert、update、countなど)
insert() はinsert_many([]) or insert_one()、count()はcount_documents({})、update()はupdate_many or update_oneに変わっているので適宜変更ください。
“機械学習”を含むツイートを最大18000件(一度に取得できるツイート数のAPI側の制限)取得しにいきます。
tweets = getTwitterData_DB("機械学習", 180)
MongoDBに登録されたデータの確認
上記のコードを実行することでMongoDBにツイートが登録されたはずです。MongoDB CompassからDBの状態を確認してみます。
Pythonコード上で事前に指定しておいたデータベース名とコレクション名でデータが登録されていることが確認できました!
![](https://i0.wp.com/www.simpletraveler.jp/wp-content/uploads/2020/04/image-56.png?fit=728%2C455&ssl=1)
MongoDBからデータを抽出する方法
MongoDBに継続的にデータを貯められるようになったところで、最後に保存したデータを抽出してデータ分析に使える形にしようと思います。
これは簡単で以下のコードでDataFrame化してやれば良いです。下記は全件抽出時のコードなので、条件指定があればfind()の中に条件文を記載します。
df_tweet = pd.DataFrame(tweetdata.find())
以上、今回はMongoDBを使う仕組みの構築を行いました。
この仕組みを使った実際のテーマを定めたデータ分析はまた別の記事でご紹介できればと思います。
本日も最後までご覧いただきありがとうございました。参考になった!という方は下のいいねボタンを押していただけると励みになります!
おしまい
コメントを残す