#開発環境
Python3.7.3
Twitter API
#参考にしたページ
https://qiita.com/kngsym2018/items/2524d21455aac111cdee
http://westplain.sakuraweb.com/translate/twitter/Documentation/REST-APIs/Public-API/The-Search-API.cgi
https://syncer.jp/Web/API/Twitter/REST_API/
https://qiita.com/mida12251141/items/97bce06e4167db8ed3d5
https://qiita.com/tomozo6/items/d7fac0f942f3c4c66daf
#事前にやっておくこと
Twitter APIの登録申請。ここでは割愛。
私は申請から許可まで4日ほどかかりました。
「参考にしたページ」の一番目で丁寧な解説がされてます。
#やりたいこと
1レコード1ツイートなテーブル形式の状態でcsvファイルに保存する。
各データには改行はない。
なるべく大量にデータを取得する。
#困ったこと
・一度に検索できるツイート数の上限は100ツイート
・上項の処理の連続実行上限は180回(上限までいくと15分間の待機が必要)
・検索できるツイートデータは一週間前まで
・下記5項目はカンマやら改行やらの楽園状態なので文字列処理必須
・Name
・Screen Name
・Text
・Description
・Location
※Locationは適当なこと書いてるユーザが多すぎてデータとして使えない
取得したツイートデータを変数csvlinetextに入れた後の文字列整形を下記のように行った。
他にもいい方法あると思うけど手っ取り早くこれで対処した。
#textの文字列を整形
csvlinetext = line["text"].strip() #ツイートデータから改行を削除
csvlinetext = csvlinetext.replace(",", " ") #カンマ文字を半角スペースに置換
csvlines = csvlinetext.splitlines() #配列変数に格納することで消しきれない改行を削除
csvlinetext = ''.join(csvlines) #配列変数の全要素内のデータを結合
#シナリオ
分かってる人は見なくてもいいやつ。
この流れでコードを組み立てれば上手くいく。
01.Twitter API登録時にもらう認証キーを変数に代入する
02.検索ワードを変数に代入する
03.検索プロパティを配列変数に代入する
04.OAuth認証でセッションを確立する
(ループ処理開始)
05.Twitter API利用制限回数のチェック
06.セッション切断
07.06の制限にかかった場合は15分待機
08.変数maxidを検索プロパティに指定
09.OAuth認証でセッションを確立する
10.検索実行して結果を変数csvline1に代入する
11.変数の結果をCSVに書き込む
12.ツイートIDを変数maxidに代入する
(ループ処理終了)
#ソース
import os
import json
import config
import csv
import time
import math
from requests_oauthlib import OAuth1Session
from pytz import timezone
from dateutil import parser
from dateutil.relativedelta import relativedelta
from datetime import datetime, date, timedelta
import json, time, pytz, re, sys,traceback
#認証キーの変数代入とセッション確立
CONSUMER_KEY = "XXXXXXXXXXXXXXXXXXX"
CONSUMER_SECRE = "XXXXXXXXXXXXXXXXXXX"
ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXX"
ACCESS_SECRET = "XXXXXXXXXXXXXXXXXXX"
#+****************************************************************
#関数処理
#+****************************************************************
#セッション確立
def getTwitterSession():
return OAuth1Session(CONSUMER_KEY, CONSUMER_SECRE, ACCESS_TOKEN, ACCESS_SECRET)
# 文字列を日本時間2タイムゾーンを合わせた日付型で返す
def str_to_date_jp(str_date):
dts = datetime.strptime(str_date,'%a %b %d %H:%M:%S +0000 %Y')
return pytz.utc.localize(dts).astimezone(pytz.timezone('Asia/Tokyo'))
#API利用制限ステータスチェック
def rate_limit_status():
limit = 0
remaining = 0
reset_minute = 0
twitter = OAuth1Session(CONSUMER_KEY, CONSUMER_SECRE, ACCESS_TOKEN, ACCESS_SECRET)
url = "https://api.twitter.com/1.1/application/rate_limit_status.json"
req = twitter.get(url)
if req.status_code == 200:
res = json.loads(req.text)
limit = res['resources']['search']['/search/tweets']['limit']
remaining = res['resources']['search']['/search/tweets']['remaining']
reset = res['resources']['search']['/search/tweets']['reset']
reset_minute = math.ceil((reset - time.mktime(datetime.now().timetuple())) / 60)
twitter.close()
return limit, remaining, reset_minute
#検索条件を配列変数に代入
def getParam():
params ={
'count' : 100,
'q' : keyword,
'result_type' : 'mixed',
'max_id' : maxid
}
twitter = getTwitterSession()
req = twitter.get(url, params = params)
return twitter, params, req
#+****************************************************************
#メイン処理
#+****************************************************************
#Twitter Endpoint
url = 'https://api.twitter.com/1.1/search/tweets.json'
#ツイートID
maxid = ''
#検索ワード
keyword = '英会話'
#実行日の取得(csvファイル命名用)
today = date.today()
#ツイート取得開始日
start_dt = today
#start_dt = datetime.strptime(start_dt, '%Y%m%d')
dt1 = (start_dt).strftime('%Y-%m-%d')
#ツイート取得最終日
end_dt = (start_dt - timedelta(days=7))
dt2 = (end_dt).strftime('%Y-%m-%d')
since = str(dt1) + '_00:00:00_JST'
until = str(dt2) + '_23:59:59_JST'
csvline1 = "DateTime,ID,User ID,Name,Screen Name,Text,Follower Count,Friend Count,Favorite Count,Retweet Count,Description,Location\n"
with open("twitter_data_%s_%s.csv" % (keyword,today), "a") as f:
f.write(csvline1)
for i1 in range(5000):
#API使用制限回数チェック
limit, remaining, reset_minute = rate_limit_status()
print(remaining)
#API使用制限解除待機
if remaining == 0:
print("** Waiting for limit release **")
time.sleep(60 * (int(reset_minute) + 1))
time.sleep(1)
twitter, params, req = getParam()
if req.status_code == 200:
res = json.loads(req.text)
i2 = 0
i3 = 0
for line in res['statuses']:
i3 += 1
if i3 <= 3:
continue
t = str_to_date_jp(line["created_at"])
maxid = line['id']
maxid -= 1
#Nameの文字列を整形
csvlinename = line["user"]["name"].strip()
csvlinename = csvlinename.replace(",", " ")
csvlines = csvlinename.splitlines()
csvlinename = ''.join(csvlines)
#Screen Nameの文字列を整形
csvlinescreen_name = line["user"]["screen_name"].strip()
csvlinescreen_name = csvlinescreen_name.replace(",", " ")
csvlines = csvlinescreen_name.splitlines()
csvlinescreen_name = ''.join(csvlines)
#textの文字列を整形
csvlinetext = line["text"].strip()
csvlinetext = csvlinetext.replace(",", " ")
csvlines = csvlinetext.splitlines()
csvlinetext = ''.join(csvlines)
#descriptionの文字列を整形
csvlinedescription = line["user"]["description"].replace(",", " ")
csvlinedescription = csvlinedescription.strip()
csvlines = csvlinedescription.splitlines()
csvlinedescription = ''.join(csvlines)
#locationの文字列を整形
csvlinelocation = line["user"]["location"].replace(",", " ")
csvlinelocation = csvlinelocation.strip()
csvlines = csvlinelocation.splitlines()
csvlinelocation = ''.join(csvlines)
csvline1 = "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s" % (t,line["id"],line["user"]["id"],csvlinename,csvlinescreen_name,csvlinetext,line["user"]["followers_count"],line["user"]["friends_count"],line["favorite_count"],line["retweet_count"],csvlinedescription,csvlinelocation)
#末尾に改行を追加
csvline1 = format(csvline1) + '\n'
with open("twitter_data_%s_%s.csv" % (keyword,today), "a") as f:
f.write(csvline1)
i2 += 1
else:
print("Failed: %d" % req.status_code)
f.close()
print(maxid)
print("** Finished **")
#収集したデータを分析する
Mecabを使って単語と品詞のみを抽出すると
再頻出ワードの件数やツイートの傾向が分かる。
マーケティング施策の参考情報程度にはなると思いますが、
複数ワードで検索したデータをマージするなどの設計をしないと
有用性の高い分析はできなそう。
import csv
import pandas as pd
import MeCab
mecab = MeCab.Tagger ('-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
i = 1
f = open('/Users/nomotom/Workspace/py/xxxxxxxx.csv', 'r')
reader = csv.reader(f)
line = f.readline()
for row in reader:
text = row[5]
mecab.parse('')
node = mecab.parseToNode(text)
while node:
#単語を取得
word = node.surface
#品詞を取得
pos = node.feature.split(",")[1]
line = word + ',' + pos + ',\n'
with open("mecab_data.csv", "a") as f:
f.write(line)
print(i)
i += 1
node = node.next
f.close()