社内の案件でツイッターと連動したキャンペーンを担当している方が、
手動でツイートを収集しなければいけないという悩みを抱えており、
何とかしてあげたいという思いから、DockerとPythonを使って
ツイートの収集ツールを作成してみました。
#作る際に直面した問題点
-
無料のTwitterDeveloperアカウントを所有していたが、取得できるツイートに制限が多く、
かといって自動化のためだけにに高額なプレミアム契約はできない -
そこで以下のサードパーティライブラリ"GetOldTweet"を使って
API無しで任意の数と時期のツイートを取得できるプログラムを作成
https://github.com/Jefferson-Henrique/GetOldTweets-python
=> ある日からプログラムがエラーを吐くようになり、調べたところIssueが挙げられていた
バグが解消される見込みがしばらくはなさそう -
困っていたところ、Issueにインドのエンジニアがコメントしていた
以下のリポジトリを発見
https://github.com/itsayushisaxena/Get_Old_Tweets-Python
どうやらソースコードを見ると、TwitterStandardAPIのアカウントは必要だが、
tweepyとsnscrapeを組み合わせて、これまでと同じように欲しい範囲と数の
ツイートが取得できそう
ということで作ったもの
- DockerでPython3の動作する環境構築
- PythonでTwitterAPIを使ったスクレイピング
- 担当の方にdockerコマンドを意識させずにターミナルから使えるように
自動化するシェルスクリプト
ソースコードはこちら
https://github.com/hikkymouse1007/GetTweets_pub
今回は、案件担当の方のPCで動かせてかつ、難しい操作を排除できる仕組みを
考えて作りました。
そこでDockerとシェルスクリプトによってコンテナ起動・ツイート取得・CSV作成
までを実行してくれる一連の流れを作ってみました。
ディレクトリ構造は以下のようになっております。
.
├── Dockerfile
├── Makefile
├── README.md
├── command
│ └── twitter //シェルスクリプト
├── docker-compose.yml
└── src
├── csv_files //ここにCSVを出力
└── got_v2.py //Pythonのソースコード
Dockerfile, docker-compose
python3の動くコンテナのレシピは以下の記事を参考にさせていただきました。
https://qiita.com/reflet/items/4b3f91661a54ec70a7dc
tweepyが3.9に対応していないため、今回はpython3.8のバージョンを指定しました。
pythonの動作環境と必要なライブラリをインストールします。
# Dockerfile
FROM python:3.8
USER root
RUN apt-get update
RUN apt-get -y install locales && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
RUN apt-get -y install sudo
RUN sudo apt-get update && apt-get install -y cowsay fortunes
ENV PATH $PATH:/usr/games
RUN echo $PATH
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm
RUN apt-get install -y vim less
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install requests requests_oauthlib
RUN pip install pandas
RUN pip install IPython
RUN pip install twitter
RUN pip install tweepy
RUN pip install snscrape
# docker-compose.yml
version: '3'
services:
python3:
restart: always
build: .
container_name: 'python3'
working_dir: '/root/'
tty: true
volumes:
- ./src:/root/src
#got.py
TwtterAPIにアクセスし、ツイートを取得するためのソースコードです。
基本のソースコードはこちらのリポジトリから拝借しました。
https://github.com/itsayushisaxena/Get_Old_Tweets-Python
twitterStandardAPIのアカウント発行時に貰う以下の情報を入力してください。
定数名 | 入力するキーの種類 |
---|---|
TWITTER_CLIENT_KEY | APIキー |
TWITTER_CLIENT_SECRET | APIシークレットキー |
TWITTER_CLIENT_ID_ACCESS_TOKEN | アクセストークン |
TWITTER_CLIENT_ID_ACCESS_TOKEN_SECRET | シークレットトークン |
簡単な流れとしては、後述するシェルスクリプトからdockerコンテナ内に
環境変数を渡し、pythonで環境変数からハッシュタグなどの情報を読み取り、
tweepyとsnscrapeを使って、tweetを取得。
取得したツイートをCSVファイルに出力といった処理を実行します。
import tweepy
import csv
import os
import snscrape.modules.twitter as sntwitter
import sys
sys.dont_write_bytecode = True
#ENV_VALUES
tag = os.environ["TAG"]
since_date = os.environ["FROM"]
until_date = os.environ["UNTIL"]
tweet_count = os.environ["NUM"]
#Provide your own credentials here.
TWITTER_CLIENT_KEY = '####################'
TWITTER_CLIENT_SECRET = '########################'
TWITTER_CLIENT_ID_ACCESS_TOKEN = '####################################'
TWITTER_CLIENT_ID_ACCESS_TOKEN_SECRET = '################################'
auth = tweepy.OAuthHandler(TWITTER_CLIENT_KEY, TWITTER_CLIENT_SECRET)
auth.set_access_token(TWITTER_CLIENT_ID_ACCESS_TOKEN, TWITTER_CLIENT_ID_ACCESS_TOKEN_SECRET)
api = tweepy.API(auth,wait_on_rate_limit=True)
#pip install snscrape
csvFile = open('/root/src/csv_files/%s_from_%s_to_%s_%s_tweets.csv' %(tag, since_date, until_date, tweet_count), 'a')
csvWriter = csv.writer(csvFile)
maxTweets = int(tweet_count) # the number of tweets you require
print('%s since:%s until:%s' % (tag, since_date, until_date))
for i,tweet in enumerate(sntwitter.TwitterSearchScraper('%s' % tag +'since:%s until:%s' % (since_date, until_date)).get_items()) :
if i > maxTweets :
break
csvWriter.writerow([tweet.date, tweet.username, tweet.content]) #If you need more information, just provide the attributes
シェルスクリプト
ここではtwiiterという名前のコマンドのパスを通すことで、検索したい条件に一致する
ツイートを取得するための処理を全て実行させます。
ここで標準入力されたパラメータはDockerコンテナ内に環境変数として渡されます。
command/twitter
#!/bin/sh
echo "次のデータを入力してenterを押してください"
read -p "ハッシュタグ(eg. #テスト): " str1
read -p "データ取得開始日(eg. 2020-08-10): " str2
read -p "データ取得終了日(eg. 2020-08-20): " str3
read -p "取得ツイート件数(eg. 100): " str4
TAG=$str1 FROM=$str2 UNTIL=$str3 NUM=$str4
echo "入力されたデータ"
echo $TAG $FROM $UNTIL $NUM
ANIMALS=("cheese" \
"cock" \
"dragon-and-cow" \
"ghostbusters" \
"pony" \
"stegosaurus" \
"turtle" \
"turkey" \
"gnu"\
)
ANIMAL=${ANIMALS[$(($RANDOM % ${#ANIMALS[*]}))]}
docker-compose -f ~/path/to/docker-compose.yml \
run \
--rm \
-e TAG=$TAG \
-e FROM=$FROM \
-e UNTIL=$UNTIL \
-e NUM=$NUM \
-e ANIMAL=$ANIMAL \
python3 \
/bin/bash -c "python /root/src/got_v2.py && cowsay -f $ANIMAL “ツイートを収集したよ” "
FILENAME="${TAG}_from_${FROM}_to_${UNTIL}_${NUM}_tweets.csv"
echo $FILENAME
mkdir -p ~/Desktop/twitter_csv_files
cp src/csv_files/$FILENAME ~/Desktop/twitter_csv_files
open ~/Desktop/twitter_csv_files/$FILENAME
Makefile
make pathでディレクトリの作成・twitterコマンドの作成を一発で実行してくれます。
makeコマンドは本リポジトリのルートディレクトリで実行します。
今回はユーザディレクトリの直下にcommadというディレクトリを作成し、
そこにtwitterコマンド用のスクリプトファイルを設置します。
make rm-pathでパスを削除可能。
docker-path:
@echo $(PWD)
path:
@mkdir ~/command
@cp ./command/twitter ~/command/twitter
@ln -si ~/command/twitter /usr/local/bin
@chmod 777 ~/command/twitter
rm-path:
@rm -rf ~/command
@rm /usr/local/bin/twitter
実際に動かしてみた
今回作成したプログラムを動かしてみた動画を以下に記載します。
おまけ
先程の動画に謎の動物が入っていますが、こちらはcowsayというプログラムを
今回作成したDockerイメージにインストールしています。
作業者が単調な作業に飽きないように可愛い動物がランダムにCSVファイルの作成完了を
教えてくれるようにしました。
シェルスクリプトに書いた動物名をdockerの起動時にランダムに環境変数として渡し、
スクリプトの終盤にcowsayコマンドを実行させています。
例
ここに書いた動物以外にも色々あるので、興味のある方は調べて追加してみてください。
参考記事
- シェルスクリプト
https://qiita.com/Lambda34/items/7d24ebe6f7bde5bedddc - GetOldTweet(TPL)
https://github.com/hikkymouse1007/Get_Old_Tweets-Python - Docker+Python3
https://qiita.com/reflet/items/4b3f91661a54ec70a7dc - Cowsay
https://qiita.com/Hiroki_lzh/items/8cf206d54f91e29b3912#unix%E3%81%A7%E6%9C%89%E5%90%8D%E3%81%AA%E3%82%A2%E3%82%B9%E3%82%AD%E3%83%BC%E3%82%A2%E3%83%BC%E3%83%88%E3%82%92%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8Bcowsay