Paper Crawler (download pdf)
created_at: 2024/11/12 23:30:00
一個微服務架構實作的論文爬蟲系統,這個系統每個服務都可以單獨運作、部署,方便擴充支援的網站。
為什麼會有這個服務
...有人有需求,於是我想了想,這樣可以解決問題,然後我想說當練手,於是這個服務就誕生了。
Demo
大概說明一下:
- 一開始要輸入一串預先產好的
token
做最最基本的防禦(因為畢竟還是有public
到網路上,雖然沒有給其他人) - 爬取過程有機會失敗,若失敗會有相應的錯誤訊息(
timeout
、something went wrong
等等),若是something went wrong
的話,有可能的問題很多,所以要看一下log
才能知道是什麼問題,但不方便透露給前端,所以就只有something went wrong
這樣的訊息,但失敗不影響服務的運作 - 爬取成功後,可以預覽或是下載
PDF
檔案- 預覽是打開新分頁(
blob
)顯示PDF
檔案 - 下載是直接下載
PDF
檔案(檔名會正確) - 註1
- 預覽是打開新分頁(
- 使用者重新整理頁面會保留當前的狀態,但如果使用者整個
session
都關掉,就會回到最初的狀態- 這邊使用者定義為同一個
real ip
- 這邊使用者定義為同一個
註1: 為什麼不預覽然後讓使用者直接 Ctrl + S
呢? 為什麼還要多做一個下載的按鈕?
簡短來說是為了提高下載的 UX
,細節的話主要是因為我的檔案也有受到 token
的保護,所以除非我在後端特別做一些比較麻煩的處理,不然如果透過單純預覽的方式下載,檔名會是 blob
,這樣對於使用者下載的 UX
來說不太好,所以額外提供一個下載的按鈕,就可以透過 Content-Disposition
來取得正確的檔名。
- 其實有兩個下載的按鈕,下拉選單本身也是
Source code
目前沒辦法公開,有兩個原因:
- 我還沒整理好
code
畢竟是這種服務,公開讓大家去爬蟲的話,好像不太好(雖然需要帳號)
但我可以放上架構和一些實作流程(?)
Tech Stack
Frontend
:Svelte 5
、Tailwind CSS
、EventSource
Backend
:Gin
、gRPC
、Python
、RabbitMQ
CI/CD
:Github Actions
沒有資料庫,因為並不打算做資料的儲存,重啟服務後又和乾淨的一樣。
宏觀的系統架構
這個架構圖省掉了一些細節,主要是呈現可以輕易的擴充服務的部分。
另外 Auth
的部分其實可以與 Audio
服務整合成一個服務,因為在這個系統中並沒有其他服務去使用 Audio
(聲音轉文字)的功能,但為了當作練習(?)所以刻意將它分開。
接著我們來看看細節,還有為什麼可以方便擴充服務。
實作流程
既然是爬蟲服務,最主要的當然就是爬取的流程,所以先附上爬取流程的圖片。
這些爬蟲服務的流程都是一樣的,只是不同的服務有不同負責的網站,而每個服務都會去消費 RabbitMQ
的 Queue
,當有新的 URL
進來時,就會去爬取資料。
爬取的流程,一開始會先去初始化 WebDriver
,然後以 MultiProcess
的方式去執行爬蟲的流程,這樣還可以來監聽執行的時間,如果超過一定時間就會強制結束,避免爬取的時間過久。
而爬取的細節則與流程圖一樣,比較重要的是當爬蟲結束後會將登入的狀態保存下來,這樣下次爬取時就不用再重新登入,這樣不只可以節省一點時間以外,還可以防止被網站鎖住(?)
接著還會需要 Auth
的部分
Auth
的部分其實和爬蟲的部分差不多,只是在多了 Retry
的機制,避免 Audio
服務去得到的驗證碼有誤,這樣就可以重試。
然後也一樣有儲存登入狀態的機制,避免每次都要重新登入。
為什麼可以方便擴充服務
每個爬蟲服務都是獨立的,所以只要新增一個服務,然後將一樣去監聽 RabbitMQ
的 Queue
,就可以開始爬取資料。 (並且建立屬於自己的 Queue
)
另外爬蟲的部分有實作一個抽象類別並實作 Template Method
,這樣可以讓每個服務去實作自己的爬取流程,也不用擔心 Auth
與 Timeout
等等的細節,只要聚焦在自己負責的網站身上,也就是上方流程圖當中 Start crawling documents
的部分。
後端也會透過 RabbitMQ
的 API
來取得目前的 Queue
來得知目前支援的網站,這樣就可以在前端動態的顯示支援的網站,並且在使用者送出 URL
時,也可以檢查是否支援。
最後是部署也是獨立的,各服務有自己的 Environment
設定、Dockerfile
。
方便擴充服務的驗證
2024/12/12更: 時隔一個月,新增服務支援 Springer
平台,前後端一行 code
都沒動,只微調了 docker-compose
(加一個服務) 與 CI
的一個 job
(確保生成的程式碼由程式產生(grpc
))。
未來展望
這個服務的重點大概就這些了,如果未來有時間會想做的更完整一些,例如:
- 使用更好的服務發現的方式(
etcd
),讓服務可以自動加入,也能增加冗餘,增加服務的可用性 (目前是Docker Compose
)- 還可以在前端顯示服務的狀態
- 增加資料庫,讓爬取的狀態更完整並即時顯示在前端
- 前端的
Retry
機制 (因為沒有DB
,實在很不想每個去跑for
- 增加
Rate Limit
的機制 (因為目前沒有公開,所以沒有實作;若公開的話,這個機制是很重要的)如果公開也許還可以做quota
的機制來收費
- 使用
Kubernetes
來部署: 來達到更高的穩定性 - 使用
Prometheus
+Grafana
來監控服務
暫時想到的就這些(?) 可能有忘掉的地方
主要還是礙於時間論文的壓力,所以這個服務就先這樣了,有機會再來完善。(如果未來有機會沒事做沒題材的話)