入門ソーシャルデータ①環境構築とTwitterAPI

こんばんは。先週末から風邪でダウンしている太鼓眼鏡です。

今日あたりからようやく調子が戻り始めたので、久しぶりにプログラミングをいじってました。

さて先々週辺りからいつもの友達とひたすら進めているのがこちら。

この本のスクレイピングの技術を使って、 こないだの記事をpython版で作り変えたりしてました。 taikomegane.hatenablog.jp

ただそちらは規約的にかなりグレー(というかアウト)なので、アップするのはやめにしています。

機械学習の方の最終目標は「チャットボットを作るようになること」 ちょっと処理的に理解できない箇所が増えてきているので、気長に頑張ろうと思います。

一方で、もう一つ買ったっきり進めてない本があったので今日はそちらの進捗報告。

入門 ソーシャルデータ 第2版 ―ソーシャルウェブのデータマイニング

入門 ソーシャルデータ 第2版 ―ソーシャルウェブのデータマイニング

まずこの本だとvagrantfileが用意されてるので、それでいろいろ上手くいくはずが、 エラーを吐きまくるのでこちらは諦めました。

そこで、前述の本を参考にdockerで環境構築をしたので方法を簡単に紹介。

#dockerでminiconda3のコンテナをプルリクエスト
docker pull continuumio/miniconda3

#一応動作確認
docker run -i -t continuumio/miniconda3 /bin/bash
python3 -c "print(3*5)
exit

#コンテナの一覧を出してCONTAINER IDを確認
docker ps -a

#コンテナをコミット
docker commit "CONTAINER ID" 適当な名前

#自分の環境をマウントしてコンテナを起動
docker run -it -v 自分の環境:自分の環境 \
     -e LANG=ja_JP.UTF-8 \
     -e PYTHONIOENCODING=utf_8 \
     -p 8080:8080 適当な名前 /bin/bash

これでpython3が入った環境が出来上がり この後ソーシャルデータ入門のTwitterAPIを使うための準備をしていきます。

#pipをインストール
apt-get update
apt-get install -y python3-pip

#twitterをインストール
pip3 install twitter

で、これでいけると思ったら見つからないとエラーを吐いたので別の方法を探す。 同じエラーで悩んでいる人を発見。解決方法をぱくる。

stackoverflow.com

#まずtwitterをアンインストール
pip3 uninstall twitter

#その後インストールしなおし
wget https://pypi.python.org/packages/source/t/twitter/twitter-1.12.1.tar.gz
tar -xzf twitter*.tar.gz
python3 setup.py build
python3 setup.py install

これで上手くインストール出来ている。 ひとまずここまでで、TwitterAPIを使うための環境構築が終了。

この後TwitterAPIを入手する。

import twitter

CONSUMER_KEY = ''
CONSUMER_SECRET = ''
OAUTH_TOKEN = ''
OAUTH_TOKEN_SECRET = ''

auth = twitter.oauth.OAuth(OAUTH_TOKEN, OAUTH_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET)

twitter_api = twitter.Twitter(auth=auth)

print(twitter_api)

このファイルをさっきの環境で、

python3 oauth.py

とやって上手いこと返ってきたら、成功。

一応続きとして、世界とアメリカのトレンドを検索してみる。

import twitter

CONSUMER_KEY = ''
CONSUMER_SECRET = ''
OAUTH_TOKEN = ''
OAUTH_TOKEN_SECRET = ''

auth = twitter.oauth.OAuth(OAUTH_TOKEN, OAUTH_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET)

twitter_api = twitter.Twitter(auth=auth)

WORLD_WOE_ID = 1
US_WOE_ID = 23424977

worId_trends = twitter_api.trends.place(_id=WORLD_WOE_ID)
us_trends = twitter_api.trends.place(_id=US_WOE_ID)

print(worId_trends)
print("")
print(us_trends)

このコード、動いたのだけど結果はすごいことに、、、

