ニートが学ぶプログラミング

ニートの日記。プログラムのことやら、くだらないこと、思ったことをまとめていきます。頑張って毎日更新するぞぉ_(:3」∠)_ 更新が連続して途切れたら察してください。

各政党フォロワーのユーザー情報を取得してみた

こんにちは鬱太郎です。昨日取得したフォロワーIDからユーザー情報を取得してみました。ですので、それについて記事にしたいと思います。

ソースコード

取得したデータ

プログラムを起動して約2時間ほどですべてのデータが集まりました!データを取得してから、データベースに追加するなどの処理をしていたためレートリミット回復の時間はあまりいりませんでした。

取得したデータの詳細を表にまとめておきますね。

政党 IDの数 取得したデータ数 ロス サイズ(MB)
自民党 124,328 124,317 11 131.5
公明党 73,705 73,702 3 72.2
民進党 25,335 25,333 2 30.1
日本維新の会 13,707 13705 2 15.8
立憲民主党 174,896 174,880 16 195.2
希望の党 10,607 10,606 1 12.2
日本のこころ 37,913 37,905 8 47.0
共産党 36,732 36,727 5 43.1
社民党 21,649 21,644 5 27.1
自由党 28,244 28,240 4 35.5
幸福実現党 6,754 6,753 1 7.6

どうしても、取得時にロスが発生してしまうようです。フォロワーのIDを取得してからユーザーの情報を取得する間に、アカウント削除などの理由から取れないユーザー情報があったようです。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171015151917p:plain f:id:neet-utsu-taro:20171015154433p:plain

ユーザー情報のJSONの例

取得したデータの一例を表示したいと思います。こんな感じのデータをTwitterAPIで取得できます。

{
        "_id" : ObjectId("59e1823fae898d323863ba37"),
        "miniProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg",
        "screenName" : "neet_utsu_taro",
        "contributorsEnabled" : false,
        "profileUseBackgroundImage" : false,
        "profileBackgroundTiled" : false,
        "createdAt" : "Tue Aug 29 09:12:49 GMT+09:00 2017",
        "profileBackgroundImageURL" : "http://abs.twimg.com/images/themes/theme1/bg.png",
        "biggerProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg",
        "protected" : false,
        "miniProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg",
        "profileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg",
        "id" : NumberLong("902323111994916864"),
        "profileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg",
        "profileSidebarBorderColor" : "000000",
        "utcOffset" : -25200,
        "URLEntity" : {
                "displayURL" : "neetaro.com",
                "start" : 0,
                "end" : 23,
                "text" : "https://t.co/8tj7yW4gCF",
                "expandedURL" : "http://www.neetaro.com",
                "URL" : "https://t.co/8tj7yW4gCF"
        },
        "timeZone" : "Pacific Time (US & Canada)",
        "defaultProfile" : false,
        "profileLinkColor" : "91D2FA",
        "originalProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg",
        "profileSidebarFillColor" : "000000",
        "rateLimitStatus" : {
                "limit" : 75,
                "secondsUntilReset" : 900,
                "remaining" : 74,
                "resetTimeInSeconds" : 1507952068
        },
        "profileBannerMobileURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile",
        "name" : "ニート鬱太郎",
        "followersCount" : 69,
        "followRequestSent" : false,
        "status" : {
                "inReplyToUserId" : -1,
                "userMentionEntities" : [ ],
                "source" : "<a href=\"http://twitter.softama.com/\" rel=\"nofollow\">ツイタマ for Android</a>",
                "retweeted" : false,
                "currentUserRetweetId" : -1,
                "createdAt" : "Sat Oct 14 10:10:19 GMT+09:00 2017",
                "hashtagEntities" : [ ],
                "mediaEntities" : [ ],
                "inReplyToStatusId" : -1,
                "extendedMediaEntities" : [ ],
                "id" : NumberLong("919007427701248000"),
                "text" : "おはようございます❗☀🙋❗",
                "lang" : "ja",
                "favorited" : false,
                "retweet" : false,
                "accessLevel" : 0,
                "URLEntities" : [ ],
                "truncated" : false,
                "quotedStatusId" : -1,
                "possiblySensitive" : false,
                "contributors" : [ ],
                "retweetedByMe" : false,
                "symbolEntities" : [ ],
                "retweetCount" : 0,
                "favoriteCount" : 1
        },
        "showAllInlineMedia" : false,
        "geoEnabled" : false,
        "profileBannerMobileRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile_retina",
        "translator" : false,
        "description" : "ニートです。どうでもいいこと言います。趣味アニメ等 だけども最近全く見てない。。。 フォローされたら、bot等でない限りフォロー返します。  犬は柴犬、猫は黒猫が好き。  柴犬っていいよね…The犬って感じで _(:3」∠)_ ブログやってます。下のリンクからどうぞ。",
        "profileTextColor" : "000000",
        "descriptionURLEntities" : [ ],
        "URL" : "https://t.co/8tj7yW4gCF",
        "biggerProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg",
        "profileBannerIPadURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad",
        "lang" : "ja",
        "defaultProfileImage" : false,
        "statusesCount" : 192,
        "accessLevel" : 2,
        "profileBackgroundImageUrlHttps" : "https://abs.twimg.com/images/themes/theme1/bg.png",
        "profileBackgroundColor" : "000000",
        "verified" : false,
        "favouritesCount" : 218,
        "friendsCount" : 105,
        "listedCount" : 0,
        "profileBannerURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web",
        "location" : "自宅",
        "profileBannerRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web_retina",
        "originalProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg",
        "profileBannerIPadRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad_retina"
}

ユーザー情報JSONのプロパティ説明

私が理解した範囲、およびできる範囲で調べたものを説明していきます。プロパティは大きく分けて

  • 数値
  • bool値
  • 文字列
  • URL
  • オブジェクト
  • 最近したツイート

に分けられます。これについて説明していきます。

数値

数値は主にIDやツイート数などの計測情報からなります。

プロパティ名 意味
_id MongoDBのデフォルトID
id ユーザーID
utcOffset UTCのオフセット値(秒)
followersCount フォロワー数
statusesCount ツイート数
accessLevel 不明。おそらくTwitterAPIのアクセスレベルか?
favouritesCount いいね数
friendsCount フォロー数
listedCount リスト数

ツイート数からフォロワー数等の有名な数値がデータとして格納されています。

私のデータはなぜかタイムゾーンがUSカナダになっているのでutcOffsetがおかしい値になっていましたね。

bool値

bool値というのはtruefalseで表現する状態を表す値です。trueならyesfalseならnoと考えるとわかりやすいと思います。

プロパティ名 意味
contributorsEnabled ユーザーがcontributor modeを有効にしたかどうか(認証アカウントで複数人数での管理をOKにしているか等)
profileUseBackgroundImage ホーム画面で背景に画像を使っているかどうか
profileBackgroundTiled ホーム画面で背景にタイル画像を使っているかどうか
protected 鍵垢かどうか
defaultProfile ユーザーがユーザープロファイルのテーマまたは背景を変更していないことを示します。
followRequestSent 不明
showAllInlineMedia 不明
geoEnabled 位置情報を有効にしているかどうか
translator ユーザーがTwitterの翻訳者コミュニティに参加しているかどうか
defaultProfileImage trueの場合、ユーザが自分のプロフィール画像をアップロードしておらず、代わりにデフォルト画像が使用されていることを示します。
verified 認証済みかどうか

Twitterの設定情報などが多いですね。鍵垢か認証済みがよく知られている項目でしょうか?

文字列

プロパティ名 意味
screenName スクリーン名(@に続く名前)
createdAt アカウント作成日時
timeZone タイムゾーン名
name 名前
description 自己紹介
lang 表示言語
location 場所(ユーザーが自由に決めれるやつ)

自己紹介なども取得できるようですね。

色はユーザーが設定したテーマの色等ですね。

プロパティ名 意味
profileSidebarBorderColor 不明
profileLinkColor 不明
profileSidebarFillColor 不明
profileTextColor 不明
profileBackgroundColor 不明

プロパティ名からどこの色のことを言っているのかはなんとなくわかるのですが、あまり意味のない数値だと思います。詳しく調べませんでした。

URL

URLは主に画像のリンク等の文字列がデータとして入っています。

オブジェクト

プロパティ名 意味
URLEntity プロフィールのURLの内容
rateLimitStatus TwitterAPIのレートリミットオブジェクト
status 最近したツイート

オブジェクトの中でも最近したツイート以外はたいした意味を持ちません。

最近したツイート

ユーザー情報の中には最近したツイートの内容が付属されています。statusというオブジェクトにツイート情報が入っています。

プロパティ名 意味
inReplyToUserId リプライ先のユーザーID(リプライでなければ-1)
userMentionEntities メンションの配列
source ツイートしたアプリの詳細
retweeted 不明
currentUserRetweetId 不明
createdAt ツイート日時
hashtagEntities ハッシュタグの配列
mediaEntities 画像等のメディアの配列
inReplyToStatusId リプライ先のツイートID(リプライでなければ-1)
extendedMediaEntities 画像等のメディアの配列(extended)
id ツイートID
text ツイート本文
lang ツイート言語
favorited 不明
retweet 不明
accessLevel 不明
URLEntities URLの配列
truncated 翻訳されたかどうか
quotedStatusId 引用ツイート元のツイートID(引用していなければ-1)
possiblySensitive 不明
contributors 不明
retweetedByMe 不明
symbolEntities 不明
retweetCount リツイート数
favoriteCount いいね数

まだ詳細な意味は分かりません。ごめんなさい!

実際に政党別で比べてみる

詳しい比較は後日やります。今日はフォロワーがどれくらい鍵垢かどうかを調べたいと思います。

MongoDBはdb[collection_name]db.collection_nameのように扱えます。db.getCollectionNames().forEachですべてのコレクションについてfunction()の中身を実行させます。

> db.getCollectionNames().forEach(function(e){ 
if(e.match(/_ids$/))return;
var all = db[e].count();
var count= db[e].find({protected:true}).count();
print(e +","+count+","+all+","+count/all); 
} 
)
党名 スクリーン名 鍵垢数 フォロワー数 鍵垢率 偏差値
立憲民主党 CDP2017 25722 174880 0.1470 60.68
民進党 MinshintoNews 3257 25333 0.1285 51.24
社民党 SDPJapan 2288 21644 0.1057 39.59
幸福実現党 hr_party_TW 874 6753 0.1294 51.68
共産党 jcp_cc 4076 36727 0.1109 42.27
自民党 jimin_koho 16327 124317 0.1313 52.65
希望の党 kibounotou 1795 10606 0.1692 71.98
公明党 komei_koho 9510 73702 0.1290 51.48
日本のこころ nipponkokoro 4047 37905 0.1067 40.12
維新の会 osaka_ishin 1807 13705 0.1318 52.91
自由党 seikatsu1pr 2750 28240 0.0973 35.34
名称
平均 0.1261
標準偏差 0.019611

フォロワーの鍵垢率が高い政党は希望の党,立憲民主党,維新の会ですね。偏差値で見ると希望の党立憲民主党が明らかに高いことが分かります。逆に鍵垢の率が極端に低い自由党社民党も目立ちます。

比較する値がbool値だとこんな感じに楽にできますね!

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171016163838p:plain

終わりに

ここまで読んでくださってありがとうございます!

Twitterのユーザー情報の取得が完了しました!これからデータを分析していきたいと思います。もしかしたら、2・3日かかるかもしれません。いいデータ取れるといいんですが…

またね('ω')ノ

各政党のフォロワーIDをデータベースに追加してみた

こんにちは鬱太郎です。今日は日本の政党のフォロワーIDをデータベースに格納してみましたので、それを記事にしたいと思います。

f:id:neet-utsu-taro:20171014204511p:plain:h300

/followers/ids

今回はTwitterAPIの/followers/idsを使っていきたいと思います。

Get followers/ids

指定したユーザーに続くすべてのユーザーのユーザーIDのカーソル付きのコレクションを返します。 現時点では、結果は最新のものから順番に並べられますが、この注文は予告なしに変更され、一貫性の問題が発生する可能性があります。結果は5,000ユーザーIDのグループで与えられ、結果の複数の「ページ」は後続の要求でnext_cursor値を使用してナビゲートできます。詳細については、「カーソルを使用したコレクションのナビゲート」を参照してください。 このメソッドは、GET users/lookup と組み合わせて使用​​すると特に強力です。これは、ユーザーIDをフルユーザーオブジェクトに一括して変換できるメソッドです。

GET followers/ids — Twitter Developers

このアクセスにはレートリミットが存在します。15分に15回しかアクセスできません。

1回につき5000人のIDを取得できます。

ですので、15分に75000人のIDしか取得できませんね。

Twitter4jではTwitter#getFollowersIDsというメソッドを使います。

各政党のフォロワーIDを取得してMongoDBに格納

自民党

f:id:neet-utsu-taro:20171014195206p:plain

5000件取得
・・・
5000件取得
途中で75000件追加しました。
レートリミット回復のため897000[ms] 停止します。
5000件取得
・・・
5000件取得
4328件取得
49328件追加しました。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014191639p:plain

公明党

f:id:neet-utsu-taro:20171014181555p:plain

5000件取得
・・・
5000件取得
3705件取得

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014181317p:plain

希望の党

f:id:neet-utsu-taro:20171014124126p:plain

5000件取得
5000件取得
607件取得

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014131304p:plain

民進党

f:id:neet-utsu-taro:20171014195747p:plain

レートリミット回復のため91000[ms] 停止します。
5000件取得
5000件取得
5000件取得
5000件取得
5000件取得
335件取得
25335件追加しました。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014200026p:plain

立憲民主党

f:id:neet-utsu-taro:20171014194937p:plain

5000件取得
5000件取得
5000件取得
5000件取得
5000件取得
途中で25000件追加しました。
レートリミット回復のため450000[ms] 停止します。
5000件取得
・・・
5000件取得
途中で75000件追加しました。
レートリミット回復のため897000[ms] 停止します。
5000件取得
・・・
5000件取得
4896件取得
74896件追加しました。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014194428p:plain

日本維新の会

f:id:neet-utsu-taro:20171014140456p:plain

