はじめてWebサービスを構築してみたので記録を残す

#Webサービスは誰でも挑戦することができる

皆、好きにやればいいと思うよ
[]( ※Webサービスが公開されてからこの記事は公開する )

## きっかけ
この[記事](https://qiita.com/jabba/items/1a49e860a09a613b09d4)を読んで始めようと思った
要するに儲けたい

## 売上結果
まだ、Google Adsenseの登録も終わっていないので、
成功しても失敗しても結果が出たら公開しようと思う

## どんな感じのサイトなのか？
Twitterで話題にあがった[BandCamp](https://bandcamp.com/)で配信されている曲を紹介する[Webサービス](http://valuepub.net/service/bandcamp/index.html)

## 実装の流れ
TwitterからBandCampに関するツイートからRetweet数が多かった内容を取得する
取得した情報を元に、Bandcampの埋め込みタグを利用してホームページに貼っていく

## 実装目標
時間を掛けずに構築すること
理由は売上が目的なのであって、サイト構築に時間を掛けることは「本末転倒」だと思ったため[^1]

そのためには、利用できるサービスは何でも使って時間短縮をはかる
実際にWebサイトの画面周りはサービスを利用することで「デザイン」するためのコードは書いていない
Webサイトに表示する中身だけ書き換えた

## スケジュールの見積り
第一次スケジュール
3営業日
第ニ次スケジュール(リスケ)
8営業日

## 実装結果
失敗 -> 半自動サービスに切り替え
詳しくは、[自分が過去に投稿した記事](https://qiita.com/JINCHANGUITAR/items/b5c0089606af71588bd5)を読むと失敗した原因が分かる

## 実装時に感じたこと
- 公式ドキュメントを読むことをオススメする[^2]
- ドキュメントの英語が読めなきゃGoogle翻訳を使って内容を察するとよい
- 毎日少しずつ進めよう[^3]
- 誰かと話してみよう[^4]

## 実装日数
11営業日

## 総工数
約31時間[^5]

## サイト構築をするために利用した内容
- [Python](https://www.python.org/)
- [Python Twitter Tools](https://pypi.org/project/twitter/)
- JSON
- [Online JSON Viewer](http://jsonviewer.stack.hu/)
- [SQLite](https://www.sqlite.org/index.html)
- [Design Blocks](https://www.froala.com/design-blocks)
- [A5:SQL Mk-2](https://a5m2.mmatsubara.com/)
- [Visual Studio Code](https://code.visualstudio.com/)
- [Twitter Apps](https://apps.twitter.com/)
- [Google Adsese](https://www.google.com/intl/ja_jp/adsense/start/#)
- [バリュードメイン](https://www.value-domain.com/)[^6]
- [XREA](https://www.xrea.com/)[^7]
- [Filezilla](https://filezilla-project.org/)[^8]

## 初期費用
2000円

## 実装記録

### 1日目
- 他サービスのAPI取得につまずく[^9]
- テストサーバの検討と申請

### 2日目
- 仕様変更、仕様を再度検討
 - Twitter api, カーリル api, Qiita api, Udemy api, BandCamp apiの内容について
- Twitterの短縮URLを展開するには
- Twitter apiの登録は電話番号が必要
- JSONの取得方法
- curl, twurlを導入と使い方を調査

### 3日目
- Pythonで実装することを決意
- Pythonをインストール
- Python Twitter Toolsをインストール
- 取得したJSONの一部をデータベースに格納することを検討
- 短縮URLを展開しなくても元のURLは"expand_url"から取得できることを確認した

### 4日目
- 疲れてねた

### 5日目
- Pythonでif文を学ぶ
- Pythonでlenを学ぶ
- PythonでSQLiteの使い方を学ぶ
- A5:SQL MK-2を使ってテーブルを作成、データを閲覧
- 正規表現を学ぶが使い方に苦しむ

### 6日目
- レコード内容が重複してテーブルにINSERTできない問題が発生、及び対処

### 7日目
- 疲れてねた

### 8日目
- HTMLに書き込むタグの作成

### 9日目
- Twitter apiは"standard"だと7日間分のツイートしか取得できないことが分かった

### 10日目
- Webサイトの調整

### 11日目
- Webサイトの調整
- 独自ドメインの取得
- Webサーバの有料プランを契約
- Google Adsenseの申請

## 具体的な実装方法
下記を参考にするとよい[^10]

### Twitter apiを実行してJSONを取得するには

Pythonは[公式サイト](https://www.python.org/)からインストーラをダウンロードすること
その後、Pythonをインストールする

プログラムの実行はコマンドプロンプトで実行する

```console
python sample.py
```

「Python Twitter Tools」をインストールする

```console:sample.bat
pip install twitter
```

「Python Twitter Tools」を読み込む

```python:sample.py
from twitter import * 
```

「Twitter API」の登録をする
[公式サイト](https://apps.twitter.com/)へTwitterアカウントでログインする
ログインできれば、ユーザーインターフェースがシンプルなのでAPIは取得しやすいかと思う
必要に応じて適宜、GoogleでTwitter apiの登録方法を検索するのもよい
下記の4つの値を取得できれば成功だ[^11]

- CONSUMER_KEY
- CONSUMER_SECRET_KEY
- ACCESS_TOKEN
- ACCESS_TOKEN_SECRET

「ツイート」を検索する

```python:sample.py
from twitter import *

t = Twitter(auth=OAuth(token, token_secret, consumer_key, consumer_secret))

t.search.tweets(q='検索したい単語を入力する')) 
```

検索オプションについては[「Standard search APIのドキュメント」](:https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets.html)を参照するとよい
Twitterを検索する方法については[「Python Twitter Toolsのドキュメント」](:https://pypi.org/project/twitter/)を参照するとよい

### JSONを保存するには

```python:sample.py
import json

# 中略：必要に応じて他の要素と紐づけること

# Twitterの検索結果をresultに格納する(例)
result = t.search.tweets(q='検索する単語')) 

# hogeという名前でJSONを作成して、Twitterの検索結果を書き込み出力する
f = open("hoge.json", "w") 
json.dump(result, f)
f.close()

```

[こちらの記事](:https://qiita.com/Hyperion13fleet/items/7129623ab32bdcc6e203)を参考にした

### Listの展開

JSONにある情報を[Online JSON Viewer](http://jsonviewer.stack.hu/)で確認する。
ここにJSONの中身をコピーして貼り付ければよい
JSONはテキストエディタでは見づらい内容であるが「JSON Viewer」を使うことで
どういうデータがJSONにあるのか視覚的に表示されて便利である

Twitterの検索結果を表示する

```python:sample.py
# Twitterを検索する
result = t.search.tweets(q='検索する単語')) 

# Twitterの検索結果を展開する
for tweet in result['statuses']:
 print('ツイート内容：')
 print(tweet['text'])
```

### 正規表現の使い方

自分が検索した内容でも、思った通りの結果が返ってこない場合があったので
必要な情報を絞る方法を考えたときに「正規表現」が頭に浮かんだので振り返った[^12]

文字列の部分一致
例えば、hogeと検索したときに「hogeは～～である」「hogehoge.com」などと検索結果が出てくる
自分がほしい文字列がURLを示すアドレスである場合は、アドレスとして他の内容と区別できる文字を考える

```python:sample.py
import re

for result in results:
 # .comという文字列が含まれているかを判定する
 if re.search('\.com', result['text'])):
  print("一致")
```

[こちらの記事](:https://python.keicode.com/lang/regular-expression-use-search.php)を参考にした

### データベースにアクセスしたりコミットするには

データベースは「SQLite」を使用する
SQLiteの使い方については[こちらの記事](:https://www.dbonline.jp/sqlite/)が参考になるかもしれない
ここでは標準SQLを使って、データベースにデータを挿入する方法やレコードを検索する方法を振り返った[^13]

データベースを作成する
sqlite3.exeがあるフォルダでコマンドプロンプトを実行する

```console
sqlite3 作成するデータベースの名前.db

sqliyte3>.tables

sqliyte3>.exit 
```

データベースに接続する

```python:sample.py
import sqlite3

# データベースに接続する
con = sqlite3.connect('接続するDB名.db')

# データベースを閉じる
con.close()
```

データベースにコミットする

```python:sample.py
import sqlite3

con = sqlite3.connect('接続するデータベースの名前.db')
cur = con.cursor()

# データベースのテーブルにあるレコードを削除する
cur.execute('DELETE FROM テーブル名')

# データベースにした操作を確定させる
con.commit()

cur.close()
con.close()
```
データベースをPythonで取り扱うには[「12.6. sqlite3 — SQLite データベースに対する DB-API 2.0 インタフェースのドキュメント」](:https://pypi.org/project/twitter/)を参考にするとよい

### Pythonのエラーについて[^14]

エラーが起こるときには、何かしら自分がやらかしたと思った方がいい
コンパイル時のエラーならば、1行ずつコンパイルが通るか試したり、コンパイルが通っていたコードと比較するとよい
実行時のエラーならば、自分の想定できていなかったことがあると思った方がいい

## レンタルサーバとドメインの設定

今回は下記サービスを利用した[^15]

|サービス|採用|
|:--|:--|
|レンタルサーバ|XREA|
|独自ドメイン|VALUE-DOMAIN|

レンタルサーバは何度か利用しているので、利用するのは問題なかったがドメインの設定が初めてなので難しかった
ドメインの設定方法については[こちらの記事](https://www.xrea.com/support/manual/old/domain/domainweb/)を参考にしてほしい
各種サービスの支払いはデビットカードでもできた。しかも即時反映で便利だった

## 追記
* 2018年8月24日に"Google Adsense"の登録が完了した。
* Google Adsenseの広告枠を作るため、Design Blocksを辞めてBootStrapを使ってコード編集することにした。

## 脚注

[^1]: 大きく売上に繋がるから時間を掛けるのは問題ないと思っている。ここでは売ることを忘れて実装内容やデザインに拘り出したときに、今回の目的には見合わないため「本末転倒だ」と言っている。目的が「デザイン」や「プログラム」することに焦点が当てられていれば問題ないかと思う
[^2]: 公式サイトは使い方やコードが簡潔に書かれているため、他のサイトで調べるよりスムーズに実装を進めることができたため
[^3]: 仕事から帰ってきてから実装をしていた、夜中の10時から深夜2時くらいまで毎日頑張って実装していたが、疲れて寝てしまった日もあった、身体は正直であるし精神的にもキツイ。問題に当たったときの冷静な判断力も失われると思われる。逆に睡眠を取れば解決に至れた。
[^4]: エンジニアとして経験のある人や非エンジニア問わず、人に相談することや意見を貰うことは重要かと思った、実際、技術的な解決やロジカルな解決、そして、自分なりのアイディアが浮かんだ
[^5]: 短く見積もっている可能性がある。相談した時間や記録に残していないためだ。5時間～10時間プラスすると丁度よいかもしれない
[^6]: 独自ドメインを取得、Google Adsenseの契約に必要なため
[^7]: 有料のレンタルサーバとして契約、広告表示を消すため
[^8]: Filezillaは[こちら](https://ja.osdn.net/projects/filezilla/)から取得したかもしれない、Filezillaをインストールしたのはだいぶ前だから記憶にない。
[^9]: 実は最初、違うWebサービスを作ろうとしていた。途中でサービス内容を変更した
[^10]: 実際に作るときはドキュメントの書き方をベースにして考えつつ作りたい内容を実装している。本当に自分のコードが有益であればソースコードを売ることも検討してみるかも
[^11]: 4つの値を公開しないように注意すること。Googleで検索しても実際の値が例として出てこないのはそのためだと思う
[^12]: 自分は正規表現を理解していないので、必要に応じて調べてみることをオススメする
[^13]: ここでの目的はTwitterで検索したデータをどうやって格納するかについて考えることだったので、SQL構文を扱うことや、SQLiteのツールを詳しく扱えることが目的ではないことを断っておく。今回の場合ならデータを挿入するINSERT文やテーブルを作るCREATE文が分かればよい。そしてPython上でデータベースを取り扱えることができれば、検索した値をデータベースに挿入できるだろうと考えた
[^14]: Pythonのエラーが起こったときの参考になればと思う
[^15]: 採用基準は価格が安いこと、レンタルサーバは無料でもPHPなどプログラミング言語をサポートしていたのでテストサーバとして使えたためだった。今はリリースに向けて有料版に切り替えている。ドメインはGoogle Adsenseを申請するのに必要と学んだためだ。レンタルサーバと同じ会社でドメインも発行していたので買った