功能介紹
做為一個爬蟲比價網站,搜尋、排序這兩個基本功能是一定要有的
登入會員後可以使用收藏功能,導覽列會顯示目前收藏幾本書,點擊它可以看到目前的收藏列表
待優化的部分
- 收藏清單可以自行增加:比方有一類專門放課外書籍、有一類專門放原文書相關等,讓使用者根據需求調整
- 無搜尋結果時,幫使用者改變關鍵字:上蝦皮網站時發現,要是輸入的關鍵字找不到任何匹配結果,網站會幫你換成其它相關關鍵字,盡可能幫使用者找尋商品
- 篩選條件新增資料來源:使用者可勾選只想要博客來的書籍搜尋結果
- 在商品資訊附上更新時間
實作新知分享
這段過程運用到一些新的東西,像是編碼、在資料庫使用regex、node-mailer、cheerio等,以下分享一些實作後學到的新知識:
- bulkCreate 原來可以設定 updateOnDuplicate
爬資料的時候希望重複編號的書籍就不寫入資料庫,之前用過 findOrCreate 可以達成這件事,但這是新增單筆資料的方法,如果是用bulkCreate 新增大量資料要用什麼方法呢?
在stackOverflow查到這個方法,用bulkCreate時可以設定 updateOnDuplicate 這個選項並放入要更新的欄位。預設是以primary key作為判斷是否重複的基準,如果資料表有unique index則以它作為duplicate key
Book.bulkCreate(result, { updateOnDuplicate: ['name', 'img', 'price', 'discount', 'stock', 'author', 'url', 'StoreId', 'updatedAt'] })
2. 善用 referer 可以增加使用者體驗
在還沒登入前如果按下收藏按鈕會被導入登入畫面,輸入帳密後會被導回首頁,我希望使用者能夠導回它登入前的畫面要怎麼做呢?
在登入頁面儲存 referer (referer 就是被導入登入畫面前的頁面)並一併用表單送到後端。
前端表單加入這行 (view template我使用的是 handlebars)
<input type="hidden" name="referer" value="{{referer}}">
後端邏輯
if (referer && referer !== 'undefined' && referer.slice(-7) !== '/signin' && referer.slice(-7) !== '/signup') { return res.redirect(referer)}return res.redirect('/')
3. Error: read ECONNRESET 如何解決?
在更新資料庫的時候,常常遇到這個報錯,查了一些資料發現是因為同時送太多請求到網站而導致此錯誤,因為篇幅有點長,我另外寫了一篇文章,有興趣的可以參考看看。
過程中的抉擇
- 要不要使用資料庫?直接回傳爬蟲的資料 vs. 先存到 DB 再回傳
一開始有想說要不要直接回傳爬蟲結果到前端渲染,因為這樣可以確保資料都是最新的,但假設今天有很多使用者都搜尋同樣的關鍵字,一直發送請求會造成他人伺服器的負荷,且爬蟲耗費的時間比查資料庫的時間更長。
因此最後決定將爬蟲結果先存到資料庫,接著使用者要查詢的資料如果已經在資料庫就先回傳,沒有才會進行爬蟲。此外也會將每次使用者搜尋的關鍵字用findOrCreate存起來,每天定時爬蟲更新資料。
實作心得
這次的side project我是一個人處理前後端,和上次協作專案相比,雖然對專案的掌控程度比較高,不過也容易分心,因為除了要花時間處理資料以外,也要思考前端的排版怎麼呈現。
在這次的專案我想最有感的就是「搜尋功能不好做呀」,過往覺得搜尋只是把含有關鍵字的資訊找出來就好,但這次專案發現有很多細節要注意,比方如果包含非英文的關鍵字要先進行編碼、如果關鍵字含有空格要先進行字串切割,再運用regex比對等等,目前採用的方式比較偏向精確搜尋,精準度高,但缺點是資料量少且無法容錯。
有觀察到蝦皮他們是以精確查詢為主,模糊查詢為輔,比方搜尋「起頁管理」時,網站會自動幫你搜尋「企業管理」的結果,這種搜尋結果是我希望專案可以達到的目標,未來會繼續朝這個方向努力。
這次專案大致告一段落,目前還在持續優化,很高興能夠用所學解決生活中遇到的麻煩。
以上就是這次專案的心得,有任何意見反饋都歡迎留言告訴我!