5000件取得
5000件取得
3707件取得

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014140924p:plain

日本のこころ

f:id:neet-utsu-taro:20171014200315p:plain

5000件取得
5000件取得
5000件取得
5000件取得
5000件取得
5000件取得
5000件取得
2913件取得
37913件追加しました。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014200447p:plain

自由党

f:id:neet-utsu-taro:20171014171911p:plain

5000件取得
5000件取得
5000件取得
5000件取得
5000件取得
3244件取得

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014172630p:plain

社民党

f:id:neet-utsu-taro:20171014173619p:plain

5000件取得
5000件取得
5000件取得
5000件取得
1649件取得

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014173815p:plain

共産党

f:id:neet-utsu-taro:20171014174204p:plain

5000件取得
5000件取得
5000件取得
5000件取得
5000件取得
1732件取得

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014174122p:plain

幸福実現党

f:id:neet-utsu-taro:20171014175100p:plain

5000件取得
1754件取得

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014175142p:plain

ソースコード

レートリミットへの対処を追加しました。

クリックしてソースコードを見る

まとめ

追加したフォロワーIDは

政党 件数
自民 124,328
公明 73,705
希望 10,607
民進 25,335
維新 13,707
立民 174,896
こころ 37,913
自由 28,244
社民 21,649
共産 36,732
幸福 6,754

です。プログラムで収集した時期の数ですので、今とは誤差があるかもしれません。政党に漏れがあった場合は教えてください。

終わりに

ようやくフォロワーのIDを取得できました!次はこのIDを元にユーザー情報をデータベースに追加したいと思います。

今もそのプログラムを作ってると思います。最近は特に良い記事を書けてなくてすいません。

またね('ω')ノ

Javaを使いデータをMongoDBに入れてみた

こんにちは、鬱太郎です。今日はプログラムからMongoDBにデータを入れる実験をしたので、それについてまとめたいと思います。

f:id:neet-utsu-taro:20171011211254j:plain

jarドライバーをダウンロードする

下記リンクからドライバーをダウンロードします。

MongoDB Java Driver

Index of /repositories/releases/org/mongodb/mongo-java-driver/3.5.0

mongo-java-driver-x.x.x.jarというものをダウンロードし、環境変数等に登録しておきましょう。私はEclipseの外部JARに追加しました。

f:id:neet-utsu-taro:20171014111651p:plain

f:id:neet-utsu-taro:20171014112055p:plainf:id:neet-utsu-taro:20171014112230p:plain

プログラムからMongoDBを検索する

  • MongoClient client = new MongoClient("localhost", 27017);で指定したアドレス、ポート番号で接続を確立させる。
  • MongoDatabase db = client.getDatabase("testdb");で指定したデータベースを使う。クライアントでのuse testdbと同じ
  • MongoCollection<Document> coll = db.getCollection("test");でコレクションを指定する。この変数に検索・追加等を行う場合はこのコレクションに行う。

特に特筆する点はありませんでした。Documentクラスは他のパッケージでも使われるため、org.bson.Documentという風に明示しておく必要があるくらいでしょうか?

実行結果は下のようになります。これまでにいろいろとデータを追加したりしていたので、汚れていますね…

