:CATEGORIES: @kanazawabengosi #金沢弁護士会 @JFBAsns 日本弁護士連合会(日弁連) #法務省 @MOJ_HOUMU #スクリプト #プログラミング
寝ていた時間も含めてですが20時間ほど掛かったように思います。次のツイートがようやく完成した頃の投稿になります。タイムラインには4時間前と表示されています。
(py37_env) ➜ twilog wc -l *.csv
— 刑事告発・非常上告_金沢地方検察庁御中 (@kk_hirono) April 7, 2021
227225 hirono_hideki20210408054207.csv
137286 kk_hirono20210408054209.csv
79830 s_hirono20210407224547.csv
444341 合計
今回はこのあとソースコードを公開しようと思います。告発状でもご紹介したTwilogのテキストデータですが,TwitterAPIからツイートを取得して追加をするようにしました。3件のアカウントで10分程掛かっていた処理が1秒足らずで終わるようになりました。
(py37_env) ➜ twilog wc -l *.csv 227259 hirono_hideki20210408102712.csv 137294 kk_hirono20210408104001.csv 79835 s_hirono20210408102047.csv 444388 合計
20210408104001という部分が最終更新時刻になりますが,やはり読みづらく勘違いする可能性もありそうなので,これは早めに修正をしておいた方がよいかと考えました。
now_time = Time.now.strftime("%Y-%m-%d_%H%M%S") newFile = "#{@dir}#{user}#{now_time}.csv" check = Dir.glob("#{@dir}#{user}[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{6}.csv").join
check = Dir.glob("#{@dir}#{user}[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{6}.csv").join
上記の箇所に問題があることに気が付きました。Dir.globでは正規表現が使えないということです。
次の方法でうまくいきそうです。もっと簡単に済ませる方法はあるのですが,プログラミングの上達のためによりよい方法を模索しています。
Dir.glob("#{@dir}*").grep(/s_hirono[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{6}.csv/)
ようやくうまくいきました。.joinは必要なさそうでしたが,これは返却値が配列になっているのを文字列に型変換する処理です。文字列として扱うことを明示しておいた方がよいのかと考えていましたが,配列のままでもcheck.empty?の条件式は同じでした。
(py37_env) ➜ twilog wc -l *.csv 227262 hirono_hideki2021-04-08_114623.csv 137300 kk_hirono2021-04-08_114405.csv 79836 s_hirono2021-04-08_114625.csv 444398 合計
それではソースコードの掲載です。今朝になっての思いつきですが,江村正之検察官について先に取り上げておこうかと思います。
#!/usr/bin/env ruby #encoding:UTF-8 #告訴状-2013-金沢地方検察庁御中_API require 'twitter' require 'open-uri' require 'time' require "fileutils" @users = ['hirono_hideki','kk_hirono','s_hirono'] @dir = "/home/a66/twilog/" @dir=ARGV[0].dup if ARGV[0] if @dir !~ /^\/.+/ then puts "ディレクトリは絶対パスで指定して下さい!" exit 1 end if @dir !~ /.+\/$/ then @dir.sub!(/(.+)/){ $1 + '/'} end #@users = ['s_hirono'] def twilogFileAdd(user) tweets = Array.new # ログイン client = Twitter::REST::Client.new do |config| config.consumer_key = 'カスタマーキー' config.consumer_secret = 'カスタマーシークレット' config.access_token = 'アクセストークン' config.access_token_secret = 'トークンシークレット' end client.user_timeline("#{user}", {:count => "300", :page => "1", :tweet_mode =>"extended"}).each do |tweet| tw_url = "https://twitter.com/#{tweet.user.screen_name}/status/#{tweet.id}" tw_date = "#{(tweet.created_at + (60 * 60 * 9)).strftime("%Y-%m-%d %H:%M:%S")}" user = tweet.user.screen_name name = tweet.user.name tweet_text = tweet.full_text tweets << "#{tw_date} \"#{tweet_text.gsub(/(\r\n|\r|\n|\f)/,'\n').gsub('"', '\\\"')}\" #{tw_url}" end puts "#{user} #{tweets.size}件を取得しました。" now_time = Time.now.strftime("%Y-%m-%d_%H%M%S") newFile = "#{@dir}#{user}#{now_time}.csv" check = Dir.glob("#{@dir}*").grep(/s_hirono[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{6}.csv/).join unless File.directory?(@dir) then puts "#{@dir}#{user}[0-9]*.csv" FileUtils.mkdir_p(@dir) `touch "#{newFile}"` end if check.empty? then File.open(newFile, "w") do |io| tweets.each do |x| io.puts(x) end end puts "#{newFile}を新規に作成しました。\n\n" return end twilogFile = `find "#{@dir}" -name '*.csv' | grep -E "#{@dir}#{user}[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{6}.csv"` puts twilogFile.chomp! oldFile = twilogFile.chomp lastDate = `head -n 1 "#{twilogFile.chomp}"` lastDatePoint = lastDate.scan(/^([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}) .+/)[0] search_text = lastDatePoint.join n = tweets.index(tweets.select { |e| e =~ %r{^#{search_text}.*} }.join) now_time = Time.now.strftime("%Y-%m-%d_%H%M%S") updateFile = "#{@dir}#{user}#{now_time}.csv" if n == 0 then puts "更新なし\n\n" return else puts "#{n}件の更新です。" end #tweets.reverse! tweets[0..n-1].each do |x| puts x end cmd = "cp #{oldFile} #{updateFile}" `#{cmd}` File.open(updateFile, "r+") do |io| ## ブロックにすると最後に"io.close"を書く手間が省けます line = io.read ## 引数なしのreadは行末まで読み込みます io.seek(0) ## io#seekは先頭からのオフセットを指定する場合1引数で書けます tweets[0..n-1].each do |x| io.write(x) io.write("\n") end io.write(line) end if oldFile == updateFile then return end FileUtils.rm(oldFile) puts "#{n}件を追加した#{updateFile}を新規作成し,#{oldFile}を削除しました。\n\n" end #twilog/hirono_hideki210407.csv twilog/kk_hirono210407.csv twilog/s_hirono210407.csv @users.each do |u| twilogFileAdd(u) end
:count => "300"とハッシュ値の値を指定していますが,200件しか取得できないと思います。ただ,2,3日前同じ処理をするコマンドで300件の取得が出来たことがあり,TwitterAPIの仕様が変わったのかと思いました。多めに指定してもエラーはでないようです。
時刻は12時03分ですが,昨日4月7日のほぼ同じ時間に,このスクリプトの本体は出来上がっていました。そのあと難儀し時間がかかったのは,ディレクトリーを指定し,新規にファイルを作成する場合の処理です。
共通したコードを数箇所に貼り付けていけば,簡単に処理の分岐ができたのですが,無駄にコードが増えると全体の可読性が悪くなるので,その辺りも勉強のつもりで取り組んでみました。