[{'trends': [{'name': '#USAin4words', 'url': 'http://twitter.com/search?q=%23USAin4words', 'promoted_content': None, 'query': '%23USAin4words',
'tweet_volume': 14411}, {'name': '#WednesdayWisdom', 'url': 'http://twitter.com/search?q=%23WednesdayWisdom', 'promoted_content': None, 'query':
 '%23WednesdayWisdom', 'tweet_volume': 47481}, {'name': '#PhilJackson', 'url': 'http://twitter.com/search?q=%23PhilJackson', 'promoted_content':
 None, 'query': '%23PhilJackson', 'tweet_volume': None}, {'name': '#LifeWouldBeDifferentIf', 'url': 'http://twitter.com/search?q=%23LifeWouldBeD
ifferentIf', 'promoted_content': None, 'query': '%23LifeWouldBeDifferentIf', 'tweet_volume': None}, {'name': 'Michael Bond', 'url': 'http://twit
ter.com/search?q=%22Michael+Bond%22', 'promoted_content': None, 'query': '%22Michael+Bond%22', 'tweet_volume': 14472}, {'name': '#WhenWeRunTwitt
er', 'url': 'http://twitter.com/search?q=%23WhenWeRunTwitter', 'promoted_content': None, 'query': '%23WhenWeRunTwitter', 'tweet_volume': None},
{'name': "Trump Is China's Chump", 'url': 'http://twitter.com/search?q=%22Trump+Is+China%27s+Chump%22', 'promoted_content': None, 'query': '%22T
rump+Is+China%27s+Chump%22', 'tweet_volume': None}, {'name': 'Amtrak', 'url': 'http://twitter.com/search?q=Amtrak', 'promoted_content': None, 'q
uery': 'Amtrak', 'tweet_volume': None}, {'name': 'Zach Orr', 'url': 'http://twitter.com/search?q=%22Zach+Orr%22', 'promoted_content': None, 

これがめちゃくちゃ続きます。このあと綺麗にする方法も学ぶらしいので期待。

ひとまずここまでやってみてわかったのが、

  • この本python2で書かれているから、文法が異なることが多い
  • コードをそのまま書いただけじゃ動かないことが多い。都度修正が必要

まあエラーを一つずつ潰すのも勉強だと思って頑張ります。 ではまた。

NewsPicksでスクレイピングやってみた

こんにちは。駆け出しエンジニアの太鼓眼鏡です。
まだまだ研修中の身ですが、今日も書いたものや学んだことをシェアしていきます。

今日作ったのは、NewsPicksの記事をpicksした人から、影響力の大きい人だけを抽出する仕組みです。 先日から研修ではJSPサーブレットを用いてECサイトを作る課題をやっているので、 そこで得た知識と、googleさんの力を借りて作成しました。

ファイルはこちらからご覧ください。 よくわからないままに書いている箇所もたくさんありますが、ご了承ください。 github.com

前提条件

  • 記事のURLを投げると、「影響力の大きいpicker」の情報が見れるようにしたい
  • 「影響力の大きい」=1000人以上following、followerがいる人と定義
  • 表示したい情報は、ユーザID、名前、フォロワー数、フォロー数、ユーザURL

結果

今回は色々調べて、こちらを使いました。

jsoup.org Apache HttpClient - Tutorial

一応色々な記事に助けてもらいながら動かすことはできました。 ただ異常なほど重く、1500picksくらいされている記事を投げると1分強結果が返ってきません。

まずこの検索窓にNewsPicksの記事URLを投げます。

f:id:cyclemem:20170528234912p:plain

待つこと数十秒。。 こんな感じで結果が返ってきます(念のためモザイク処理しています)。 f:id:cyclemem:20170528234917p:plain

構造

図で書くとこんな感じ。 f:id:cyclemem:20170528234923p:plain

  1. まず「index.jsp」に対象サイトのURLを入力します
  2. POSTで「LinkConvertServlet.java」に記入されたURLを送ります
  3. 「pickersList.java」にURLを送ります
    3-1. メソッド「execute」で、2-5のメソッドを順に呼び出し、最後にinfoListを返します
    3-2. 指定されたリンクから、pickしているユーザのIDを配列にして返します
    3-3. ユーザIDの配列からユーザの個別ページのhtmlを呼び出し、スクレイピングを行います。そのうちfollowerとfollowingが1000以上のユーザIDのみを新たに配列にして返します
    3-4. 生成された配列を用いて、該当ユーザの名前を配列にして返します
    3-5. 生成された配列を用いて、該当ユーザのフォロワー数とフォロー数を配列にして返します。
    3-6. 3-2~5で生成された配列から、「ユーザID、名前、フォロワー数、フォロー数、ユーザURL」を持つインスタンス「Info」を生成します。それらを「infoList」として、「LinkCOnvertServlet.java」に返します
  4. 返ってきた配列を「result.jsp」に返します
  5. forループを用いて、配列をテーブルとして出力します

今後やりたいこと

  • あまりにも重いのでもっと効率的に回したい
  • 今回cssをいじってないので、もっときれいに出したい
  • これセキュリティ的にどうなの?という箇所が多いのでサーバ周り勉強したい

参照した記事一覧

d.hatena.ne.jp d.hatena.ne.jp qiita.com d.hatena.ne.jp www.ctrlshift.net

じゃんけんシミュレータ作ってみた

こんにちは。駆け出しエンジニアの太鼓眼鏡です。
まだまだ研修中の身ですが、書いたものや学んだことをシェアしていきます。

今日は研修の課題で作成した「じゃんけんシミュレータ」について紹介します。
仕様言語はJava、一応オブジェクト指向を意識したつもりです。

ファイルはこちらから御覧ください。
github.com

コメント等も残しているので、詳細はそちらから。 一応記事下にも添付してありますが、長いです。

前提条件

  • 5人でじゃんけんを行う
  • 1〜5位まで全員に順位がつくまでに、何回じゃんけんをするかを算出する
  • 1000回シミュレーションを行い、その平均値を出力する
  • 複数グループに分かれてじゃんけんを行うときは、同時にじゃんけんを行う

フローチャート

f:id:cyclemem:20170521225938p:plain

各ファイルの説明

Main.java

ゲームの全体の流れ

Player.java

じゃんけんに参加するプレイヤークラス
*フィールド、メソッドはそれぞれ1つずつ。

フィールド:
- rsp = じゃんけんの手。0: rock, 1: scissors, 2: paperとする
メソッド:
- setRsp()=引数無しで、0~2の乱数をrspに代入する

Referee.java

じゃんけんの結果を判定する審判クラス

フィールド:
- num = シミュレーション回数。コンストラクタで設定
- total = じゃんけんを行う総人数。コンストラクタで設定
- group = 各グループの人数。詳しくは後述
- win, lose = それぞれ各ゲームの勝敗人数
- total = じゃんけん1回が終了するまでの回数。詳しくは後述
- total_count = じゃんけん終了までの総回数
- r, s, p = それぞれグー、チョキ、パーの人数
メソッド:
- 各セッター、ゲッター:基本は通常通りなため割愛
- setGroup = groupを初期化
- setTotal_count = count[0]とcount[1]を比較して、大きいほうをtotal_countに代入
- setCount = countを1増やす
- 初期化用メソッド
- clearRsp = じゃんけんの手を初期化
- clearCount = countを初期化
- じゃんけん用メソッド
- countRsp = r,s,pがそれぞれ何人いるか数える
- judge = 勝敗判定、あいこならループ続行指示
- add = 勝敗人数をgroupに追加
- remove = じゃんけんを行ったgroupを削除
- シミュレーション用メソッド
- calcAvg = 総回数の平均値を算出する

結果

今回課題では5人という指定がありましたが、n人でも利用出来るシミュレータを作成することを意識しました。
最終的に、プログラムとしては可能ですが、PCのスペック的に処理が追いつかないものになりました。20人ほどで結果がでなくなります。
またその仕様を実現するために、ArrayListを用いています。

今後に向けて

  • もう少し細かく説明する記事をあげたい
  • いざ文章にしてみるとフローチャートの流れが自然じゃない箇所が散見されるので修正加えたい
  • ArrayListについてもう少し詳しく勉強しときたい
  • 今回人数増えると結果が出なくなるので、もっと効率的なフローで回したい 以上!精進あるのみ。

最後に肝心のプログラム

gist.github.com