8
Document{{_id=59ddaf21ee43c8a85e9dfea5, name=testinsert, message=hello mongodb, testv=org.bson.BsonUndefined@0, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb11dee43c8a85e9dfea6, name=ニート鬱太郎, message=テストメッセージ, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb5e19a2f587d7ea7001a, name=ニート鬱太郎, message=ストメッセージ, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb5ff9a2f587d7ea7001b, test=false, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb8879a2f587d7ea7001c, testname=tet, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb9c09a2f587d7ea7001d, id=9.0232311199491686E17, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddbd099a2f587d7ea7001e, created_at=Tue Aug 29 09:12:49 GMT+09:00 2017}}
Document{{_id=59ddbf9b9a2f587d7ea7001f, createdAt=Tue Oct 10 19:00:05 GMT+09:00 2017, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}

プログラムからMongoDBにデータを追加する

  • db.createCollection("test1");でデータベースにコレクションを追加します。
  • coll.insertOne(Document.parse(json));でコレクションにデータを追加します。

データを追加する際はorg.bson.Documentクラスとして追加する必要があります。文字列のJSONがある場合は下の例のようにDocument.parse(json)Document型に変換できます。

結果

> db.test1.find()
{ "_id" : ObjectId("59e17ea9ae898d27ec86e0e9"), "name" : "test", "value" : 111,"created_at" : "Sat Oct 14 12:04:09 GMT+09:00 2017" }

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014121148p:plain

Twitterの自分のユーザー情報を追加してみる

目的であるフォロワーの情報の取得の前に、自分のユーザー情報を追加してみます。

  • JSONObject json = new JSONObject(user);でユーザー情報のJSONを作ります。
  • coll.insertOne(Document.parse(json.toString()));でJSONの文字列からDocumentクラスに変換しMongoDBに追加します。

結果です

> db.test.find({},{_id:0,status:0})
{ "miniProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg", "screenName" : "neet_utsu_taro", "contributorsEnabled" : false, "profileUseBackgroundImage" : false, "profileBackgroundTiled" : false, "createdAt" : "Tue Aug 29 09:12:49 GMT+09:00 2017", "profileBackgroundImageURL" : "http://abs.twimg.com/images/themes/theme1/bg.png", "biggerProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg", "protected" : false, "miniProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg", "profileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg", "id" : NumberLong("902323111994916864"), "profileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg", "profileSidebarBorderColor" : "000000", "utcOffset" : -25200, "URLEntity" : { "displayURL" : "neetaro.com", "start" : 0, "end" : 23, "text" : "https://t.co/8tj7yW4gCF", "expandedURL" : "http://www.neetaro.com", "URL" : "https://t.co/8tj7yW4gCF" }, "timeZone" : "Pacific Time(US & Canada)", "defaultProfile" : false, "profileLinkColor" : "91D2FA", "originalProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg", "profileSidebarFillColor" : "000000", "rateLimitStatus" : { "limit" : 75, "secondsUntilReset" : 900, "remaining" : 74, "resetTimeInSeconds" :1507952068 }, "profileBannerMobileURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile", "name" : "ニート鬱太郎", "followersCount": 69, "followRequestSent" : false, "showAllInlineMedia" : false, "geoEnabled" :false, "profileBannerMobileRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile_retina", "translator" : false, "description" : "ニートです。どうでもいいこと言います。趣味アニメ等 だけども最近全く見てない。。。フォローされたら、bot等でない限りフォロー返します。  犬は柴犬、猫は黒猫が好き。  柴犬っていいよね…The犬って感じで _(:3」∠)_ ブログやってます。下のリンクからどうぞ。", "profileTextColor" : "000000", "descriptionURLEntities" : [ ], "URL" : "https://t.co/8tj7yW4gCF", "biggerProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg", "profileBannerIPadURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad", "lang" : "ja", "defaultProfileImage" : false, "statusesCount" : 192, "accessLevel" : 2, "profileBackgroundImageUrlHttps" : "https://abs.twimg.com/images/themes/theme1/bg.png", "profileBackgroundColor" : "000000", "verified" : false, "favouritesCount" : 218, "friendsCount" : 105, "listedCount" : 0, "profileBannerURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web", "location" : "自宅", "profileBannerRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web_retina", "originalProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg", "profileBannerIPadRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad_retina" }
>

希望の党のフォロワーIDを取得する

試しに、希望の党のフォロワーIDを取得してみます。TwitterAPIのfollowers/idsは15分に15回しかアクセスできません。1回に5000人のIDを取得します。

f:id:neet-utsu-taro:20171014124126p:plain

プログラムを作る前には10600人のフォロワーがいます。3回のアクセスで取得できますね。

プログラムの標準出力

5000件取得
5000件取得
607件取得

MongoDBの結果

> db.ki
db.kibounotou_ids  db.killOP(         db.killOp(
> db.kibounotou_ids.find({},{_id:0});
{ "user_id" : NumberLong(152582955) }
{ "user_id" : NumberLong("805586963134722048") }
{ "user_id" : NumberLong(207533598) }
{ "user_id" : NumberLong("2366735000") }
{ "user_id" : NumberLong("2578806756") }
{ "user_id" : NumberLong(101443148) }
{ "user_id" : NumberLong("2381150839") }
{ "user_id" : NumberLong("858242448211836928") }
{ "user_id" : NumberLong("853963341563285505") }
{ "user_id" : NumberLong(1895710039) }
{ "user_id" : NumberLong("919038152525758464") }
{ "user_id" : NumberLong("701664499904819200") }
{ "user_id" : NumberLong("4026560532") }
{ "user_id" : NumberLong("2401011818") }
{ "user_id" : NumberLong("3969213373") }
{ "user_id" : NumberLong(124797590) }
{ "user_id" : NumberLong(189854952) }
{ "user_id" : NumberLong(108766513) }
{ "user_id" : NumberLong("2328720366") }
{ "user_id" : NumberLong(1458820586) }
Type "it" for more
> db.kibounotou_ids.find({},{_id:0}).count();
10607
>

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014131304p:plain

10607人のユーザーIDを取得できました。私がプログラムを作っている間に7人のフォロワーが増えたようですね。

このユーザーIDはhttps://twitter.com/intent/user?user_id=の=の先につけることでそのユーザーの情報をブラウザでも見ることができます。ちなみに私の情報はhttps://twitter.com/intent/user?user_id=902323111994916864です。

まとめ

プログラムからMongoDBにデータを追加することができました!次はすべての政党のフォロワーのIDをデータベースに追加したいと思います。

その次に、追加したユーザーIDを元にユーザー情報を取得したいと思います。

またね('ω')ノ

次のHTMLタグを非表示表示できるjavascriptを作ってみた

こんにちは、鬱太郎です。先日あるものを作りました。

ここをクリック(タップ)してください

f:id:neet-utsu-taro:20170907193330j:plain

そう!クリックすると次のHTMLタグを表示非表示にできるプログラムを作りました。

あれ?デジャヴ・・・?

追記:改良型を作りましたこちらの記事をご覧ください

www.neetaro.com

次のタグ表示非表示モジュール(next-hidden.js)

名前は相変わらずです。そもそもhideとhiddenの違いや使い方もよくわかっていませんw

hideよりもhiddenの方がかっこいいよね!

何ができるかというと、

  • クリック(タップ)すると次のHTMLタグを非表示や表示できる
  • 最初から次のHTMLタグを非表示にするか表示したままかを選べる

この2点です。文章力なくてすみません。

前回のプログラムとの違い

www.neetaro.com

前回は見出し間を表示非表示にするものでした。今回のは、表示非表示させる部分を次のHTMLタグのみに限定することで、見出しだけでなく、すべてのタグにイベントを追加できるようになりました。

次のHTMLタグというのは親と子の関係でなく、兄弟の関係を指します。

<p class="next-hidden">ここをクリック</p>
<div>
 ....
</div>

上の例では<p><div>は兄弟関係にあります。<p>をクリックすると次のタグの<div>を表示非表示にできるイベントを<p>に追加します。

<div class="next-hidden">
  <p>あいうえお</p>
</div>
<ul>
 ...
</ul>

上の例では<div><p>は親子関係、<div><ul>は兄弟関係にあります。ですので、<div>をクリックすると<ul>を表示非表示にできるイベントを<div>に追加します。

動作デモ

pタグにイベントを追加して、次のpタグを隠す

<p>タグというのは文章を表示する際のタグですね。

<p class="next-hidden">ここをクリックすると、次のタグが表示非表示します</p>
<p>ちらっ |ω・`)</p>

ここをクリックすると、次のタグが表示非表示します

ちらっ |ω・`)

次の画像を表示非表示にさせるイベントを追加する

<p class="next-hidden"><a>ここをクリックして画像を見る</a></p>
<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/n/neet-utsu-taro/20170907/20170907193330.jpg" title="サンプル画像" class="hatena-fotolife" itemprop="image">

ここをクリックして画像を見る

Markdown記法の方はこのように簡単に書けます

<p class="next-hidden"><a>ここをクリックして画像を見る</a></p>
[f:id:neet-utsu-taro:20170907193330j:plain]

ここをクリックして画像を見る

f:id:neet-utsu-taro:20170907193330j:plain

次のli要素を隠す

<ul>
  <li>未経験者歓迎</li>
  <li class="next-hidden">福利厚生充実(クリックしちゃダメ)</li>
  <li>残業代なし</li>
  <li>笑顔の絶えない職場です</li>
</ul>
  • 未経験者歓迎
  • 福利厚生充実(クリックしちゃダメ)
  • 残業代なし
  • 笑顔の絶えない職場です

コードと使用例

実際の使い方を説明していきます。

1.スクリプトコードを記事に貼り付ける

次のコードを記事に貼り付けてください。最初の1行はjQueryの読み込みです。既にヘッダー等に記述してある方は必要ありません。

<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(function(){
    var classSelector = ".next-hidden";
    var attrForNext = "data-display";
    var attrNextClass = "data-next-class";
    var display ="display";
    var none="none";

    $(classSelector).each(function(){
        if($(this).next().length){
            var init = $(this).attr(attrForNext);
            $(this).next().css(display,(init)?init:none);
            $(this).click(function(){
                if($(this).next().css(display) == none){
                    $(this).next().show();
                }else{
                    $(this).next().hide();
                }
            });
            var nextClass = $(this).attr(attrNextClass);
            if(nextClass){
                $(this).next().addClass(nextClass);
            }            
        }
    })
})
</script>

2.イベントを登録したいタグにクラス名や属性を追加する

ソースコードをコピペした後は、タグにクラス名を付けるだけで機能します。

そのまま記法の方は、HTML編集ページから、Markdown記法の方は直接記述できます。

デフォルト動作の記述方法

class="next-hidden"を記述することで、そのタグに次のタグを表示非表示にさせるイベントを追加します。このとき、デフォルトで次のタグの要素を非表示にします。

<p class="next-hidden"><a>ここをクリック</a></p>
<p>タグに<code>class="next-hidden"</code>を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。</p>

ここをクリック

タグにclass="next-hidden"を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。

最初に次のタグを表示しておきたい場合

さらにdata-display="block"という属性を追記することで、初期状態を決定できます。

<p class="next-hidden" data-display="block"><a>ここをクリック</a></p>
<p>タグに<code>class="next-hidden" data-display="block"</code>を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。また、次のタグが表示されたまま読み込まれます。</p>

ここをクリック

タグにclass="next-hidden" data-display="block"を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。また、次のタグが表示されたまま読み込まれます。

次のタグにクラス名を付けたい場合

CSSなどで非表示にさせるタグにデザインを追加したい場合があるかもしれません。その場合はdata-next-class="hogehoge"の様に記述することで、クラス名が次のタグに追加されます。

<style>.hogehoge{background-color: gray;}</style>
<p class="next-hidden" data-next-class="hogehoge"><a>ここをクリック</a></p>
<p>タグに<code>class="next-hidden" data-display="block"</code>を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。また、次のタグが表示されたまま読み込まれます。</p>

ここをクリック

タグにclass="next-hidden" data-next-class="hogehoge"を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。また、次のタグにクラス名が追加されます。これを使ってデザインを変更できます。

上の例ではクラス名hogehogeに背景を灰色にするCSSを追加しています。

機能のまとめ

  • class="next-hidden"で機能を追加
  • 読み込み時はデフォルトで非表示。data-display="block"で読み込み時に表示
  • data-next-class="..."で次のタグにクラス名を追加

応用

基本的にどんなタグでも追加できる

基本的にはどんなタグでもイベントを追加できます。ただし、クリック(タップ)できるものでないとイベントは発生しません。

<div class="next-hidden"></div>
<p>ここが隠れます</p>

ここが隠れます

この場合でも正常にイベントが追加されますが、ユーザーが<div>タグをクリック(タップ)できないため表示非表示をさせることができません。

CSSなどを駆使して、ユーザーがクリック(タップ)できるサイズにする必要があります。

<div class="next-hidden" style="width:30px;height:30px;background-color:blue;"></div>
<p>ここが隠れます</p>

ここが隠れます

上記の例は<div>にサイズを設定して、色を付けました。青色の部分をクリックするとイベントが発生し、下のタグが表示・非表示されます。

複数のタグを表示・非表示にさせる

このプログラムは次のタグだけしか表示・非表示にできません。

<p class="next-hidden"><a>募集要項はこちら</a></p>
<p>具体的な内容を下に並べました。</p>
<ul>
  <li>未経験者歓迎</li>
  <li class="next-hidden">福利厚生充実(クリックしちゃダメ)</li>
  <li>残業代なし</li>
  <li>笑顔の絶えない職場です</li>
</ul>
<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/n/neet-utsu-taro/20170907/20170907193330.jpg" title="サンプル画像" class="hatena-fotolife" itemprop="image" width="200" height="200">

募集要項はこちら

具体的な内容を下に並べました。

  • 未経験者歓迎
  • 福利厚生充実(クリックしちゃダメ)
  • 残業代なし
  • 笑顔の絶えない職場です

本当は画像まですべて非表示にさせたいと思っても、そのままでは次のタグしか非表示にできません。

しかし、<div>で囲むとまとめて非表示にできます。

<p class="next-hidden"><a>募集要項はこちら</a></p>
<div>
  <p>具体的な内容を下に並べました。</p>
  <ul>
    <li>未経験者歓迎</li>
    <li class="next-hidden">福利厚生充実(クリックしちゃダメ)</li>
    <li>残業代なし</li>
    <li>笑顔の絶えない職場です</li>
  </ul>
  <img src="https://cdn-ak.f.st-hatena.com/images/fotolife/n/neet-utsu-taro/20170907/20170907193330.jpg" title="サンプル画像" class="hatena-fotolife" itemprop="image" width="200" height="200">
</div>

募集要項はこちら

具体的な内容を下に並べました。

  • 未経験者歓迎
  • 福利厚生充実(クリックしちゃダメ)
  • 残業代なし
  • 笑顔の絶えない職場です

終わりに

ここまで読んでくださってありがとうございます!

前回の見出し間の表示非表示プログラムよりも、汎用性は高いかなと思います。前回のは見出しが不必要に増えてしまうため、目次等が荒れてしまいました(´;ω;`)。今回はすべてのタグに追加できるものなので、見出しにする必要もありません。好きなタグに追加しましょう!

興味のある方はぜひこのスクリプトで遊んでください!私が発情した犬のようにソーラン節を踊りまくりつつ喜びます。

読者登録ありがとうございます。スターやブックマーク、コメント等もありがとうございます!励みになってます。

またね('ω')ノ

追記:改良型を作りましたこちらの記事をご覧ください

www.neetaro.com

Mongodbで元のデータを使いUpdateする方法

Mongodbを使っているとある列(プロパティ)の値を元にUpdateをしたい時ってありますよね?

UPDATE table SET fugafuga = fugafuga+3;

SQLだとこんな感じのやつです(SQLの知識があまりないため、間違ってたらごめんなさい)。この場合ですと、Mongodbには$incというものがあり、db.collection.update()を使って更新することができます。

しかし、こんな場合はどうでしょうか?

UPDATE table SET name_size = length(name);

このように、name列の文字列の長さを元に、Updateをしたい。このような複雑な更新をMongodbでしようと思ってドキュメントを探しても、見つかりませんでした。もしかしたら、見逃しているかもしれませんが。

Mongodbのコレクションのデータをもとに、そのコレクションを更新する方法を見つけましたので、紹介したいと思います。

f:id:neet-utsu-taro:20171011211254j:plain

海外の方が解決策を載せてくれてました

stackoverflow.com

色々検索してみると、次のような文章を見つけました。

Update: If all you have to do is change the structure of a document without changing the values, see gipset's answer for a nice solution.

According to a (now unavailable) comment on the Update documentation page, you cannot reference the current document's properties from within an update().

You'll have to iterate through all the documents and update them like this:


db.events.find().snapshot().forEach(
  function (e) {
    // update document, using its own properties
    e.coords = { lat: e.lat, lon: e.lon };

    // remove old properties
    delete e.lat;
    delete e.lon;

    // save the updated document
    db.events.save(e);
  }
)

Such a function can also be used in a map-reduce job or a server-side db.eval() job, depending on your needs.

これをGoogle翻訳で日本語にすると、

更新:値を変更せずにドキュメントの構造を変更するだけで済む場合は、素晴らしい解決策のgipsetの答えをご覧ください。

Update documentationページの(現在利用できない)コメントによれば、update()内から現在のドキュメントのプロパティを参照することはできません。

すべてのドキュメントを繰り返して、次のように更新する必要があります:


db.events.find().snapshot().forEach(
  function (e) {
    // update document, using its own properties
    e.coords = { lat: e.lat, lon: e.lon };

    // remove old properties
    delete e.lat;
    delete e.lon;

    // save the updated document
    db.events.save(e);
  }
)

このような関数は、必要に応じてmap-reduceジョブまたはサーバー側のdb.eval()ジョブでも使用できます。

一般化してみる

先ほどの例は少し特殊な例です。既にある列lat,lonからオブジェクトを作り、それを更新したいという内容でした。ついでに元からある二つの列を削除しようという事です。

これを一般化してみます。

SQLだとUPDATE table SET value = value + 200;とするUpdate文をmongodbでは

db.collection.find().snapshot().forEach(
  function(e){
    e.value = e.value+200;
    db.collection.save(e);
  }
)

と表せます。つまり、

db.コレクション名.find({更新したいデータの条件指定}).snapshot().forEach(
  function(e){
  //Updateしたい内容
  db.コレクション名.save(e);
  }
)

ですね!

データを使って実際に試してみる

こんなデータがあるとします。

> db.coll1.find({},{_id:0});
{ "name" : "山田", "value" : 101, "text" : "リンゴ" }
{ "name" : "田中", "value" : 102, "text" : "バナナ" }
{ "name" : "加藤", "value" : 103, "text" : "グレープフルーツ" }
{ "name" : "佐藤", "value" : 104, "text" : "キウイフルーツ" }
{ "name" : "武田", "value" : 105, "text" : "スイカ" }

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171012141455p:plain

バックアップを取る

db.collection.copyTo(newCollection)でコレクションをコピーできます。

> db.coll1.copyTo("coll1bak")
WARNING: db.eval is deprecated
5

中身を確認すると同じものが入っていますね!

> db.coll1bak.find({},{_id:0})
{ "name" : "山田", "value" : 101, "text" : "リンゴ" }
{ "name" : "田中", "value" : 102, "text" : "バナナ" }
{ "name" : "加藤", "value" : 103, "text" : "グレープフルーツ" }
{ "name" : "佐藤", "value" : 104, "text" : "キウイフルーツ" }
{ "name" : "武田", "value" : 105, "text" : "スイカ" }

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171012142447p:plain f:id:neet-utsu-taro:20171012142713p:plain

プロパティを加算

プロパティvalueの値に100を加算するUpdateをしてみましょう。

db.coll1.find().snapshot().forEach(
  function(e){
    e.value = e.value+100;
    db.coll1.save(e);
  }
)

一般化したものから、コードを書くとこんな風になります。

> db.coll1.find().snapshot().forEach(
... function(e){
... e.value = e.value+100;
... db.coll1.save(e);
... }
... )
> db.coll1.find({},{_id:0})
{ "name" : "山田", "value" : 201, "text" : "リンゴ" }
{ "name" : "田中", "value" : 202, "text" : "バナナ" }
{ "name" : "加藤", "value" : 203, "text" : "グレープフルーツ" }
{ "name" : "佐藤", "value" : 204, "text" : "キウイフルーツ" }
{ "name" : "武田", "value" : 205, "text" : "スイカ" }

実行に成功すると、何も出力しませんでした。その後、find()で検索すると、確かにvalueの値が+100されていることが分かります。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171012143810p:plain

指定した範囲だけUpdate

SQLで言うWhile句のようなものを使い更新してみましょう。

value>202のデータに新たにプロパティisGT202を追加し、値にtrueを追加してみます。

db.coll1.find({value:{$gt:202}}).snapshot().forEach(
  function(e){
    e.isGT202 = true;
    db.coll1.save(e);
  }
)

結果は、

> db.coll1.find({},{_id:0});
{ "name" : "山田", "value" : 201, "text" : "リンゴ" }
{ "name" : "田中", "value" : 202, "text" : "バナナ" }
{ "name" : "加藤", "value" : 203, "text" : "グレープフルーツ", "isGT202" : true }
{ "name" : "佐藤", "value" : 204, "text" : "キウイフルーツ", "isGT202" : true }
{ "name" : "武田", "value" : 205, "text" : "スイカ", "isGT202" : true }

となりました。valueが202よりも大きいデータに新しいプロパティが追加されてますね。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171012154225p:plain

複雑な範囲指定をしてUpdate

先ほどのようにfind()を使って絞り込みができる場合はそれでいいのですが、もっと複雑な検索条件を元にUpdateしたいという場合もあるでしょう。

その場合は直接function()の中身にif文を追加します。

textの文字列の長さが4以上のデータにプロパティtext_lengthを追加して、値にtextの文字列の長さを追加してみます。

db.coll1.find().snapshot().forEach(
  function(e){
    if(e.text.length >=4){
      e.text_length = e.text.length;
      db.coll1.save(e);
    }
  }
)

その結果は

> db.coll1.find({},{_id:0,isGT202:0})
{ "name" : "山田", "value" : 201, "text" : "リンゴ" }
{ "name" : "田中", "value" : 202, "text" : "バナナ" }
{ "name" : "加藤", "value" : 203, "text" : "グレープフルーツ", "text_length" : 8 }
{ "name" : "佐藤", "value" : 204, "text" : "キウイフルーツ", "text_length" : 7 }
{ "name" : "武田", "value" : 205, "text" : "スイカ" }

となります。文字列の長さが4以上にデータが追加されていることが分かります。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171012155227p:plain

あれ?find()の部分で条件指定しなくても、function()の中でif文使えばすべてできそう…

とは言ったものの、find()の検索はMongoDBの方で最適化されていると思います。find()で条件指定ができる部分はできるだけした方がいいかもしれません。

文字列の日付からオブジェクトの日付に更新する

一度文字列で入れてしまった日付をオブジェクトの日付として置き換えます。

> db.coll2.find({},{_id:0})
{ "createdAt" : "Mon Oct 09 11:26:20 GMT+09:00 2017" }
{ "createdAt" : "Mon Oct 09 19:27:09 GMT+09:00 2017" }
{ "createdAt" : "Mon Oct 02 17:00:42 GMT+09:00 2017" }
{ "createdAt" : "Tue Aug 29 09:12:49 GMT+09:00 2017" }

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171012160540p:plain

Twitterのデータを直接入れると、文字列で格納されてしまうため、日付同士の比較がしにくいですよね。

ですので、オブジェクトの日付に更新しましょう。

db.coll2.find().snapshot().forEach(
  function(e){
    e.createdAt = new Date(e.createdAt);
    db.coll2.save(e);
  }
)

これを実行すると

> db.coll2.find({},{_id:0})
{ "createdAt" : ISODate("2017-10-09T02:26:20Z") }
{ "createdAt" : ISODate("2017-10-09T10:27:09Z") }
{ "createdAt" : ISODate("2017-10-02T08:00:42Z") }
{ "createdAt" : ISODate("2017-08-29T00:12:49Z") }

ISODateというオブジェクトデータに変わります。ISODataにすると、日本時間を-9時間した標準時間で表記されます。元のデータと違う!という風に焦らないでください。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171012161408p:plain

まとめ

MongoDBの更新はdb.collection.update()だけでなく、次のようにすることもできます。

db.collection.find().snapshot().forEach(
  function(e){
    //更新処理 
    db.collection.save(e);
  }
)

function()の中身ではif文を使いさらに条件を絞り込んだり、javascriptのコードを使ってデータを操作できます。

データを更新する際は、db.collection.copyTo(newCollection)等でバックアップを取りましょう!

終わりに

ここまで読んでくださってありがとうございます!

今日もプログラムの話で興味のない方には申し訳ないです。

読者登録、スター、ブックマーク、コメント等ありがとうございます!すごい励みになってます!

またね('ω')ノ

MongoDBをインストールしてみた

こんにちは、鬱太郎です。先日Twitterのユーザー情報からフォロワーについて調べてみました。

www.neetaro.com

その時に、フォロワーを5000人だけでなくすべてのデータを取得してみようと思いました。そのためにはデータベースを使う必要があります。どんなデータベースがあるのかを色々と調べて、MongoDBを使う事を決めました。

今日はそのMongoDBのインストール方法についてご紹介したいと思います。

f:id:neet-utsu-taro:20171011211254j:plain

MongoDBとは

MongoDBはNoSQLデータベースの一つです。RDBMS(MySQLやPostgreSQL)のようにあらかじめ、データの形式を決めておく必要がありません。またJSON形式を取り扱うことが容易です。

MongoDBはRDBMSではなく、いわゆるNoSQLと呼ばれるデータベースに分類されるものである。RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する(このデータの物理的な格納はBSONと呼ばれるJSONのバイナリ版といえる形式で行われる)。コレクションはRDBMSのような固定的なスキーマを持たない。ドキュメントには複雑な階層構造を持たせることもでき、それらの構造に含まれるフィールドを指定したクエリやインデクス生成も簡単な指定によって行える。RDBMSのように高度な結合操作を効率的に行うことはできないが、データの追加・更新・削除・クエリは高速に行うことができる。また、アプリケーションは自身の構造やデータ型に合った自然な形でデータを格納することができるため、扱うデータの特性によっては、RDBMSよりも容易かつ迅速に開発を行える可能性がある。

MongoDB - Wikipedia

MongoDBを選んだ理由

MongoDBを選んだ理由は、

  • JSONをそのままinsertできる
  • あらかじめテーブル等を定義しなくてよい

などです。TwitterAPIはJSON形式でデータをやり取りしています。MongoDBはそのままJSONを追加できるので、今回最も適しているのかなと思いました。初めて勉強するなら、MySQLやPostgreSQLなどの難しいものよりも、データのやり取りが楽な方がいいと思ったからです。

先にJSONの全プロパティをテーブルに定義させるのは大変でしょう…

参考

qiita.com

ありがとうございます!

MongoDBをダウンロードする

MongoDB Download Center | MongoDB

上記公式サイトからmsiファイルをダウンロードします。

タブを選んでmsiファイルをダウンロードしましょう

MongoDBをインストールする

ダウンロードしたmsiファイルを実行してインストールしましょう。

環境変数を登録

mongomongodがある場所を環境変数に登録します。

Windowsボタン+Rでファイル名を指定して実行が出るので、sysdm.cplを入力して実行しましょう。

sysdm.cplを入力して、OKを押します

システムのプロパティの詳細設定タブの環境変数を選択します。

詳細設定タブの環境変数を選択します

Path変数にmongomongodのフォルダへのパスを末尾に追加します。

私の場合はC:\Program Files\MongoDB\Server\3.4\binでした。

末尾に追加する際に区切り文字の;を必ず追加してから上記パスを入力してください。

;C:\Program Files\MongoDB\Server\x.x\binですね

区切り文字を入力してから、フォルダへのパスを入力します。

実行

MongoDBをインストールしたので、実行してみましょう。

環境変数の登録確認

コマンドプロンプトを開きましょう。ファイル名を指定して実行からcmdで開きます。

cmdでコマンドプロンプトが起動します

先ほどの環境変数が登録できているかを確認します。

mongo --version

および

mongod --version

を入力しましょう。 環境変数の登録ができているかを確認します

環境変数の登録ができている場合はバージョン情報が表示されます。

サーバーの実行

環境変数の登録が住んでることも確認できたので、サーバーを立ち上げます。

コマンドプロンプトでmongodを実行しましょう。--dbpath--logpathでデータベースの場所やログの生成場所を選択できます。

mongod --dbpath ... --logpath ...

このとき指定した--dbpath--logpathのフォルダがないと、下のようにエラーが出ます。

[main] Failed global initialization: FileNotOpen: Failed to open ...

このようなエラーが出た場合は指定したフォルダを作成しましょう。もしくはアクセス制限を追加しましょう。

mongodを実行すると、何も起きませんが内部でサーバーが立ち上がります

mongodを実行するとファイアウォールのアクセス許可を聞いてくるので許可しましょう。

アクセス許可をしましょう

実行が完了すると、表面上は何も動きません。しかし、正しくサーバーは立ち上がっています。

このコマンドプロンプトは閉じずにそのままにしておきます

クライアントからデータベースにアクセス

サーバーも立ち上がったので、クライアントを使いアクセスしてみましょう。

別のコマンドプロンプトを起動しmongoを入力します。

mongoを入力するとクライアントが起動します

show dbs

と入力してみましょう

f:id:neet-utsu-taro:20171011142618p:plain

まだ何も使ってないので、0GBとなっていますね。

MongoDBにデータを追加

mongoターミナルから

use testdb

を入力しましょう。

すると

switched to db testdb

というメッセージが出ます。これから追加(検索)するデータはすべてtestdbの中に追加しますという事ですね。

f:id:neet-utsu-taro:20171011143610p:plain

コレクションの追加

コレクションとはデータベースに対するテーブルのようなものです。

db.createCollection("test")

testコレクションを追加します。

f:id:neet-utsu-taro:20171011143746p:plain

また、コマンドの入力の途中でTabキーを押すと、コマンドの候補が出現します。便利ですね。

{ "ok" : 1 }

という内容が出たら、成功です。

show collections
test

のようにコレクションが追加されたことが分かります。

クリックしてコマンドプロンプトの結果を見る

f:id:neet-utsu-taro:20171011143907p:plain

f:id:neet-utsu-taro:20171011144036p:plain

データを追加する

db.コレクション名.insert({})

で、データを追加できます。

db.test.insert({name:"testinsert",message:"hello mongodb"});

を追加してみましょう。追加する内容はJSON形式で記述する必要があります。

{プロパティ名1:値1,プロパティ名2:値2,...}といった感じですね。値は文字列の場合は"'で囲まないといけません。

追加に成功すると

WriteResult({"nInserted":1})

と出力されます。

クリックしてコマンドプロンプトの結果を見る

f:id:neet-utsu-taro:20171011144206p:plain

データを検索する

db.コレクション名.find({条件指定},{表示指定})

で指定されたコレクションの中身を検索できます。表示指定の部分は省略できます。また、無条件で検索する(すべての内容を表示)場合は条件指定も省略できます。

db.test.find();

この場合はすべての内容を表示させます。select * from testのような感じでしょうか?

条件を指定して検索する場合は

db.test.find({name:"testinsert"});

のようにします。

詳しくは、公式のドキュメントに載っています。

db.collection.find() — MongoDB Manual 3.4

クリックしてコマンドプロンプトの結果を見る

f:id:neet-utsu-taro:20171011144359p:plain

f:id:neet-utsu-taro:20171011144509p:plain

終了

クライアントの終了

クライアントはexitコマンドで終了できます。

>exit
bye

サーバーの終了

サーバーはCtrl+Cで終了できます。

終わりに

ここまで読んでくださってありがとうございます!

プログラムに興味のない方には申し訳ありません!ほーんと流し目で見ていただけたらなと思います。

次はプログラムからデータベースに追加しようと思います。

またね('ω')ノ

早朝散歩に行ってきました3

こんにちは、鬱太郎です。今日は早朝散歩に行ってきたので、それについてと先日の記事のコメント返しをしたいなと思います。

散歩してきた(オチなし)

ただ、散歩してきただけですw

今日は朝の5時10分から6時頃まで散歩してきました。

散歩に出かけると、外は真っ暗でした

散歩に出かけると、外は真っ暗でした。写真を撮るのが下手で申し訳ないです。暗すぎて、画質がものすごい悪くなってる( ゚Д゚)

散歩往路での空の風景です

散歩中だんだんと空が明るくなってくるのがいいですよね!早朝散歩の醍醐味です。

川の遊歩道についたら、突然変な物音が!ビビりな私が恐る恐る見てみると、魚が水面から口を出したりして泳いでる音でした。

何の音かと思ったら魚が水面から口を出す音でした。

途中、物音や通行人などにびくつきながら歩いていくと、向こう側の川岸に白鷺のような足の細長い鳥がいました。写真を撮ろうとしたら飛び立って離れていったよ…

恐るべし野生の感('ω')

ちょっとすると上空を旋回して先ほどの川岸の近くの家の屋根の上にとまりました。

川岸にいた鳥が上空を旋回して家の屋根の上にとまりました

アヒルのような「ぐうぁー」という鳴き声をしていました。どういった種類の鳥なんでしょうね?

散歩も中盤に差し掛かり、だんだん空が明るくなってきました!

だんだん空が明るくなってきました!

綺麗でいいですよね!

帰路にも鳥発見!画像粗くてすいません…(´;ω;`)

これ以上近づくと逃げてしまいました

しかし、近づくとすぐに飛び立って上空を旋回します。別の場所に行かず、上空を旋回して家の屋根の上にとまるという事は何か縄張りでもあるのかもしれません。

そして帰宅時の空

散歩の終わりにはもう空は明るくなってきました

だいぶ明るくなってきましたね!

今日も1日頑張りましょう!(もう夜ですが…)

今日は今までと違い約20分ほど早く家を出ました。そのせいもあってか、通行人もほとんどおらず、のびのびと散歩できました。これをできるだけ習慣づけたいと思います。

コメント返し

www.neetaro.com

昨日の記事についてコメントを返したいと思います。

Twitter4jを使い立憲民主党のフォロワーについて調べてみた - ニートが学ぶプログラミング

面白い分析ですね〜

2017/10/09 22:26
Twitter4jを使い立憲民主党のフォロワーについて調べてみた - ニートが学ぶプログラミング

素晴らしい分析です。こんな風に使えるのですね。

2017/10/09 23:18
Twitter4jを使い立憲民主党のフォロワーについて調べてみた - ニートが学ぶプログラミング

こんなことできるんですね!すごいですΣ(・□・;)

2017/10/10 00:45
Twitter4jを使い立憲民主党のフォロワーについて調べてみた - ニートが学ぶプログラミング

twitter4すげぇ(小並感

2017/10/10 07:53

コメントありがとうございます!

これから各政党のフォロワーをすべて取得してみて分析しようと思います。ただ、いろいろと知識が足りないもので多少時間がかかるかもしれません。頑張ります!

Twitter4jを使い立憲民主党のフォロワーについて調べてみた - ニートが学ぶプログラミング

1.http://bit.ly/2y3HnEl のように直近で謎のフォロワー傾向変動が起きているため誤差が出ている 2. 1と同様だがサンプル採取区間に偏りがあるため統計として不適当 3.他党など対照サンプルの数値が不明なので結論がおかしい

2017/10/10 00:03

コメントありがとうございます!

1および2は私も気になっていたところです。どうやらfolloweridsのリクエストは最新のものから5000人を取得するようです1

3は同じ条件(フォロワーを最新のものから5000人取得)で別政党を比べてみました。といっても自民党、公明党、希望の党だけですが。昨日の記事を更新しましたので、ぜひご覧になってください。

これからすべてのデータの取得をしてみようかなと思います、時間がかかると思いますが、その時になったらまた記事を書きますね。

こういったデータを取り扱うのは初めてなので、いろいろと勉強しながら頑張っていきます。

終わりに

ここまで読んでくださってありがとうございます!

今日はまったりと散歩の記事にしました。

(裏でどうやってデータを集めようかやプログラムの構想を考えています)

読者登録、ブックマークやスター等いつもありがとうございます。すごく励みになってます。

またね('ω')ノ

Twitter4jを使い立憲民主党のフォロワーについて調べてみた

こんにちは、鬱太郎です。最近立憲民主党のフォロワーが急激に増加したせいで、フォロワーを買ったんじゃないかという疑惑が上がりましたよね?

今日はTwitter APIとtwitter4jを使ってツイートやユーザー情報を取得してみようと思います。

Twitterでアプリ登録をする

apps.twitter.com

上記公式サイトからアプリ登録をしましょう。

f:id:neet-utsu-taro:20171009210633p:plain

Create New Appから新しいアプリを登録しましょう。

f:id:neet-utsu-taro:20171009210930p:plain

必要事項を記入して、登録を済ませましょう。

携帯認証を済ませていないアカウントではアプリ登録はできません!携帯認証を済ませましょう。

f:id:neet-utsu-taro:20171009210741p:plain

アプリ登録が完了すると、ConsumerKeyというのが発行されます。それと合わせて、keys and Access TokensタブからAccess Tokenを取得しておきましょう。

twitter4jをダウンロードする

Twitter4J - A Java library for the Twitter API

上記公式サイトからダウンロードしましょう。ダウンロードしたlibファイルを使います。

f:id:neet-utsu-taro:20171009211352p:plain

これらのlibファイルを環境変数等に登録しておきましょう。私はeclipseに追加しました。

f:id:neet-utsu-taro:20171009211515p:plain:h400

自分の情報を取得してみる

twitter4jの詳しい使い方は公式サイトやjavadocにあります。

自分の情報を取得するには、Twitter::verifyCredentials()を使います。

JSON=UserJSONImpl{id=902323111994916864, name='ニート鬱太郎', screenName='neet_utsu_taro', location='自宅', description='ニートです。どうでもいいこと言います。趣味アニメ等 だけども最近全く見てない。。。 フォローされたら、bot等でない限りフォロー返します。  犬は柴犬、猫は黒猫が好き。  柴犬っていいよね…The犬って感じで _(:3」∠)_ ブログやってます。下のリンクからどうぞ。', isContributorsEnabled=false, profileImageUrl='http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg', profileImageUrlHttps='https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg', isDefaultProfileImage=false, url='https://t.co/8tj7yW4gCF', isProtected=false, followersCount=66, status=StatusJSONImpl{createdAt=Mon Oct 09 11:26:20 GMT+09:00 2017, id=917214617541124096, text='プログラム組んでるとTwitterするの忘れてしまう…😱😱', source='<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=1, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=0, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[], urlEntities=[], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=-1, quotedStatus=null}, profileBackgroundColor='000000', profileTextColor='000000', profileLinkColor='91D2FA', profileSidebarFillColor='000000', profileSidebarBorderColor='000000', profileUseBackgroundImage=false, isDefaultProfile=false, showAllInlineMedia=false, friendsCount=102, createdAt=Tue Aug 29 09:12:49 GMT+09:00 2017, favouritesCount=204, utcOffset=-25200, timeZone='Pacific Time (US & Canada)', profileBackgroundImageUrl='http://abs.twimg.com/images/themes/theme1/bg.png', profileBackgroundImageUrlHttps='https://abs.twimg.com/images/themes/theme1/bg.png', profileBackgroundTiled=false, lang='ja', statusesCount=173, isGeoEnabled=false, isVerified=false, translator=false, listedCount=0, isFollowRequestSent=false, withheldInCountries=null}
ツイート数=173
フォロワー数=66
フォロー数=102
いいね数=204
アカウント作成日=Tue Aug 29 09:12:49 GMT+09:00 2017
最近のツイートJSON=StatusJSONImpl{createdAt=Mon Oct 09 11:26:20 GMT+09:00 2017, id=917214617541124096, text='プログラム組んでるとTwitterするの忘れてしまう…😱😱', source='<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=1, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=0, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[], urlEntities=[], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=-1, quotedStatus=null}
最近のツイート本文=プログラム組んでるとTwitterするの忘れてしまう…😱😱
最近のツイート日時=Mon Oct 09 11:26:20 GMT+09:00 2017

本題の立憲民主党を取得してみる

自分のアカウントだけでなく、他のユーザの情報も取得できます。

Twitter::showUser()を使うと対象のユーザー情報がJSON形式で取得できます。

UserJSONImpl{id=914762049481084929, name='立憲民主党', screenName='CDP2017', location='', description='立憲民主党公式アカウントです。 代表 枝野幸男 @edanoyukio0531 選挙公約 https://t.co/aPeWMDlGNE', isContributorsEnabled=false, profileImageUrl='http://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', profileImageUrlHttps='https://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', isDefaultProfileImage=false, url='https://t.co/QuM59HT4pJ', isProtected=false, followersCount=169816, status=StatusJSONImpl{createdAt=Mon Oct 09 19:27:09 GMT+09:00 2017, id=917335619180699648, text='比例中国に秋葉前広島市長=立憲民主、候補78人に【17衆院選】:時事ドットコム https://t.co/kcPLVejs9b @jijicomさんから', source='<a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=392, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=231, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[UserMentionEntityJSONImpl{name='時事ドットコム', screenName='jijicom', id=143383314}], urlEntities=[URLEntityJSONImpl{url='https://t.co/kcPLVejs9b', expandedURL='https://www.jiji.com/jc/article?k=2017100900358&g=pol', displayURL='jiji.com/jc/article?k=2…'}], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=-1, quotedStatus=null}, profileBackgroundColor='F5F8FA', profileTextColor='333333', profileLinkColor='1DA1F2', profileSidebarFillColor='DDEEF6', profileSidebarBorderColor='C0DEED', profileUseBackgroundImage=true, isDefaultProfile=true, showAllInlineMedia=false, friendsCount=52, createdAt=Mon Oct 02 17:00:42 GMT+09:00 2017, favouritesCount=562, utcOffset=32400, timeZone='Tokyo', profileBackgroundImageUrl='null', profileBackgroundImageUrlHttps='null', profileBackgroundTiled=false, lang='ja', statusesCount=293, isGeoEnabled=false, isVerified=true, translator=false, listedCount=1616, isFollowRequestSent=false, withheldInCountries=null}

立憲民主党のフォロワーを調べてみる

立憲民主党のユーザーIDが分かったので、そこからフォロワーを取得することができます。

フォロワーを5000人取り出し、ツイート数を調べてみる

フォロワーはTwitter::getFollowersIDs()で取得できます。

実行結果がとても長いので見出しをクリックして見てください。もう一度見出しをクリックすると閉じます。

↓↓をクリックで結果が開きますもう一度クリックで閉じます

クリックして結果を見る

UserJSONImpl{id=914762049481084929, name='立憲民主党', screenName='CDP2017', location='', description='立憲民主党公式アカウントです。 代表 枝野幸男 @edanoyukio0531 選挙公約 https://t.co/aPeWMDlGNE', isContributorsEnabled=false, profileImageUrl='http://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', profileImageUrlHttps='https://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', isDefaultProfileImage=false, url='https://t.co/QuM59HT4pJ', isProtected=false, followersCount=169974, status=StatusJSONImpl{createdAt=Mon Oct 09 20:09:56 GMT+09:00 2017, id=917346386898706432, text='ありがとうございます!! https://t.co/2EgBMtM1gj', source='<a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=233, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=101, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[], urlEntities=[URLEntityJSONImpl{url='https://t.co/2EgBMtM1gj', expandedURL='https://twitter.com/sejiouen/status/917336855242170368', displayURL='twitter.com/sejiouen/statu…'}], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=917336855242170368, quotedStatus=null}, profileBackgroundColor='F5F8FA', profileTextColor='333333', profileLinkColor='1DA1F2', profileSidebarFillColor='DDEEF6', profileSidebarBorderColor='C0DEED', profileUseBackgroundImage=true, isDefaultProfile=true, showAllInlineMedia=false, friendsCount=52, createdAt=Mon Oct 02 17:00:42 GMT+09:00 2017, favouritesCount=562, utcOffset=32400, timeZone='Tokyo', profileBackgroundImageUrl='null', profileBackgroundImageUrlHttps='null', profileBackgroundTiled=false, lang='ja', statusesCount=294, isGeoEnabled=false, isVerified=true, translator=false, listedCount=1622, isFollowRequestSent=false, withheldInCountries=null}
5000件のフォロワーを取得しました。
50パックに小分けしました。
5000件のフォロワー情報を取得しました。立憲民主党のフォロワー5000人のツイート数の分布は
ツイート数 0 : 3667人
ツイート数 10241 : 1人
ツイート数 1 : 93人
ツイート数 4098 : 1人
ツイート数 2 : 67人
ツイート数 3 : 20人
ツイート数 4 : 30人
ツイート数 5 : 14人
ツイート数 6 : 23人
ツイート数 7 : 13人
ツイート数 8 : 9人
ツイート数 6153 : 1人
ツイート数 9 : 7人
ツイート数 10 : 11人
ツイート数 11 : 8人
ツイート数 26636 : 1人
ツイート数 12 : 9人
ツイート数 13 : 5人
ツイート数 14 : 5人
ツイート数 2063 : 1人
ツイート数 15 : 8人
ツイート数 16 : 8人
ツイート数 17 : 6人
ツイート数 18 : 9人
ツイート数 19 : 4人
ツイート数 4116 : 1人
ツイート数 20 : 6人
ツイート数 21 : 2人
ツイート数 14358 : 1人
ツイート数 6166 : 1人
ツイート数 22 : 6人
ツイート数 23 : 4人
ツイート数 24 : 7人
ツイート数 25 : 4人
ツイート数 26 : 1人
ツイート数 6171 : 1人
ツイート数 27 : 2人
ツイート数 28 : 6人
ツイート数 29 : 3人
ツイート数 30 : 3人
ツイート数 77854 : 1人
ツイート数 6175 : 1人
ツイート数 31 : 1人
ツイート数 32 : 2人
ツイート数 2081 : 1人
ツイート数 33 : 5人
ツイート数 2082 : 1人
ツイート数 34 : 1人
ツイート数 35 : 7人
ツイート数 36 : 2人
ツイート数 37 : 2人
ツイート数 38 : 2人
ツイート数 2087 : 2人
ツイート数 39 : 3人
ツイート数 40 : 2人
ツイート数 41 : 1人
ツイート数 42 : 3人
ツイート数 43 : 5人
ツイート数 44 : 2人
ツイート数 45 : 4人
ツイート数 46 : 2人
ツイート数 47 : 1人
ツイート数 48 : 1人
ツイート数 49 : 2人
ツイート数 2098 : 1人
ツイート数 50 : 2人
ツイート数 51 : 1人
ツイート数 8244 : 1人
ツイート数 52 : 2人
ツイート数 55 : 2人
ツイート数 55352 : 1人
ツイート数 57 : 3人
ツイート数 58 : 1人
ツイート数 59 : 1人
ツイート数 60 : 4人
ツイート数 61 : 1人
ツイート数 62 : 3人
ツイート数 64 : 2人
ツイート数 8257 : 1人
ツイート数 65 : 2人
ツイート数 66 : 2人
ツイート数 161857 : 1人
ツイート数 68 : 2人
ツイート数 6213 : 1人
ツイート数 70 : 2人
ツイート数 72 : 3人
ツイート数 73 : 6人
ツイート数 8267 : 1人
ツイート数 76 : 1人
ツイート数 32845 : 1人
ツイート数 77 : 1人
ツイート数 78 : 1人
ツイート数 79 : 2人
ツイート数 81 : 2人
ツイート数 82 : 1人
ツイート数 83 : 2人
ツイート数 6228 : 1人
ツイート数 85 : 1人
ツイート数 43096 : 1人
ツイート数 89 : 1人
ツイート数 91 : 2人
ツイート数 95 : 3人
ツイート数 96 : 2人
ツイート数 98 : 3人
ツイート数 102 : 4人
ツイート数 103 : 1人
ツイート数 104 : 1人
ツイート数 105 : 1人
ツイート数 108 : 1人
ツイート数 4205 : 1人
ツイート数 109 : 1人
ツイート数 110 : 2人
ツイート数 111 : 2人
ツイート数 113 : 1人
ツイート数 115 : 1人
ツイート数 2164 : 1人
ツイート数 116 : 2人
ツイート数 2165 : 1人
ツイート数 117 : 2人
ツイート数 2166 : 1人
ツイート数 110713 : 1人
ツイート数 120 : 1人
ツイート数 121 : 2人
ツイート数 124 : 2人
ツイート数 125 : 2人
ツイート数 127 : 1人
ツイート数 2176 : 1人
ツイート数 128 : 1人
ツイート数 2177 : 1人
ツイート数 130 : 3人
ツイート数 131 : 1人
ツイート数 6276 : 1人
ツイート数 132 : 2人
ツイート数 133 : 1人
ツイート数 134 : 1人
ツイート数 135 : 2人
ツイート数 4232 : 1人
ツイート数 137 : 2人
ツイート数 138 : 2人
ツイート数 139 : 1人
ツイート数 140 : 2人
ツイート数 141 : 1人
ツイート数 18575 : 1人
ツイート数 146 : 1人
ツイート数 2195 : 1人
ツイート数 147 : 2人
ツイート数 148 : 1人
ツイート数 150 : 2人
ツイート数 151 : 1人
ツイート数 8344 : 1人
ツイート数 152 : 2人
ツイート数 156 : 2人
ツイート数 2205 : 1人
ツイート数 158 : 2人
ツイート数 6304 : 1人
ツイート数 2211 : 1人
ツイート数 164 : 2人
ツイート数 165 : 3人
ツイート数 10407 : 1人
ツイート数 4263 : 1人
ツイート数 168 : 2人
ツイート数 10411 : 1人
ツイート数 171 : 1人
ツイート数 174 : 1人
ツイート数 175 : 1人
ツイート数 30896 : 1人
ツイート数 2224 : 1人
ツイート数 178 : 1人
ツイート数 24756 : 1人
ツイート数 180 : 1人
ツイート数 181 : 1人
ツイート数 108729 : 1人
ツイート数 2234 : 1人
ツイート数 186 : 2人
ツイート数 187 : 1人
ツイート数 188 : 1人
ツイート数 189 : 2人
ツイート数 190 : 1人
ツイート数 191 : 1人
ツイート数 196 : 3人
ツイート数 198 : 1人
ツイート数 199 : 1人
ツイート数 202 : 1人
ツイート数 10443 : 1人
ツイート数 4301 : 1人
ツイート数 2254 : 1人
ツイート数 206 : 1人
ツイート数 209 : 1人
ツイート数 210 : 2人
ツイート数 51412 : 1人
ツイート数 2262 : 1人
ツイート数 214 : 1人
ツイート数 2263 : 1人
ツイート数 8408 : 1人
ツイート数 217 : 2人
ツイート数 221 : 1人
ツイート数 223 : 2人
ツイート数 225 : 1人
ツイート数 4322 : 1人
ツイート数 226 : 1人
ツイート数 2275 : 1人
ツイート数 228 : 3人
ツイート数 14565 : 1人
ツイート数 32998 : 1人
ツイート数 231 : 3人
ツイート数 2282 : 1人
ツイート数 2283 : 1人
ツイート数 235 : 1人
ツイート数 236 : 1人
ツイート数 238 : 1人
ツイート数 6385 : 1人
ツイート数 241 : 1人
ツイート数 242 : 1人
ツイート数 243 : 1人
ツイート数 245 : 2人
ツイート数 246 : 1人
ツイート数 247 : 1人
ツイート数 10489 : 1人
ツイート数 249 : 1人
ツイート数 250 : 3人
ツイート数 28925 : 1人
ツイート数 4350 : 1人
ツイート数 254 : 1人
ツイート数 135427 : 1人
ツイート数 258 : 1人
ツイート数 259 : 1人
ツイート数 260 : 2人
ツイート数 10502 : 1人
ツイート数 6408 : 1人
ツイート数 266 : 1人
ツイート数 268 : 2人
ツイート数 6413 : 1人
ツイート数 55570 : 1人
ツイート数 274 : 2人
ツイート数 275 : 1人
ツイート数 279 : 1人
ツイート数 281 : 1人
ツイート数 286 : 2人
ツイート数 2335 : 1人
ツイート数 287 : 1人
ツイート数 296 : 1人
ツイート数 297 : 2人
ツイート数 298 : 1人
ツイート数 4401 : 1人
ツイート数 305 : 1人
ツイート数 310 : 1人
ツイート数 20791 : 1人
ツイート数 313 : 1人
ツイート数 10554 : 1人
ツイート数 4410 : 1人
ツイート数 314 : 1人
ツイート数 2365 : 1人
ツイート数 2367 : 1人
ツイート数 323 : 1人
ツイート数 10564 : 1人
ツイート数 324 : 1人
ツイート数 326 : 1人
ツイート数 327 : 1人
ツイート数 328 : 1人
ツイート数 330 : 1人
ツイート数 4430 : 1人
ツイート数 334 : 1人
ツイート数 24912 : 1人
ツイート数 4432 : 1人
ツイート数 339 : 1人
ツイート数 341 : 1人
ツイート数 4440 : 1人
ツイート数 344 : 1人
ツイート数 346 : 1人
ツイート数 2397 : 1人
ツイート数 349 : 1人
ツイート数 6495 : 1人
ツイート数 352 : 1人
ツイート数 356 : 1人
ツイート数 2405 : 1人
ツイート数 360 : 1人
ツイート数 361 : 1人
ツイート数 362 : 1人
ツイート数 364 : 1人
ツイート数 368 : 2人
ツイート数 371 : 1人
ツイート数 10612 : 1人
ツイート数 4469 : 1人
ツイート数 4470 : 1人
ツイート数 374 : 2人
ツイート数 375 : 1人
ツイート数 380 : 1人
ツイート数 100735 : 1人
ツイート数 383 : 1人
ツイート数 8578 : 1人
ツイート数 2434 : 3人
ツイート数 386 : 1人
ツイート数 10627 : 1人
ツイート数 387 : 2人
ツイート数 4485 : 1人
ツイート数 389 : 2人
ツイート数 390 : 1人
ツイート数 156037 : 1人
ツイート数 2439 : 1人
ツイート数 395 : 2人
ツイート数 396 : 1人
ツイート数 14737 : 1人
ツイート数 20882 : 1人
ツイート数 402 : 2人
ツイート数 403 : 1人
ツイート数 2454 : 1人
ツイート数 406 : 1人
ツイート数 408 : 1人
ツイート数 410 : 1人
ツイート数 10651 : 1人
ツイート数 412 : 1人
ツイート数 2467 : 1人
ツイート数 420 : 1人
ツイート数 421 : 1人
ツイート数 423 : 1人
ツイート数 425 : 1人
ツイート数 432 : 1人
ツイート数 433 : 1人
ツイート数 436 : 1人
ツイート数 437 : 2人
ツイート数 12727 : 1人
ツイート数 440 : 1人
ツイート数 442 : 1人
ツイート数 444 : 1人
ツイート数 445 : 1人
ツイート数 446 : 1人
ツイート数 447 : 1人
ツイート数 448 : 1人
ツイート数 452 : 1人
ツイート数 2503 : 1人
ツイート数 455 : 1人
ツイート数 2504 : 1人
ツイート数 12745 : 1人
ツイート数 8649 : 1人
ツイート数 463 : 1人
ツイート数 467 : 1人
ツイート数 468 : 1人
ツイート数 469 : 1人
ツイート数 6615 : 1人
ツイート数 10713 : 1人
ツイート数 2521 : 1人
ツイート数 478 : 1人
ツイート数 479 : 1人
ツイート数 483 : 1人
ツイート数 14821 : 1人
ツイート数 12777 : 1人
ツイート数 490 : 1人
ツイート数 2539 : 1人
ツイート数 12782 : 1人
ツイート数 2542 : 2人
ツイート数 76275 : 1人
ツイート数 2548 : 1人
ツイート数 502 : 2人
ツイート数 8696 : 1人
ツイート数 506 : 1人
ツイート数 14844 : 1人
ツイート数 508 : 1人
ツイート数 25085 : 1人
ツイート数 6654 : 1人
ツイート数 510 : 1人
ツイート数 12801 : 1人
ツイート数 513 : 2人
ツイート数 515 : 1人
ツイート数 14853 : 1人
ツイート数 518 : 2人
ツイート数 522 : 1人
ツイート数 523 : 1人
ツイート数 524 : 2人
ツイート数 4623 : 1人
ツイート数 530 : 1人
ツイート数 12819 : 1人
ツイート数 532 : 2人
ツイート数 533 : 1人
ツイート数 4636 : 1人
ツイート数 540 : 1人
ツイート数 542 : 1人
ツイート数 14882 : 1人
ツイート数 6691 : 1人
ツイート数 2595 : 1人
ツイート数 4644 : 1人
ツイート数 2597 : 1人
ツイート数 550 : 1人
ツイート数 2599 : 1人
ツイート数 553 : 1人
ツイート数 14892 : 1人
ツイート数 74284 : 1人
ツイート数 2605 : 2人
ツイート数 21039 : 1人
ツイート数 560 : 1人
ツイート数 562 : 1人
ツイート数 18995 : 1人
ツイート数 566 : 1人
ツイート数 567 : 2人
ツイート数 570 : 1人
ツイート数 573 : 1人
ツイート数 10814 : 1人
ツイート数 2627 : 1人
ツイート数 580 : 1人
ツイート数 39495 : 1人
ツイート数 25160 : 1人
ツイート数 584 : 1人
ツイート数 587 : 1人
ツイート数 6733 : 1人
ツイート数 592 : 1人
ツイート数 593 : 1人
ツイート数 2642 : 1人
ツイート数 10835 : 1人
ツイート数 127573 : 1人
ツイート数 35414 : 1人
ツイート数 599 : 1人
ツイート数 602 : 1人
ツイート数 603 : 1人
ツイート数 6752 : 1人
ツイート数 608 : 2人
ツイート数 611 : 1人
ツイート数 2662 : 1人
ツイート数 614 : 1人
ツイート数 2665 : 1人
ツイート数 617 : 1人
ツイート数 626 : 2人
ツイート数 4724 : 1人
ツイート数 2678 : 2人
ツイート数 635 : 3人
ツイート数 636 : 1人
ツイート数 17022 : 1人
ツイート数 2686 : 1人
ツイート数 642 : 1人
ツイート数 643 : 1人
ツイート数 645 : 1人
ツイート数 647 : 1人
ツイート数 2696 : 1人
ツイート数 51850 : 1人
ツイート数 2699 : 1人
ツイート数 2703 : 1人
ツイート数 655 : 2人
ツイート数 12944 : 1人
ツイート数 657 : 1人
ツイート数 6802 : 1人
ツイート数 658 : 1人
ツイート数 4757 : 1人
ツイート数 8854 : 1人
ツイート数 663 : 1人
ツイート数 2712 : 1人
ツイート数 12959 : 1人
ツイート数 4769 : 1人
ツイート数 8871 : 1人
ツイート数 8874 : 1人
ツイート数 6826 : 1人
ツイート数 8877 : 1人
ツイート数 688 : 1人
ツイート数 691 : 1人
ツイート数 2744 : 1人
ツイート数 698 : 1人
ツイート数 699 : 1人
ツイート数 704 : 1人
ツイート数 15042 : 1人
ツイート数 709 : 1人
ツイート数 10953 : 1人
ツイート数 8906 : 1人
ツイート数 720 : 1人
ツイート数 726 : 1人
ツイート数 2775 : 1人
ツイート数 736 : 1人
ツイート数 174816 : 1人
ツイート数 6886 : 1人
ツイート数 6888 : 1人
ツイート数 35561 : 1人
ツイート数 4842 : 1人
ツイート数 746 : 1人
ツイート数 2804 : 1人
ツイート数 758 : 1人
ツイート数 760 : 1人
ツイート数 4857 : 1人
ツイート数 761 : 1人
ツイート数 2812 : 1人
ツイート数 4866 : 1人
ツイート数 772 : 1人
ツイート数 2825 : 1人
ツイート数 778 : 2人
ツイート数 780 : 1人
ツイート数 8976 : 1人
ツイート数 786 : 1人
ツイート数 788 : 2人
ツイート数 789 : 1人
ツイート数 793 : 1人
ツイート数 796 : 1人
ツイート数 797 : 1人
ツイート数 2849 : 1人
ツイート数 21283 : 1人
ツイート数 21289 : 1人
ツイート数 809 : 1人
ツイート数 9008 : 1人
ツイート数 822 : 1人
ツイート数 6970 : 1人
ツイート数 826 : 1人
ツイート数 827 : 1人
ツイート数 4927 : 1人
ツイート数 23360 : 1人
ツイート数 13121 : 1人
ツイート数 833 : 1人
ツイート数 834 : 1人
ツイート数 835 : 1人
ツイート数 838 : 1人
ツイート数 2891 : 1人
ツイート数 37709 : 1人
ツイート数 848 : 1人
ツイート数 2898 : 1人
ツイート数 852 : 1人
ツイート数 853 : 1人
ツイート数 859 : 1人
ツイート数 861 : 1人
ツイート数 9058 : 1人
ツイート数 2914 : 1人
ツイート数 2916 : 2人
ツイート数 869 : 1人
ツイート数 875 : 1人
ツイート数 880 : 1人
ツイート数 70512 : 1人
ツイート数 881 : 1人
ツイート数 884 : 1人
ツイート数 2935 : 2人
ツイート数 891 : 1人
ツイート数 7037 : 1人
ツイート数 17279 : 1人
ツイート数 23426 : 1人
ツイート数 2946 : 1人
ツイート数 899 : 1人
ツイート数 107396 : 1人
ツイート数 7047 : 1人
ツイート数 5000 : 1人
ツイート数 907 : 1人
ツイート数 15245 : 1人
ツイート数 910 : 1人
ツイート数 7056 : 1人
ツイート数 912 : 1人
ツイート数 17297 : 1人
ツイート数 7058 : 1人
ツイート数 916 : 1人
ツイート数 923 : 1人
ツイート数 925 : 1人
ツイート数 9120 : 1人
ツイート数 2979 : 1人
ツイート数 2980 : 1人
ツイート数 50088 : 1人
ツイート数 23464 : 1人
ツイート数 943 : 1人
ツイート数 15285 : 1人
ツイート数 949 : 1人
ツイート数 953 : 1人
ツイート数 956 : 1人
ツイート数 5054 : 1人
ツイート数 967 : 1人
ツイート数 3019 : 1人
ツイート数 11218 : 1人
ツイート数 3028 : 1人
ツイート数 981 : 1人
ツイート数 54232 : 1人
ツイート数 3037 : 1人
ツイート数 994 : 2人
ツイート数 70626 : 1人
ツイート数 3048 : 1人
ツイート数 1004 : 1人
ツイート数 1007 : 1人
ツイート数 3061 : 1人
ツイート数 35830 : 1人
ツイート数 7159 : 1人
ツイート数 1019 : 1人
ツイート数 29693 : 1人
ツイート数 5118 : 1人
ツイート数 1027 : 1人
ツイート数 1033 : 1人
ツイート数 1034 : 1人
ツイート数 1035 : 2人
ツイート数 11276 : 1人
ツイート数 17421 : 1人
ツイート数 1042 : 1人
ツイート数 99348 : 1人
ツイート数 5141 : 1人
ツイート数 3096 : 1人
ツイート数 1049 : 1人
ツイート数 15388 : 1人
ツイート数 1052 : 1人
ツイート数 3101 : 1人
ツイート数 1054 : 1人
ツイート数 1058 : 1人
ツイート数 11302 : 1人
ツイート数 1065 : 1人
ツイート数 1067 : 1人
ツイート数 1068 : 1人
ツイート数 1072 : 2人
ツイート数 1076 : 1人
ツイート数 3125 : 1人
ツイート数 1077 : 1人
ツイート数 5176 : 1人
ツイート数 1080 : 1人
ツイート数 5178 : 1人
ツイート数 1087 : 1人
ツイート数 3138 : 1人
ツイート数 1104 : 1人
ツイート数 3157 : 1人
ツイート数 17505 : 1人
ツイート数 1123 : 1人
ツイート数 3173 : 2人
ツイート数 5231 : 1人
ツイート数 1135 : 1人
ツイート数 11378 : 1人
ツイート数 7282 : 1人
ツイート数 3187 : 1人
ツイート数 27765 : 1人
ツイート数 13439 : 1人
ツイート数 7295 : 1人
ツイート数 1151 : 1人
ツイート数 3202 : 1人
ツイート数 1161 : 1人
ツイート数 21642 : 1人
ツイート数 23691 : 1人
ツイート数 42131 : 1人
ツイート数 46231 : 1人
ツイート数 1177 : 1人
ツイート数 3226 : 1人
ツイート数 1181 : 1人
ツイート数 23710 : 1人
ツイート数 13472 : 1人
ツイート数 1185 : 1人
ツイート数 3240 : 1人
ツイート数 13490 : 1人
ツイート数 1203 : 1人
ツイート数 40120 : 1人
ツイート数 5308 : 1人
ツイート数 7357 : 1人
ツイート数 13507 : 1人
ツイート数 1221 : 2人
ツイート数 7382 : 1人
ツイート数 1241 : 1人
ツイート数 21727 : 1人
ツイート数 1249 : 1人
ツイート数 29927 : 1人
ツイート数 1255 : 1人
ツイート数 38127 : 1人
ツイート数 7409 : 1人
ツイート数 11510 : 1人
ツイート数 1271 : 1人
ツイート数 11512 : 1人
ツイート数 1281 : 1人
ツイート数 7428 : 1人
ツイート数 152840 : 1人
ツイート数 3340 : 1人
ツイート数 11536 : 1人
ツイート数 19729 : 1人
ツイート数 1300 : 1人
ツイート数 5405 : 1人
ツイート数 15654 : 1人
ツイート数 5417 : 1人
ツイート数 3377 : 1人
ツイート数 1331 : 1人
ツイート数 1334 : 1人
ツイート数 7482 : 1人
ツイート数 3393 : 1人
ツイート数 9543 : 1人
ツイート数 1360 : 1人
ツイート数 1361 : 1人
ツイート数 1363 : 1人
ツイート数 1367 : 1人
ツイート数 13656 : 1人
ツイート数 3417 : 1人
ツイート数 1369 : 1人
ツイート数 1371 : 1人
ツイート数 15715 : 1人
ツイート数 17764 : 1人
ツイート数 1380 : 1人
ツイート数 38246 : 1人
ツイート数 1383 : 1人
ツイート数 3433 : 1人
ツイート数 5490 : 1人
ツイート数 7541 : 1人
ツイート数 50550 : 1人
ツイート数 3447 : 1人
ツイート数 5498 : 1人
ツイート数 5503 : 1人
ツイート数 1407 : 1人
ツイート数 3456 : 1人
ツイート数 44419 : 1人
ツイート数 1413 : 1人
ツイート数 1426 : 1人
ツイート数 21907 : 1人
ツイート数 1428 : 1人
ツイート数 1431 : 1人
ツイート数 13724 : 1人
ツイート数 5532 : 1人
ツイート数 1442 : 1人
ツイート数 1446 : 1人
ツイート数 1447 : 1人
ツイート数 1450 : 1人
ツイート数 3501 : 1人
ツイート数 13744 : 1人
ツイート数 7602 : 1人
ツイート数 7603 : 1人
ツイート数 1460 : 1人
ツイート数 13749 : 1人
ツイート数 11701 : 1人
ツイート数 5559 : 1人
ツイート数 3516 : 1人
ツイート数 1469 : 1人
ツイート数 3522 : 1人
ツイート数 7624 : 1人
ツイート数 1481 : 1人
ツイート数 1484 : 1人
ツイート数 11728 : 1人
ツイート数 1492 : 1人
ツイート数 3547 : 1人
ツイート数 1503 : 1人
ツイート数 1508 : 1人
ツイート数 5607 : 1人
ツイート数 1512 : 1人
ツイート数 24041 : 1人
ツイート数 15850 : 1人
ツイート数 1515 : 1人
ツイート数 1516 : 1人
ツイート数 5617 : 1人
ツイート数 11765 : 1人
ツイート数 5624 : 1人
ツイート数 3593 : 1人
ツイート数 1549 : 1人
ツイート数 7697 : 1人
ツイート数 181786 : 1人
ツイート数 22054 : 1人
ツイート数 1580 : 1人
ツイート数 17965 : 1人
ツイート数 9777 : 1人
ツイート数 5683 : 1人
ツイート数 3639 : 1人
ツイート数 1599 : 1人
ツイート数 1609 : 1人
ツイート数 34382 : 1人
ツイート数 1615 : 2人
ツイート数 7762 : 1人
ツイート数 9813 : 1人
ツイート数 24151 : 1人
ツイート数 1623 : 1人
ツイート数 13916 : 1人
ツイート数 1628 : 2人
ツイート数 20061 : 1人
ツイート数 5727 : 1人
ツイート数 54887 : 1人
ツイート数 13935 : 1人
ツイート数 87668 : 1人
ツイート数 1667 : 1人
ツイート数 3720 : 1人
ツイート数 3728 : 1人
ツイート数 1684 : 1人
ツイート数 13978 : 1人
ツイート数 1693 : 1人
ツイート数 24222 : 1人
ツイート数 1698 : 1人
ツイート数 13989 : 1人
ツイート数 20136 : 1人
ツイート数 3753 : 1人
ツイート数 1711 : 1人
ツイート数 1730 : 1人
ツイート数 9924 : 1人
ツイート数 3782 : 1人
ツイート数 5835 : 1人
ツイート数 3788 : 1人
ツイート数 32461 : 1人
ツイート数 18128 : 1人
ツイート数 48855 : 1人
ツイート数 5854 : 1人
ツイート数 1758 : 1人
ツイート数 3811 : 1人
ツイート数 1763 : 1人
ツイート数 5862 : 1人
ツイート数 9961 : 1人
ツイート数 14070 : 1人
ツイート数 3832 : 1人
ツイート数 22269 : 1人
ツイート数 63230 : 1人
ツイート数 1796 : 1人
ツイート数 1800 : 1人
ツイート数 5900 : 1人
ツイート数 16142 : 1人
ツイート数 1807 : 1人
ツイート数 1810 : 1人
ツイート数 1815 : 1人
ツイート数 10017 : 1人
ツイート数 3875 : 1人
ツイート数 1829 : 1人
ツイート数 3892 : 1人
ツイート数 14135 : 1人
ツイート数 1850 : 1人
ツイート数 3900 : 1人
ツイート数 1855 : 1人
ツイート数 3908 : 1人
ツイート数 3911 : 1人
ツイート数 8008 : 1人
ツイート数 1869 : 1人
ツイート数 3923 : 1人
ツイート数 5976 : 1人
ツイート数 8027 : 1人
ツイート数 12127 : 1人
ツイート数 1892 : 1人
ツイート数 1896 : 1人
ツイート数 79731 : 1人
ツイート数 18290 : 1人
ツイート数 3955 : 1人
ツイート数 1907 : 1人
ツイート数 1909 : 1人
ツイート数 1912 : 1人
ツイート数 75644 : 1人
ツイート数 36735 : 1人
ツイート数 3967 : 1人
ツイート数 38801 : 1人
ツイート数 1945 : 1人
ツイート数 1954 : 1人
ツイート数 6051 : 1人
ツイート数 34724 : 1人
ツイート数 1961 : 1人
ツイート数 12203 : 1人
ツイート数 1967 : 1人
ツイート数 1968 : 1人
ツイート数 8116 : 1人
ツイート数 1972 : 1人
ツイート数 1980 : 1人
ツイート数 6077 : 1人
ツイート数 1985 : 1人
ツイート数 1988 : 1人
ツイート数 1997 : 1人
ツイート数 4050 : 1人
ツイート数 4058 : 1人
ツイート数 24545 : 1人
ツイート数 4067 : 1人
ツイート数 49129 : 1人

↑の見出しをクリックで結果が開きます

ちゃんとソートしたつもりでしたが、バラバラに表示されてしまいました。

約73%が1回もツイートしていないという結果に!

f:id:neet-utsu-taro:20171009204817p:plain

ツイート数 0 : 3667人
ツイート数 1 : 93人
ツイート数 2 : 67人
ツイート数 3 : 20人
ツイート数 4 : 30人
ツイート数 5 : 14人
ツイート数 6 : 23人
ツイート数 7 : 13人
ツイート数 8 : 9人
ツイート数 9 : 7人
ツイート数 10 : 11人

1回もツイートしてない人は3667/5000で約73.3%ですね。

ツイート数が10回以下の人数は3954/5000で約79.1%です。

恐ろしや…( ゚Д゚)

立憲民主党のフォロワーの人はシャイなのかな?(震え声)

追記:コメントで指摘がありました。一つはデータの質に関するもの。もう一つは他党との比較がないという事でした。前者は今すぐに求めることはできませんが、後者はプログラムの変数を変えるだけなのですぐに求めることができました。

政党別のものを出します。他の野党の政党のものは面倒なので省きました… 興味のある方は上のソースコードからぜひ試してください。

f:id:neet-utsu-taro:20171010010752p:plain

終わりに

ここまで読んでくださって、ありがとうございます。

もしかしたら、バグや勘違いしてるかも?気が付いた方はコメント等で知らせてくれると嬉しいです。

自分でプログラムを組んで分析してみるのも楽しいですね。プログラムに興味のある方はぜひ試してみてください。

もし好評なら、フォロワーのツイート数だけでなく他の要素からも分析してみたいと思います。

またね('ω')ノ

記事の見出し間を表示非表示にできるjavascriptを作ってみた

こんにちは、鬱太郎です。昨日一昨日とJavaScriptとjQueryをいじりつつ、あるものを作っていました。

こんなのを作ってみました クリックしてみてください

見出しをクリックするとこのような画像が開きます

そう!見出しをクリックするとその内容を表示非表示にできるモジュールを作りました。今日はこれについて話していきたいと思います。

見出し間表示非表示イベントモジュール(toggle-header.js)

名前は私のネーミングセンスの結晶の塊です。あまり責めないでくださいw具体的に何ができるかというと、

  • 見出しをクリックするとその見出しから次の見出しまでを表示非表示にできる
  • 最初から見出しの次の内容を非表示にできる

この2点です。自分で説明しててもよくわかりません。(文章力がなくて申し訳ないです)

動作デモ

動作デモの見出しの中身のすべての見出しは先ほど説明したモジュールが組み込まれています。見出しを色々とクリックしてみてください。

読み込み時は見えているが、見出しをクリックすると消えたり見えたりするよ

あああああああああああああああああああああああああああああああああああああああああああああああああ

読み込み時には見えていないけど、見出しをクリックすると見えたり消えたりするよ

あああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ「ようこそ」

実は動作デモの見出しもクリックすると開いたり閉じたりするよ!

何に使うの?

といっても、何に使うと便利なんでしょうか?私がいろいろと考えてみました。

ソースコードなど、とにかく長い文章を書くとき

私はプログラムを作ってそれを乗っけたりしています。するととても長い文章を表示しなくてはいけない時もあります。

皆さんも原因は違えど、とても長い文章や写真の羅列などをしたことがあるのではないでしょうか?

その時にこのモジュールを使うと、読者の方も見やすいのではないでしょうか?

下はその例です。

サンプルソースコードをクリックして見る

問題の回答など隠したい要素があるとき

例えば読者に問いかけるような内容の記事の場合には、このモジュールは有効かもしれません。

1+1は?

クリックして答えを見る

2!

ロマン

はい。ロマンですそれ以上に何もないです。皆さんも何かに使ってみませんか?

コードと使用例

実際の使い方を説明していきます。

1.スクリプトコードを記事の先頭に貼り付ける

次のスクリプトコードを記事の先頭に貼り付けてください。

  • 見たまま記法の方はHTMLモードの先頭に貼り付けてください
  • Markdown記法の方は先頭に直接貼り付けられます
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(function(){
    //<h2,h3,h4... class="toggle-header" [data-display="none"][data-clink="1"]></h2,h3,h4,...>
    //セレクタ用
    var headerClass=":header.toggle-header";
    var headerAttrForDiv="data-display";
    var headerAttrForP="data-clink";
    
    //閉じるボタンのクラス CSS用に必要かも
    var closeLinkClass = "close-link";

    //閉じるリンクの説明文字

    var linkTextPre="<p class='"+closeLinkClass+"'><a>ここをクリックすると『";
    var linkTextPost = "』が閉じます</a></p>";

    $(headerClass).each(function(){

        var level = this.nodeName.toLowerCase().slice(-1);

        var nextHeader = "h1";
        for(var i=2;i<=level;i++){
            nextHeader += ",h" + i;
        }

        if($(this).nextUntil(nextHeader).length){
            $(this).click(function(){
                if($(this).next().css("display")=="none"){
                    $(this).next().show();
                }else{
                    $(this).next().hide();
                }
            });

            var init = $(this).attr(headerAttrForDiv);
            var divStr = "<div style='display:"+((init)?init:"block")+"'>";
            var linkStr = linkTextPre + $(this).text() + linkTextPost;
            $(this).nextUntil(nextHeader).wrapAll(divStr);
            if($(this).attr(headerAttrForP)){
                $(this).nextUntil(nextHeader).last().append(linkStr);
                $(this).next().children(":last").click(function(){
                    $(this).parent().hide();
                })
            }
        }
    });
})   
</script>             

1行目はjQueryの読み込みです。既にヘッダー等に同様の記述がある場合は必要ありません。

2.見出しにクラス名や属性を追加する

ソースコードをコピペした後は、見出しにクラス名を付けるだけで機能します。

そのまま記法の方はHTML編集のページから非表示させたい見出しh1,h2,h3...などを見つけてクラス名や属性を追加してください。Markdown記法の方はHTMLコードを直接記述できます。

デフォルト動作の記述方法

class="toggle-header"を記述することでその見出しにクリックのイベント機能が追加されます。

<h5 class="toggle-header">デフォルト動作</h5>
<p>見出しタグに<code>class="toggle-header"</code>を追加することでクリックすると非表示表示させる機能が付きます</p>

デフォルト動作

見出しタグにclass="toggle-header"を追加することでクリックすると非表示表示させる機能が付きます

最初に非表示からスタートさせる記述方法

最初から内容を非表示にしたい場合はdata-display="none"をさらに追加します。

<h5 class="toggle-header" data-display="none">最初に表示させない</h5>
<p>見出しタグに<code>class="toggle-header" data-display="none"</code>を追加することで最初に表示はさせずに、クリックすると表示非表示させる機能が付きます</p>

最初に表示させない

見出しタグにclass="toggle-header" data-display="none"を追加することで最初に表示はさせずに、クリックすると表示非表示させる機能が付きます

末尾に非表示にさせるリンクを追加する

末尾にクリックすると見出しをクリックしたときと同じように非表示にできるリンクを追加します。data-clink="1"をさらに追加します。例ではdata-display="none"を使っていませんが、もちろん両方使えます。

<h5 class="toggle-header" data-clink="1">末尾にリンクを追加</h5>
<p>見出しタグに<code>class="toggle-header" data-clink="1"</code>を追加することで、末尾にクリックすると非表示させるリンクが付きます</p>
末尾にリンクを追加

見出しタグにclass="toggle-header" data-clink="1"を追加することで、末尾にクリックすると非表示させるリンクが付きます

機能のまとめ

  • class="toggle-header"を追加したいヘッダーにつける
  • data-display="none"で初期状態は非表示
  • data-clink="1"で末尾に非表示リンクを追加

です。少し難しいですが、ぜひ試してください!

注意事項

このプログラムはclass="toggle-header"を指定した見出しレベルを読み取って動作しています。<h3 class="toggle-header">ならば見出しレベルは3ですね。

プログラムはclass="toggle-header"を指定した見出しレベルを含むそれ以上の見出しが出るまで、それを非表示にさせる内容ととらえます。見出しレベルが3ならば、<h1><h2><h3>が次に出るまでの内容をまとめて表示非表示にさせるイベントを追加します。<h4><h5><h6>の内容がかかれていてもそれもまとめて非表示にさせてしまうことがあります。下がその例です。

<h3 class="toggle-header" data-display="none">見出し3</h3>
<p>見出し3の内容</p>
<h4 class="toggle-header" data-display="none">見出し4</h4>
<p>見出し4の内容</p>
<h5 class="toggle-header" data-display="none">見出し5</h5>
<p>見出し5の内容</p>
<h3 class="toggle-header" data-display="none">見出し3-2</h3>
<p>見出し3-2の内容</p>
<h4 class="toggle-header" data-display="none">見出し4-2</h4>
<p>見出し4-2の内容</p>
<h5 class="toggle-header" data-display="none">見出し5-2</h5>
<p>見出し5-2の内容</p>

<p>ここは非表示にさせたくない!</p>

見出し3

見出し3の内容

見出し4

見出し4の内容

見出し5

見出し5の内容

見出し3-2

見出し3-2の内容

見出し4-2

見出し4-2の内容

見出し5-2

見出し5-2の内容

ここは非表示にさせたくない!

この動作は仕様なのですが、レベルが下の見出しもまとめて表示非表示にさせたくない場合もあるでしょう。

その場合は対応した見出しレベルのダミーを追加することで、問題を解決できます。対応する見出しにstyle="display:none"を付けることでうまく動作します。

<h3 class="toggle-header" data-display="none">見出し3</h3>
<p>見出し3の内容</p>
<h3 style="display:none"></h3>
<h4 class="toggle-header" data-display="none">見出し4</h4>
<p>見出し4の内容</p>
<h4 style="display:none"></h4>
<h5 class="toggle-header" data-display="none">見出し5</h5>
<p>見出し5の内容</p>
<h5 style="display:none"></h5>
<h3 class="toggle-header" data-display="none">見出し3-2</h3>
<p>見出し3-2の内容</p>
<h3 style="display:none"></h3>
<h4 class="toggle-header" data-display="none">見出し4-2</h4>
<p>見出し4-2の内容</p>
<h4 style="display:none"></h4>
<h5 class="toggle-header" data-display="none">見出し5-2</h5>
<p>見出し5-2の内容</p>
<h5 style="display:none"></h5>
<p>ここは非表示にさせたくない!</p>

見出し3

見出し3の内容

見出し4

見出し4の内容

見出し5

見出し5の内容

見出し3-2

見出し3-2の内容

見出し4-2

見出し4-2の内容

見出し5-2

見出し5-2の内容

ここは非表示にさせたくない!

終わりに

ここまで読んでくださってありがとうございます!

ここ最近はjavascriptやjQueryを触りまくっていました。ほぼほぼ初心者でしたが、今では少しはコードも書けるようになったと思います。

興味のある方はぜひこのスクリプトで遊んでください!私が泣いて喜びます!

読者登録ありがとうございます。スターやブックマーク、コメント等もありがとうございます!励みになってます。

またね('ω')ノ

はてなブログは何で書く? Markdownで決まりでしょ!

皆さんはどの方法ではてなブログを書いていますか?見たままですか?それとも硬派にHTML直打ちですか?

Markdown教に入信して約1か月がたった私、鬱太郎がMarkdown記法の魅力についてお伝えしたいと思います。

PCで書かれる方向けに想定してます。スマホで記事を書かれる方はディスプレイの大きさ的に見たまま記法の方がいいのかもしれません。

f:id:neet-utsu-taro:20170907212631p:plain

はてなブログの編集方法

はてなブログの編集方法は4つありますよね

  • そのまま
  • はてな記法
  • Markdown
  • HTML

皆さんはどれが好きですか?Markdownを使っている人は私とお仲間ですね(*'ω'*)

Markdownの疑問

Markdownって何?

Markdown(マークダウン)は、文書を記述するための軽量マークアップ言語のひとつである。本来はプレーンテキスト形式で手軽に書いた文書からHTMLを生成するために開発されたものである。しかし、現在ではHTMLのほかパワーポイント形式やLATEX形式のファイルへ変換するソフトウェア(コンバータ)も開発されている。各コンバータの開発者によって多様な拡張が施されるため、各種の方言が存在する。

Markdown - Wikipedia

Markdownはいわゆるホームページ(HTML)を簡単に作る書き方のことです。HTMLを書いたことがある方はわかると思いますが、HTMLはタグを閉じたりするのにとても面倒です。そういった面倒を解消するために作られた手段というわけですね。

staff.hatenablog.com

Markdownって難しいんじゃないの?

そんなことありません。確かに最初は戸惑いますが、慣れれば見たまま記法よりも早く書くことができます。

また、見たまま記法のようにツールバーやサイドメニューのモジュールも普通に使うことができます。

Markdownでも、見たまま記法のようにモジュールを使うことができます

画像の追加から、目次の追加、文字の拡大縮小、太文字等の基本的な機能はMarkdownでする必要もなく、はてなブログのインターフェースからも使うことができます。いいね!

また、書きながら記事の完成を見ることができます。見たまま記法のように完ぺきではありませんがある程度のデザインを見ながらできます。

さあ、Markdown教に入信したくなってきましたか?

Markdownにしていいことあるの?

もちろんです!これから説明していきますね!

堅苦しいからこその安定感がある

MarkdownはいわゆるCUI(文字ベース)でブログを書いていきます。再現性があるということです。また、記事にする際に無駄な部分を省いてくれるため記事ごとの無駄な表記ズレがなくなります。

見たまま記法ですと、見出しを入れるときに少しずれてしまったりなどよくありませんか?ありますよね!(食い気味)そういったGUI(マウスなどでドラッグなどして操作する方法)にない利点があります。

はてなブログのMarkdownはちょっと特殊

はてなブログのMarkdownはいわゆる正規のMarkdownとは違います。方言みたいのものが組み込まれていると考えてください。Markdown記法でも使えるものによってははてな記法のものも使えます。

両者のいいとこどりというわけですね!

Markdownを覚えておけば他のブログを使ったときに便利

Markdownを使っておけばMarkdownに対応している他のブログに移った時に便利です。いわゆるMarkdownはブログ界の共通語のようなものです。(大げさに言いました)

環境が変わっても同じものがあるというのはいいものですよ!

MarkdownはHTMLも書ける

Markdown記法ではHTMLコードも書くことができます。HTMLで記述したい部分があるけど、HTML記法ですべて書くのはちょっと…といった方にピッタリですね!

HTMLコードがかけるという事は<script>も埋め込むことができます。javascriptで便利なモジュールを見つけたけどどうしよう?といった方はMarkdown記法を使ってみるのはいかがでしょうか?

きっとあなたの役に立つことでしょう!

Markdownはネットがない場所でも編集できる

せっかくブログを書いたのに、書きたかったのに、ネットにつながらない!という方いませんか?

外出してノートパソコンだけど、ブログ書こうかな?無料Wifiないし、テザリングか…でも通信制限大丈夫だっけ?…といった経験ありませんか?

ありますよね!

Markdown記法でブログを書けば、画像の貼り付け以外のほとんどをネットのない環境で作ることができます。

もちろんフリーソフトでありますよ!

forest.watch.impress.co.jp

macdown.uranusjr.com

ネットが必要でない部分を手元で書いておいて、あとではてなブログの方にコピペするだけで完成です!簡単!

あ!入信してくださるんですか?ありがとうございます!

よく使うMarkdownの記述方法

どうやら入信される決心がついたようですね!そこで、私がよく使うMarkdown記法について説明していきます。

見出し

見出しは基本!Markdown記法では#で見出しを表せます。#の個数が見出しのレベルと対応しています。

そのまま記法では、ブラウザのアドイン等を入れない限り、見出し3~5のレベルしか使えません。Makrdown記法はそんな束縛をものともしないでしょう。

##見出し2
###見出し3
####見出し4
#####見出し5
######見出し6

見出し2

見出し3

見出し4

見出し5
見出し6

あれ?じゃあ#を表示したいときはどうするの?と思う方もいるでしょう!

安心してください!エスケープ文字というのがあります。Markdownのエスケープ文字は\バックスラッシュです。

\#

\#\#

#

##

また、`バックコーテーションで囲むと<code>タグとみなされ、中身のmarkdown記法がすべてエスケープされます。バックコーテーションはキーボードのShiftキーを押しながら@で出ます。

`\``####`といったものもこんな風にエスケープできます。

\####といったものもこんな風にエスケープできます。

改行

改行する際は必ず二回以上改行しないと改行とみなされません。1行開ける必要があります。

改行したつもりでも、
つながってしまいます。

改行したつもりでも、 つながってしまいます。

改行したい場合は、

1行開けましょう。

改行したい場合は、

1行開けましょう。

箇条書き

箇条書きはツールバーからも書けますよ!初心者にも安心!

* 箇条書きは、アスタリスク`*`
*`-``+`などを書き、半角スペースを空けて、
* 内容を書くと書けます。
  • 箇条書きは、アスタリスク*
  • -+などを書き、半角スペースを空けて、
  • 内容を書くと書けます。

その際上下に1行空行を空けておくといいでしょう。

表を書く

ちょっと調査不足なのですが、そのまま記法で表って書けますか?上のツールバー見ても見当たらないのでもしかしたらかけないのかもしれません。

しかし、Markdown記法を使えば表を入れることができます

左揃え|中央ぞろえ|右揃え
:-|:-:|-:
01|02|03
Markdown記法は|あなたのブログ作りに|光を指すでしょう!
左揃え 中央ぞろえ 右揃え
01 02 03
Markdown記法は あなたのブログ作りに 光を指すでしょう!

これもまた上下に1行開けておきましょう。|で要素を区切ります。キーボードのバックスペースキーの左にあります。Shiftキーを押しながら円記号を押すと出ます。

2行目にその列の文字揃えを記述する必要があります。その内容は上記の例を参考にしてください。

画像の詳細を記述する

これははてな記法になるのですが、Markdownでもできます!

画像をサイドバーから選ぶと、このような形式のものが出てきます。

[f:id:neet-utsu-taro:20170924085633j:plain]

これはそのままですとこのような縦長の写真が出てきてしまいます。

f:id:neet-utsu-taro:20170924085633j:plain

長い!すみません。

はてな記法では写真の高さや幅を調節できます。

[f:id:neet-utsu-taro:20170924085633j:plain:h200]

f:id:neet-utsu-taro:20170924085633j:plain:h200

これは高さ200のサイズで画像を表示させる方法です。plainの後ろに:hと続けて設定したい大きさを書きましょう。

幅を指定したい場合は:wに指定したいサイズを書きます。幅200のサイズで画像を表示させてみました。

[f:id:neet-utsu-taro:20170924085633j:plain:w200]

f:id:neet-utsu-taro:20170924085633j:plain:w200

また、画像のタイトルや説明をtitle要素とalt要素を使い盛り込むことができます。

[f:id:neet-utsu-taro:20170924085633j:plain:w200:title=カーソルを合わせると画像のタイトルが表示されます:alt=これは画像の説明です。画像の代わりを文字で表しましょう]

これは画像の説明です。画像の代わりを文字で表しましょう

画像にカーソルなどを合わせると、タイトルが表示されます。タイトルを設定しないと、画像ファイルのIDが表示されます。上の画像で試してみてください。

え?画像が左寄りばかり?

先ほども言ったようにHTMLコードも記述できますよ!という事は…?<center>等のタグも使えますよ!といっても<center>タグは非推奨なので<div align="center">を使っていきます。

<div align="left">
[f:id:neet-utsu-taro:20170924085633j:plain:h200]
</div>
<div align="center">
[f:id:neet-utsu-taro:20170924085633j:plain:h200]
</div>
<div align="right">
[f:id:neet-utsu-taro:20170924085633j:plain:h200]
</div>
f:id:neet-utsu-taro:20170924085633j:plain:h200
f:id:neet-utsu-taro:20170924085633j:plain:h200
f:id:neet-utsu-taro:20170924085633j:plain:h200

HTMLの書き方になれていない方は難しいかもしれませんが、できればこんな風に綺麗に画像をそろえることができます。

Markdown教への入信、してくださいますよね?

コードを書く

コードとはプログラミング言語だけでなく<code>のことです。この記事もかなりの数を使っています。エスケープ文字の時でもちょろっと出ましたね。バックコーテーションで囲むことで文中に特殊な表示の仕方をさせることができます。

私のメールアドレスは`teineiteineiteinei@ahoo.co.jp`です。

私のメールアドレスはteineiteineiteinei@ahoo.co.jpです。

表示のさせ方は各ブログのテーマやCSSによって変わります。フォントも強制的に変わる場合があり、数字やアルファベットも見やすくなったりする場合もあります。

バックコーテーション`はShiftキーを押しながら、@を押しましょう。

また、じゃあ`を表示したいときはどうすればいいんだろう?と思う方もいるでしょう。HTMLタグの中に書くことでエスケープできます。

この場合は<span>`</span>で文字を囲みます。

この場合は`で文字を囲みます。

ただ、あんまり`を文字として使いたいことは少ないと思うので気にしなくていいですね。

引用をする

引用はツールバーからも追加できますが、とても簡単なので直接記入しましょう。>だけです。

>これは引用文です。


>>2重に引用させることもできます。

これは引用文です。

2重に引用させることもできます。

引用文が続けば、隙間を空けてもくっつきます。(改行はされます)また、>を重ねることで引用の中に引用を持ってくることもできます。

他にも画像にも引用を付けることができます。

>[f:id:neet-utsu-taro:20170924085633j:plain:h200]

>これは私がとった早朝の空の写真です。

f:id:neet-utsu-taro:20170924085633j:plain:h200

これは私がとった早朝の空の写真です。

さあ!Markdownを使いたくなってきましたよね!

まとめ

最後にこんな人はMarkdown記法をしてみてはいかがでしょうかというのをまとめてみました。

  • Texが好きな人

ってTexが好きな人は既にMarkdown使ってそう…

  • 見出しから書いていく方

見出しから書いていく方は、Markdownがぴったりかもしれません。Markdownでは見出しは#を使い簡単に書け、またMarkdown記法ではフォントサイズが一定のため、見出しの数が多くなった場合に確認しやすいという利点があります。

  • Markdown教に入信希望の方

皆さんMarkdown教に興味を持ってくださいましたよね?という事で、ぜひ触ってみてください。

下にこの記事のmarkdown表記を載せておきました!入信希望の方は是非参考にしてくださいね!

クリックすると開きます↓↓

この記事のMarkdown

終わりに

ここまで読んでくださってありがとうございます!

Markdown。ぜひお試しあれ!

実際のところはてなブログの記法の使用率ってどんなんでしょうね?ちょっと気になります。

読者登録ありがとうございます!スターやブックマーク等もありがとうございます。励みになってます!

またね('ω')ノ