raretwit.ps1というスクリプトを作りました。
コードは一番下に置いたので、すぐに使ってみたいひとはそちらをどぞ。
さて、ではまずヘルプを呼び出してみます。スクリプトのはじめのコメント文に書式に沿って書くことでget-helpを使用した場合に表示することができます。
とりあえず、ずらずら書いてみました。
順を追ってみてみましょう。
1.フォローユーザーを取得する
引数に g をつけることで、フォローユーザーを取得できます。
コードは一番下に置いたので、すぐに使ってみたいひとはそちらをどぞ。
さて、ではまずヘルプを呼び出してみます。スクリプトのはじめのコメント文に書式に沿って書くことでget-helpを使用した場合に表示することができます。
とりあえず、ずらずら書いてみました。
順を追ってみてみましょう。
1.フォローユーザーを取得する
引数に g をつけることで、フォローユーザーを取得できます。
アカウント名の入力を促されるので、取得したいユーザーアカウントを入力すると、
webAPIからデータを取得し、カレントディレクトリのtuser.txtに書き出します。
別に自分のアカウントでなくても、他の人のフォローリストでも取得できます。
2.レアユーザーを取得する
引数に r をつけることで、レアユーザーを取得することができます。
昨日分のツイートから指定した回数以下の発言をしたユーザーを抽出し、
rareuser.txtに書き出します。
たとえば、5回以下の発言をしたユーザーを取得する場合を例とします。
「全 2 ページ 1 ページ目 9 回実施」と出たあと、「~回目完了」と出力してます。
これは、たとえばフォロー数が100人いたとして、そのままwebAPIに100人分のツイートを検索するよう投げても、検索過多でエラーを返してくるための処置です。
一度にできる検索上限数は25件前後のようだったので、余裕をもって20人ずつ分割して処理させてます。
100人フォローユーザーがいたとすれば、20人1組として5組にわけ、5回にわけてツイート検索する、、という感じです。
また、一度に取得できる結果は最大100件までです。
101件以降のデータを取りたい場合は、pageを指定してあげる必要があります。
ちょうど書き込みが多いWeb掲示板なんかを想像するとわかりやすいかもしれません。
今回は、あまり多くのデータを取得しても時間がかかるだけなので、
10組以上、つまり200人以上のフォローユーザーがいる場合はデータ取得を1ページ分(100件)だけ。
それ以下の組数の場合は2ページ分(200件) 取るようにしました。
それぞれの組ごとで取得したデータは一度すべて足し合わせます。
その結果をGroup-Objectを使用して名前ごとにグループ分けし、出力します。
さきほど指定した回数以上のユーザーを切り捨てた後、
残ったユーザーで再度20人1組にわけ、再び同じ処理を繰り返します。
これを指定した回数以上のツイートユーザーがいなくなるまで繰り返します。
最終的に残ったユーザーアカウントはカレントディレクトリのrareUser.txtに書き出されます。
これで、レアユーザーリストができました。
3.レアユーザーのツイートを表示する
引数にsをつけることで、前日分からのレアユーザーのツイートを表示します。
出力の仕方は、ストリームのように流れ、一文字ごとタイプで打つような表示がされます。
タイプのような表示がうざったい、という場合には、引数にnotypeをつけることで、やめることもできます。
正直、個人的にはタイプでの表示は文字を目で追うことが疲れるので、お遊び的な要素ですねw
次のツイートには3秒待ってから進みますが、引数に tltime [数字] で待ち時間を変えることもできます。ツイートの数が多い時には待ち時間を小さくして一気にみたり、逆にゆっくり見たい場合には秒数を増やしてください。
4.キーワード検索をする
派生した機能として、キーワード検索もつけました。
昔、Googleでリアルタイム検索がありましたが、あれと似たような感じです。
引数に word [キーワード] をつけることで呼び出せます。
キーワード検索の場合、レアユーザーツイートと違い、多くのデータをとってくるので
さしあたって実行した時点での最新25件を表示します。あまり多くあっても見きれないですしね。
25件ながし終えたら、再度検索しなおし、25件目の時刻以降のツイートを再び表示します。
こちらもデータが多い場合には最新の25件のみの表示となってます。
ちなみに取得準備待ちというのは、
twitter webAPIには1時間あたりの取得制限があり、取得頻度が多い場合、制限にひっかかってしまうため 次の検索を行うまで70秒待つよう設定してます。
ただし、ツイート表示の時間分は引いているので、実際には
70-(データ表示数)*1ツイートあたりの待ち時間(デフォルト3秒)待機してから検索を行います。
せっかくなのでその時間を write-progress に渡して表示させるようにしてみました。
引数に viewtime をつければ見ることができます。
5.キーワードリストから検索する
カレントディレクトリにtword.txtを用意して、キーワードを記入。
引数にwordlをつけることでtword.txtを読み込み、複数キーワード検索が可能です。
ちなみに、wordとwordl 両方引数つけた場合は、wordl の方が優先されます。
6.フォローユーザーを検索する
フォローユーザーを検索する場合には引数に f をつけることで検索可能です。
レアユーザーがダークマゼンダ、通常ユーザーは青色でアカウントに色付きで表示されます。
こちらもキーワード検索と同じように初回の検索を終えたら再び検索しなおし、表示し続けます。
初回が最新30件の表示、2回目以降は特に数に制限なく表示します。
こちらもキーワード検索と同じく、70秒待機して検索しますが、
あまりにもフォローユーザーが多い場合(1000人単位くらい)には検索に少し時間がかかってしまうこともあるかもしれません。
そういった場合には 手動でtuser.txtを編集して、ユーザー数を減らすことで改善されるかと思います。
7.全部検索する
引数なしで実行すると、 wordl、f の引数をつけた状態、つまりキーワード検索とフォロー検索両方実行して表示されます。
レアユーザーがダークマゼンダ、通常ユーザーは青色、キーワード検索は黄色でそれぞれ表示されます。
初回は最新30件表示します。キーワード検索は最新25件まで取得、フォローユーザーは制限なしで時系列にソートされて表示されていきます。
8.コード
ながながと説明してきましたが、結構まだエラーやら抜けがあったりコードも汚いです(;´∀`)。
まぁ、こんなやり方もあるよというサンプル的な感じで掲載
raretwit.ps1
<# .SYNOPSIS レアツイ。 twitterで各発言検索スクリプト .DESCRIPTION -word [キーワード] キーワード検索、ツイート表示 -wordl tword.txt に書かれたワード検索、ツイート表示 -f follower、レアユーザーのツイート表示 -s レアユーザーのツイート表示(1回のみ) 無地 tword.txtとユーザーリストのツイート表示 -r レアユーザーを取得、rareUser.txtに書きこむ -g followユーザーを取得、tuser.txtに書きこむ -tltime [整数] 次のTL表示の秒数指定。指定しなければは3秒 -notype タイプ形式の表示をやめる -viewtime 次のデータ取得の待ち時間を表示する .LINK Twitter Search API の使い方 http://www.ibm.com/developerworks/jp/xml/library/x-twitsrchapi/ Twitter API http://watcher.moe-nifty.com/memo/docs/twitterAPI.txt おえかきWindows http://win-enikki.blogspot.com/ .NOTES from%3Aユーザー名で特定ユーザー発言 to%3Aユーザー名で特定ユーザーにむけての発言 %23[検索名]でハッシュの検索 langをつけて国の設定 API制限は60分間に100回で発生 最大検索数は25前後。検索数を20個に分割して検索実施 .EXAMPLE #> param(` [switch]$g,[switch]$r,[switch]$s,[switch]$f,` $word,[switch]$wordl,` [switch]$notype,$tltime=3,[switch]$viewtime` ) #検索リストをTwitterAPI形式に変換 function join-search { param ($tuser) $txtUSerfrom=$tUser | %{ "from%3A"+"$_" } $txtUserfrom -join '+OR+' } #検索リストを分割する function join-search2 { param ($userlist) $countP=[math]::Truncate($userlist.length /20) $countD=$userlist.length % 20 for ( $i = 1; $i -le $countP; $i++ ) { $s=20*($i-1) $e=20*$i-1 join-search $userlist[$s..$e] if ($i -eq $countP){ join-search $userlist[$s..$($s+$countD)] } } } #TwitterAPI形式の検索語句から検索結果を返す Function Get-TwitterSearch { Param($searchTerm) if ($WebClient -eq $null) { $WebClient=new-object System.Net.WebClient } $results=[xml]($webClient.DownloadString(` "http://search.twitter.com/search.atom?lang=ja&q=$SearchTerm")) $Searchitems=$results.feed.entry $SearchItems } #引数ユーザーのFollowerチェック function Check-follower { param($tname,$tpage=-1) if ($WebClient -eq $null) { $WebClient=new-object System.Net.WebClient } while ($tpage -ne 0) { $results=[xml]($webClient.DownloadString(` "http://api.twitter.com/1/statuses/friends/"+ $tname + '.xml?cursor=' + $tpage)) $results.users_list.users.user | % { $_.screen_name } $tpage=$results.users_list.next_cursor } } #検索ユーザーテキスト if ($g){ $tname=read-host アカウント名入力 write-host データ取得中... $a=Check-follower $tname $a $a | Out-File .\tuser.txt write-host tuser.txtに書き込みました。 break } if ( test-path .\tuser.txt) { $txtUser=Get-Content .\tuser.txt | sort -Unique } else { write-host tuser.txtがみつかりません。 write-host -g オプションでfollowerを読み込んでください break } $searchUser= join-search2 $txtuser #Search Twitterから読み込んだデータを編集、表示する function See-tweet { param($obj, $rare, $txtuser) $($obj.length-1)..0 | ? { $obj[$_] -ne $null } | % { $twitname=$obj[$_].author.name $twittitle=$obj[$_].title #それぞれの取得データに応じて名前部分の色を変化 if (Select-String -InputObject $twitname $rare) { $colorname="DarkMagenta" }elseif (Select-String -InputObject $twitname $txtUser) { $colorname="blue" }else { $colorname="darkgreen" } if ($txtTword){ if (Select-String -InputObject $twittitle $txtTword){ $colorname="yellow" } } #出力内容 write-host $twitname -ForegroundColor $colorname -NoNewline write-host " ---- " -NoNewline write-host $([datetime]($obj[$_].published)) $_ if (-not $notype){ for ($i=0;$i -le $(($obj[$_].title).length-1); $i++){ write-host $($obj[$_].title)[$i] -nonewline Start-Sleep -Milliseconds 20 } Write-Host "" } else { write-host $obj[$_].title } Write-Host "" Start-Sleep -s $tltime } $colorname=$null } $yday=[string]$(Get-Date).adddays(-1).tostring("yyyy-MM-dd") $tday=[string]$(Get-Date).tostring("yyyy-MM-dd") #レアユーザーを取得する function Check-RareUser { param($searchrareuser, $txtuser) [int]$twitcount=Read-host 何回発言以下を取得しますか? $rare=$txtuser do { $twitresult=$null $txtmanyUser=$null $gruser=$null if (($searchrareUser.length) -le 10) { $t=2 }else { $t=1 } for ($i=1; $i -le $t; $i++){ write-host "全" $t "ページ" $i "ページ目"` ($searchrareUser.length) "回実施" $twitresult += 0..($searchrareUser.length-1) |` % { get-twittersearch $($searchrareuser[$_] + ` "+since%3A$yday+until%3A$tday&rpp=100&page=$i") write-host $($_+1) 回目完了 } } write-host 回数ソート中.. $twitresult.count $gruser = $twitresult | %{ $_.author.name } | Group-Object |` sort -Property count -Descending $gruser $txtmanyUser = $gruser | ? { $_.count -gt $twitcount } |` % {$_.name -replace " .*","" } Start-Sleep $tltime if ($txtmanyuser) { $rare=Compare-Object $txtmanyUser $rare -SyncWindow $rare.count |` % { $_.inputobject } $searchrareUser = join-search2 $rare } } while ($txtmanyUser) $rare > .\rareUser.txt } if ($r){ Write-Host "前日分のレアチェックユーザー発言" Check-RareUser $searchuser $txtUser write-host 完了 break } if ( test-path .\rareuser.txt) { $txtrareUser=Get-Content .\rareuser.txt | sort -Unique } else { write-host rareuser.txtがみつかりません。 write-host -r オプションでレアユーザーを生成してください break } $searchrareUser=join-search2 $txtrareUser #レアユーザーのツイート表示 if ($s){ $twitresult=$null for ($i=1; $i -le 2; $i++){ $twitresult += 0..($searchrareUser.length-1) |` % { get-twittersearch $($searchrareuser[$_] + ` "+since%3A$yday+until%3A$tday&rpp=100&page=$i") } } $twitresult = $twitresult | sort -Property published -Descending write-host "総発言数:" $twitresult.count see-tweet $twitresult $txtrareUser $txtUser break } #キーワード検索フラグ if ( test-path .\tword.txt) { $txtTword= Get-Content .\tword.txt | sort -Unique if ($txtTword){ $searchWord=$txtTword -join '+OR+' } } if ($word) { $searchWord=$null $searchWord=$word -join '+OR+' $w="true" } if($wordl) { if ($txtTword) { $w="True" }else{ write-host tword.txtに検索文字をいれてください。 break } } #残り時間表示 function Count-Time { param($time) for ($i = 1; $i -le $time; $i++ ) { $status = " {0} 秒" -F $i,$($i*100/$time) $currentOperation = "{0} 秒待ちです" -F $time Write-Progress -activity "待機中" -status $status -PercentComplete $($i*100/$time)` -CurrentOperation $currentOperation Start-Sleep -s 1 } Write-Progress -Activity "Working..." -Completed -Status "All done." } #ツイートを調べる function Check-List { param($first) $twitresult = $null if ($w) { #wordは25発言まで取得 $twitresult += get-twittersearch $("$searchWord&rpp=25") } if ($f) { $twitresult += 0..($searchUser.length-1) |` % { get-twittersearch $($searchUser[$_] + "&rpp=10") } } if (-not($w -or $f)){ $twitresult += 0..($searchUser.length-1) |` % { get-twittersearch $($searchUser[$_] + "&rpp=10") } if ($searchWord) { $twitresult += get-twittersearch $("$searchWord&rpp=25") } } if (-not $first){ $twitresult = $twitresult | ? { $([datetime]($_.published)) -gt $script:getlasttime} } if ($($twitresult -eq $null) -or $($twitresult[0] -eq $null)) { Write-Host "##########################################" Write-Output "データはありませんでした" $script:getlasttime=$(get-date) if ($viewtime){ Count-Time 70 }else{ Start-Sleep -s 70 } Write-Host "##########################################" }else{ Write-Host "############## コメント数 $($twitresult.length)" $twitresult = $twitresult | sort -Property published -Descending #30ツイートまで出力する if ($first) { $twitresult = $twitresult[0..30] } see-tweet $twitresult $txtrareUser $txtUser $script:getlasttime=$([datetime]($twitresult[0].published)) Write-Host "##########################################" Write-Host "取得準備待ち" if (($twitresult.length-1)*$tltime -le 70) { if ($viewtime){ Count-Time $(70-($twitresult.length-1)*$tltime) } else { Start-Sleep -s (70-($twitresult.length-1)*$tltime) } }else{ } } } Write-Host "##########################################" Write-Host "ストリーム開始!" check-list first $a = 0 do { check-list } while ($a -ne 1)
今回は、おもいついたままに作ったスクリプトでしたが、
PowerShellはデータの編集や 動作処理など色々なことができるので、是非使ってみてください( ´∀`)
スポンサーリンク