下町柚子黄昏記 by @yuzutas0

したまち発・ゆずたそ作・試行錯誤の瓦礫の記録

PCが入るバッグを検索するWEBサービスを作りました

概要

f:id:yuzutas0:20150708203235p:plain

もくじ

  • どんなサービスか
  • どうやって使うのか
  • なぜ作ったのか
  • どうやって作ったのか
  • 思ったこと

どんなサービスか

  • 持ち運びたいノートPCを選ぶと、そのPCより大きいバッグを一覧表示します。
  • 名前は「PCが入る(ハイル)バッグを検索(サーチ)する」という語感決めです。

注意点

  • PCでのWEBブラウザ閲覧を推奨します。スマートフォンだと閲覧しにくい箇所があります。
  • Amazonの商品画像はアソシエイト用途でのみ利用可能という規約があったので「商品詳細を見るボタン=Amazonへのアフィリエイトリンク」という体裁を取っています。問題があればご指摘いただけると幸いです。

f:id:yuzutas0:20150708203132p:plain

どうやって使うのか

  • HileSearchにアクセス。
    • 持ち歩きたいPCのブランドを選択(例:Mac)。
    • PCの機種を選択(例:MacBookPro Retina 15inch)。
    • バッグが一覧表示されます。
  • さらに条件で絞り込み
    • 種類を選択(例:メンズのショルダーバッグ)。
    • 並び順を選択(例:価格が安い順)。
    • 検索ボタンを押下。
  • バッグを選択
    • 回遊しながら良さそうなバッグを探す。
    • 「詳しい情報を見る」を押してAmazonの商品紹介ページに遷移。
    • 気に入ったらAmazonなり店舗なりで購入。

なぜ作ったのか

  • 技術学習のためです。バッチ処理スクレイピングを練習したかったので、手持ちのアイデアの中から練習に向いているものを選びました。
  • また、事前準備ができていたからです。「鞄を探すサービス」というアイデアは昨年の秋から持っており、紙モックで見込みユーザーに軽くインタビューをしていました。コンセプトが固まっていたので、開発に専念できました。
  • 何よりも、自分自身が使いたかったからです。新しいPCを最近入手したので、持ち運びに適したサイズの鞄を探したいと考えました。

どうやって作ったのか

  • 以下の手順を踏みました。

    1. 企画:ペルソナ、課題、解決策、インタビュー、ピボット
    2. 開発:要件定義、設計、製造、テスト、チューニング
    3. リリース:環境構築、資材配置
  • システム構成は以下の通りです。

  • 基本的にはEnokilogと同じ流れです。

yuzutas0.hatenablog.com

企画

  • 最初は女性向けの想定でしたが、ヒアリング途中で方向転換しました。
  • なお、もともとは私のアイデアではなく、新規事業を考えようという有志の集まりで考えた素案の1つです。

初期想定

  • Customer:サイバーエージェント女子やリクルート女子。ノートPCを頻繁に持ち運ぶが、可愛い鞄を好むので、「見栄えの良さ」と「PCを持ち運べること」を両立したい。
  • Problem:欲しいバッグに自分のPCが入るかどうか調べるのが大変。店舗で聞いても「A4なら入る」程度の情報しか手に入らない。
  • Solution:バッグとPCを入力すると入るかどうか分かるスマートフォンアプリ。

インタビュー

  • 紙のモックアップ(いわゆるペーパープロトタイプ)を作成して、老若男女問わず約20人にヒアリングを実施。
  • IT系イケイケ女子は、PCが入ろうが入るまいが欲しいブランドのバッグは買う。課題感が弱い。
  • 普段からPCを持ち歩くのは外回り営業、就活生、IT系企業勤務やフリーランスのプランナー職/エンジニア職。
  • 特にIT系/フリーランス:人によってはAmazonでサイズを見比べながら良さそうなバッグを買うこともある。

