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はデータの編集や 動作処理など色々なことができるので、是非使ってみてください( ´∀`)
スポンサーリンク












