2020-05-08に投稿

副業求人の横断検索サービスで利用した技術について

はじめに

こんにちは。かつおです。個人開発が趣味でがんばってます。

この記事では先日リリースしたWebサービス「副業サーチ」の利用技術やシステム構成を書いてみました。
* 開発者の想い的なNoteはこちら

副業サーチとは?

image
副業サーチのサービスのURLはこちら

色々なWebサイトに掲載されている副業求人、副業案件を収集し、まとめて検索できるWebサービスです。
いわゆる横断検索サイトで、副業特化の「Indeed」のようなサービスです。

副業サーチは以下の階層で構成されてます。
* トップページ
* 副業の検索ページ
* お役立ち記事一覧ページ
* お役立ち記事詳細ページ

システム構成・利用技術

image

副業求人検索

  1. Webサイトをクローリングして副業案件データを収集。
  2. PythonのScrapyを使ってスクレイピング
  3. 収集したデータをちょっと加工(タギング、データの正規化)
  4. 全文検索エンジン(Elastic Search)へインデックス

あとはフロントから検索APIを叩いて結果を表示している感じです。
直接ブラウザから呼ばずにFirebase Functions経由で読んでいます。

記事コンテンツ

  1. ヘッダレスCMSのContentfulで記事編集
  2. Gridsomeでビルドする際にデータを全部取ってきて、静的ページとしてビルド

使っている技術・選定理由・感想

スクレイピング ⇒ Scrapy

スクレイピングしたデータを加工する際に、自然文処理みたいなことに手を出す可能性を考えて、Python製のものを使いたいなと考えました。使ってみて、かなり使い勝手が良かったので採用しました。

Scrapyはスクレイピング処理を構築するフレームワークで、かなり便利でした。
スクレイピングやるのにフレームワーク使ったのは初めてです。
個人的に便利だと感じたポイントです。
* クロールしたデータをローカルにキャッシュし、再クロール時はキャッシュを参照してくれる
* 開発時に何度もサイトにアクセスすることを防げます。
* もちろん保存期間は設定ファイルで自由に設定可能
* CSSセレクタでデータを取ってきて、データ加工して、保存するみたいな流れがFWで定義されていて、処理の共通化や追加が楽
* 個人的にPythonで書いたコードは読みやすい(対js比)

データのタギング

スクレイピングで取得したテキストデータからタグを抽出したいというものなのですが、ちょっと試行錯誤しました。

実験して没にしたもの

NTTコミュニケーションズ製のCOTOHAのキーワード抽出API

取得結果が私のほしいものに合わなかったので見送りました。

例:「 【リモート可】アパレル業界から医療関係まで、お客様の「強み」を最大限に生かすシステムの受託開発をするバックエンドエンジニアを募集!」

取得したいタグ:
* エンジニア(または、バックエンドエンジニア)

COTOHA APIだと↓
1. 募集
2. 強み
・・・

まあ、文章的には何かを募集する文章だから、「募集」が1番強いキーワードだよな、なるほどと思いました。用途が違う使い方のようです。

採用したやり方

  • スクレイピングしたテキストデータをmecab(neologd辞書利用)で形態素解析
  • 形態素解析した結果の語をもとに2gramで語抽出
  • 人力で用意した辞書(キーワードと付与するタグの一覧)のキーワードに、上記で抽出した語が完全一致でヒットした場合に、タグ付与

泥臭いやり方になってしまってますが、こんな感じで頑張ってみました。辞書は日々メンテナンスしています。

今思うと...、neologdは単語には強い一方で細かく分割されない特徴があります。今回は分割した語に対して、さらに2gramでくっつける処理を入れているので、形態素の段階では細かく分割された方がいいような気がしました。neologdやめたほうがいいかもな。

全文検索 ⇒ Elastic Search(Elastic Cloud)

私はケチなので、サービスの運用は無料にこだわっているのですが、ElasticCloudを採用しました。ElasticCloudに無料枠はありません。最低16ドル/月で利用できて、副業サーチの構成だと19ドル/月です。と言いますか、ElasticCloudはインスタンスを立てるリージョンを選択する必要があり、東京リージョンの最安構成が19ドル/月です。

Elastic Cloudを採用するまで

ケチなので、サービスのアイディアが浮かんだときからElasticCloud使ったろと考えたわけではありません。

firestoreで実現できないか試した

まずは、いつも使っているfirestoreでできないか考え、データを突っ込んで検索処理を動かして画面で確認するところまで実装してました。
Firestoreで全文検索を実装する方法は、こちらのQiita記事の方法を使ってます、