ピボット

  • Customer:対象は比較的自由な風土のIT系企業に勤める人/フリーランス
    • 普段からノートPCを持ち歩いている。
    • 鞄をネット通販で買ったり、ネットの情報を参考にして店舗で買うことに抵抗がない。
  • Problem:PCを持ち運ぶバッグを探そうと思っても大変。
    • 店頭で買おうと思っても、自分のPCが入るかどうか絶妙なサイズのことが多い。
    • ネット通販で買うときに、サイズをいちいち見比べるのが面倒臭い。
    • 初めからPC用バッグを買えば確実だが、見た目のバリエーションが少ないと感じており、できれば広い中から探したい。
  • Solution:自分のPCを入力すると、入るバッグが出力されるWebアプリ。

バッチ開発

  • まずはPC/鞄の情報を取得してDBに入れるためのスクリプトを作りました。

設計

  • DB設計
    • Input:スクレイピングで取得できるデータを確認しました。
    • Output:後述するワイヤーフレームから必要なデータを整理しました。
    • I/Oを元にデータフローとDBを設計しました。
  • クラス設計
    • 事前に見通せない点が多かったので、綿密には設計しませんでした。
    • 小さなコードで試しながら、徐々に設計を修正・確定しました。
    • 徐々にレベルアップできるよう、実装の順番は決めておきました。

製造

  • PCのスクレイピング
    • Appleと価格コムからノートPCの名前とサイズを取得する処理を書きました。
    • どちらもデータ構造が明確なのでライブラリの動作確認に最適でした。
  • 鞄のスクレイピング
    • Amazonからバッグの各種情報を取得するスクリプトを作りました。
    • サイズ(縦*横*高)のフォーマットが統一されていないので、正規表現と分岐処理を組み合わせて、複数パターンの記載場所や表現方法に対応しました。

テスト

  • 小さく作り、小さく試し、エラーが出たらすぐ直す、という検証を繰り返しました。
  • 素早く動作確認するのが苦しくなる度にメソッドやクラスを分割しました。

チューニング

  • 繰り返し繰り返し、設計/実装/試験を行き来することで、少しずつ処理を改善していきました。
  • 例えば、Amazonは頻繁にアクセスエラーを返します。公式のProduct-Advertising-APIでも類似事象があるらしいので、そういうものと割り切ってリトライやスキップの処理を追加・調整しました。
  • また、Amazonからバッグのサイズ(縦*横*高)を取得するにあたって、いきなり完全な処理を作るのは難しいと判断して、チューニングしやすいようエラーログを設計しました。エラーログの確認と正規表現+分岐処理の改善を繰り返して精度を少しずつ上げています。まだまだ完璧ではないので、サイズが違っていたり、アルゴリズムの改善方法を見つけたらぜひ教えていただきたいです。

アプリ開発

  • バッチ作成後に、PCから鞄を検索するWebアプリを作りました。

設計

  • ユースケース設計
    • 必須機能を整理しました。
    • シンプルに「PCを選ぶ/バッグを表示する/絞り込む」といった形です。
  • 画面設計
    • 必須機能を満たすワイヤーフレームを紙に書きました。
    • ただ、実装中の画面をドヤ顔で知人に見せた際、遷移が分かりにくそうな反応があった箇所は修正しました。テンション駆動型ユーザーテストです。
  • CSS設計
    • 苦手意識があったので、確実に保守性とスピードを担保できるよう「共通化を避ける」という工夫をしました。すべての要素に一意となるCSSセレクタを指定して、それぞれ別々にCSSを適用させています。
    • ちょっとレイアウトを変えたくなったときに、CSSのどこを変更させれば良いかすぐに分かります。また、変更したときに他の要素が崩れる心配もありません。
    • 中途半端に共通化して、中途半端に変更しにくくなって、中途半端に嫌なデザインになって、結果として開発のモチベーションが下がってしまうくらいだったら、この方がマシだと判断しました。
/* 共通化しない! */
.bag_items_card .icon_char {
    font-size: 11px;
}
.bag_items_search_tag_form p {
    font-size: 11px;
}
.bag_items_search_price_form p {
    font-size: 11px;
}

製造/テスト

  • 製造
    • PC選択:PCリストの表示、submitで画面遷移。
    • バッグ閲覧:条件に合うバッグの表示、検索絞り込み、ページネーション。
  • APFWの理解不足問題
    • ActiveRecord:PCとバッグのサイズ(縦/横/高の組み合わせ)を計算するクエリが書けず...。SQLなら書けるのに...。結局、スクリプトで事前に「大きい値」「真ん中の値」「小さい値(nullの場合もある)」という3つのカラムに振り分け、その大小でバッグにPCが入るかどうかを判定しています。
    • ERB:Formが思うように書けず...。HTMLなら書けるのに...。というわけで、割り切ってERBで出力されるHTML相当のものを直書きしました。
  • テスト
    • ブラウザで一通りのテストを行いながら、バグやデザインを修正しました。
    • フォームやルーティング、ActiveRecordの負荷あたりは重点的に確認しましたが、まだ改善余地があるかもです。
    • テストコードを書かない悪弊はどうにかしたいですね。

リリース

  • システム構成はEnokilogと同様(CentOS/Apache/Passenger/MySQL/Rails)です。
  • データ移行やコンパイル周りでトラブルシューティングに一手間を費やしました。

環境構築

  • インフラ/ミドルウェアの環境構築は、Enokilogとほとんど一緒です。
  • 唯一違う点として、今回はSSL証明書が不要なので該当作業はスキップしています。

資材配置

  • クローラーの取得データを開発環境用SQLiteからDumpして本番環境にImport。
    • SQLiteで問題がなかったので全く確認していなかったですが、String指定なのに255文字以上のデータがあり、MySQLのvarchar2(255)からはみ出ました。スクレイピング時にバリデーションと整形をすべきでした。
    • また、バッグの高さが大気圏を突破しているデータがあり、MySQLのInt型からはみ出ました。サイズを取得する際の正規表現で変なのが引っかかったようです。
  • Assets:precompile を通すために試行錯誤。
    • 心が折れたのでローカルでコンパイルしてから本番環境に乗せました。
    • 反映後も画像ファイルやfont-awesomeのリクエストでフィンガープリントが反映されない問題など順次対処。

思ったこと

  • 進め方
    • Enokilogでの反省を活かして、小さく検証しながら改善したり、保守しやすい設計を心掛けました。一歩改善です。
    • ただ、チューニングやトラブルシューティングに想定以上の時間が掛かりました。時間が掛かること自体はやむを得ないといえばやむを得ないですが、10分だけ試してみて、それでダメだったら「明らかにベストではないけど一応解決はできる案」で妥協するといった線引きができていませんでした。
  • システム
    • 特にAPFW(Rails)に関する知識不足が足を引っ張りました。きちんと内部設計や事前学習に時間を掛けるべきだったと思っています。
    • とは言え、やってみて失敗して少しずつ理解が深まるという側面もあるのと、学習自体を目的化してしまうとなかなか進まない気もするので、何とも難しいところです。
  • プロダクト
    • 実際に自分で使ってみたところ、改善点が山ほど出てきました。「このサービスで探して本当に買うぞ」という気持ちでサイトを開き、形になったものを直接触ってみて、ようやく気付けたことだらけです。
    • 絞り込み検索でボタンを大量に押さなければいけない、PCだけじゃなくてスマホで見たいけどレイアウトがひどい、候補のバッグを比較しにくい、ページングしすぎて面倒臭くなって結局Amazonを開いてレコメンドから遷移してしまう、全体的にレスポンスが遅い、実際に買おうとすると価格>見た目>購入者レビューの順で情報を見ている(だけどHileSearchだと画像1枚のみ表示/レビューは表示していない)などなど。
    • ちょっとずつ直していきたいなーと思います。

最後に

  • 長くなってしまいましたが最後まで読んでいただき本当にありがとうございます。
  • 改善点やご意見など、何かあればコメント欄やGithubTwitterでご指摘いただけると嬉しいです。
  • 指摘された点や自分で使ってみて気になった点はIsuueに挙げていこうと思います。

その後の改善報告

yuzutas0.hatenablog.com