実現したいこと 実現可否 備考
全文検索 Qiitaの方法で実現可能
全文検索 + タグ絞り込み(and) Qiitaの方法で実現可能
全文検索 + タグ絞り込み(or) × 無理(or検索の仕組みがない)
全文検索 + ソート × 無理(全組み合わせの複合インデックスが必要)
全文検索 + 関連タグ取得 × 悩んだがいい案思いつかない

実現したいことは以下

  • 全文検索 + ソート

    • 検索結果を新しい順(案件の公開日順)で表示したい
  • 全文検索 + 関連タグ取得

    • 検索ヒットしているデータについているタグを取得したい
    • できれば、タグに紐づくデータの多い順で取得したい

実際にやりたいことを検証してみて、できないこと多かったので、厳しいなぁと感じました。

代替のサービスを探す

私は技術力が高くないので、自分でサーバを立てて、全文検索エンジンをインストールしてみたいなのは無理だと考え、最初から除外しました。サーバーレスでやれるサービスがないか検討しました。

そうなると、候補は以下2つしかない?のかなと
* Elastic Cloud
* Algolia

Algoliaは別サービスでも使った実績があったのですが、今回はElasticCloudにしました。理由は「料金が安い」と思ったからです。Algoliaは無料枠はあるのですが、無料枠使いきると従量課金で、レートがかなり高い..私のサービスでAlgolia使ってるものもありますが、検索がメインのサービスではなく補助機能で使っている程度なので、無料枠に収まってました。

しかし、今回のサービスは検索が命のサービス。無料枠に収まらなくなったら地獄だと考え、月19ドルを払う決心(と妻への説明)をしてElasticCloudを採用しました。ElasticCloudは14日間の無料体験ができるので、それを利用して、実現したいことが実際にできるか動かして試し、全部できるじゃん!と確認できたので採用となったわけです。

フロント(検索UI・記事) ⇒ Gridsome

あまり使ってる人を聞かないのですが、Vue.js製の静的サイトジェネレータ「Gridsome」を使ってみました。React製静的サイトジェネレータで人気のGatsbyのVue.js版のようなフレームワークです。

Gridsomeを見つけたきっかけは、運営者ギルドの方がGatsbyを紹介してくれてたことでした。Gatsbyによって静的サイトジェネレータの存在を知り、これは便利そうだなと調べてたところ、自分が普段使っているVue.js製のGridsomeを見つけたという流れです。

採用した理由

今までいくつかサービスをリリースしてきましたが、どれもVue.js製でSSRなしで構築していました。Nuxt.jsも使った経験なし!

サービスを運用して毎回課題に感じるのが、SEOで弱いことです。

もちろんGoogleのクローラーはJavascriptの実行結果を評価しているというのを知っていますし、信じているのですが、事実としてSEO弱いと感じてます。(フレームワークの問題ではなく、私のサイトのコンテンツの問題な気もしますが)

この不安を今回は無くしたいと考え、静的サイトジェネレータ「Gridsome」に手を出しました。

といっても、検索部分は静的サイトじゃない。トップページと記事系のみ!

検索ページ以外が静的サイトになりました。
中途半端です。
しかし、記事系だけは完全に静的サイトになったので、ページの表示も速く満足しています。
トップページも静的サイトになっています。
SEOを意識した記事を追加していけば、なんとかなるはずだ。(記事が書ければ...)

記事系のページの表示は爆速になったので、ぜひ表示してみてくださいね!

でも、横断検索サービスのSEOって検索ページで狙うべきじゃね?って思うようになってきて、微妙な対応だったかなと思ったりしています。

記事のCMSはContentful

ヘッダレスCMSのContentfulを使ってマークダウンで書いてます。個人開発なら無料枠で大丈夫そうです。無料枠だと1アカウントしか作れないので、チームで運営する場合は問題になりそうです。
Contentfulの記事をGridsomeに連携する構築については、Qiitaのこちらの記事を参考にしました。

Gridsomeにしてどうだったか?

SEO効果は分かりませんが、ページの表示は速いので満足しています。

ただ、ビルドすると思った通りに動かないことがありました(ビルド前は問題ないのに!)。ビルドした後のテストがけっこう重要で、うまく動作しないパターンに慣れるまではそこが面倒かもなと思っています。

さいごに

色々と調べつつ利用する技術を選定して構築しました。今回は新しい技術けっこう使った気がするなぁ。
ElasticCloudとGridsomeはかなりいい選択だったのではないかと思ってます。運用してみて見えてくる点もあると思いますので、なにかあれば記事にしたいと思います。

それでは副業サーチをよろしくお願いします!

ツイッターでシェア
みんなに共有、忘れないようにメモ

かつお

都内のWebベンチャーで企画やってます。 Vue.jsとFirebaseで趣味でWebサービス作ってます。2019年は3サービスリリースしました! カライイネ 運用中! セールサーチ(https://sale-search.site)... 平成年表(https://heisei.me)...

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント