아카이빙 프로젝트 회고

Y·2023년 5월 15일
0

프로젝트

목록 보기
3/5

개인적으로 지인분의 소개를 받아서 외주 비슷한 프로젝트를 진행하게 됐다. 서비스 종료가 예정된 웹사이트의 데이터를 아카이빙하는 작업이었는데, 작업을 맡기신 분이 웹 관련으론 전혀 아시는 바가 없었기 때문에 여러 고민이 있었다.

우선 의뢰자분께서 부탁하신 것은 해당 사이트의 자료를 백업해주는 것이었고, 티스토리의 경우 스킨 수정이 비교적 자유로우니 티스토리 활용을 생각하고 계셨다. 그런데 찾아보니 티스토리는 일일 게시물 업로드 제한이 있었고, 해당 사이트에 있는 게시물들은 약 1800여개였다. 티스토리에 자동으로 게시물 업로드를 매일 꼬박꼬박 하더라도 너무 오랜 시간이 걸리기 때문에 티스토리는 사실상 불가능했고, 그러면 직접 웹사이트를 구현하는 방법뿐이었다. 의뢰자분께 여쭤보니 웹사이트를 직접 구현하는 것도 괜찮은데, 유지 비용은 적게 들어가는 쪽으로 하고싶다고 하셨다.

그래서 가장 간단하게 고려해볼 수 있는 것은 CMS를 활용한 무료 호스팅 서비스였는데, 예컨대 제로보드나 워드프레스를 쓰는 것이다. 이전에 제로보드를 써본 경험은 꽤 있기 때문에 이렇게 하면 사이트 구현 자체는 매우매우 간단하고 관리자 페이지도 자동으로 형성되니 의뢰자분이 사이트를 관리하기에도 편할 것이라는 생각이 들었다. 그런데 무료 호스팅 서비스에는 DB 용량이나 트래픽 제한이 있었고, 이 제한으로는 사이트 운영에 불충분할 것 같아서 이 부분이 가장 걸렸다. 또한 데이터를 긁어와서 DB에 저장을 어떻게 해야할지도 잘 떠오르지가 않았다. (지금 생각해보니 MySQL이 같이 있으니까 여기다가 바로 저장을 하면 됐을 것도 같은데 왜 그때는 이걸 못 떠올렸는지..?? 아주 오래 전에 항상 그냥 간단한 게시판 정도만 만들었어서 그런 것 같다.) 사실 뭣보다 제로보드를 쓴다고 가정했을 때 제로보드는 PHP 기반인데, PHP는 기억이 잘 안 나서 망설였던 것도 있다.. 아무튼 그래서 CMS를 활용하는 방안은 포기했다.

사실 그러고나니 남은 선택지는 하나였다. 직접 웹사이트를 구현하는 것이었다. 의뢰자분께 여쭤보니 관리자용 페이지는 굳이 없어도 된다고 하셔서 그냥 아카이브용 페이지만 만들어도 될 것 같았다. 유지 비용은 적게 드는 것이 좋다고 하셨으니 최대한 무료인 방향으로 하려고 했는데, AWS는 프리티어를 쓸 수는 있지만 기한이 한정돼있으니 안 됐고, vercel을 이용하면 되겠다 싶었다. 그러다보니 DB는 당연히 외부에 있어야 했고, 사용하기도 편리하게 MongoDB를 사용하는 걸로 결정했다. 사실 웹을 통해 접속할 수 있는 atlas의 존재가 기술 스택 결정에 가장 결정적이었지만, 데이터 특성상으로도 게시글, 댓글, 사진 등을 다 저장해야하고 답글까지 저장하다보니 배열 형식의 저장이 꽤 많이 필요해서, RDBMS로 만들기보다는(물론 RDB로도 만들려면 만들수야 있겠지만..) NoSQL로 하는게 훨씬 간편하고 편리할 것 같았다.

그런데 또 고민이 생겼다. vercel을 이용해서 배포를 해 본적이 있긴한데, vercel은 프론트단을 배포하는 거고, 외부 DB를 사용해서 데이터를 받아오려면 당연히 API를 사용해야하고, 그러면 백엔드단은 또 따로 배포를 해야하나..? 그냥 한 번에 만들 수는 없나..? 싶어진 것이다. (당연히 백엔드를 구현하는 것 자체는 어렵지 않지만 그러면 서버를 따로 또 배포해야해서 그게 문제였다.) 해서 주변에 도움을 요청하니 next.js를 사용하면 api도 만들어서 사용할 수 있다고 했다! 기존에 사용해본적은 없지만 react와 크게 다를 것이 없다고 해서 그러면 구현은 next.js, DB는 MongoDB Atlas, 배포는 vercel으로 하는 것으로 결정했다.

  1. 크롤링
    이번 프로젝트의 경우엔 크롤링이 맞는지 스크래핑이 맞는지 정확하게 잘 모르겠지만, 일단은 크롤링으로 작성한다. 사이트 종료가 예정되어있었기 때문에 일단 데이터 백업이 중요했다. 크롤링을 하려고 사이트를 들어가서 코드를 확인해봤는데, 페이징 방식이 아니고 무한 스크롤 방식으로 돼있었다(...) url에 페이지를 띄우는 식도 아니어서 이것도 문제였고, 그리고 각 게시물의 본문과 댓글을 읽어와야하는데, 각 게시글의 태그가 a로 돼있는게 아니었어서, (아마 모달이 뜨는? 형식이어서 그랬던 것 같다...) 링크를 긁어서 크롤링 할 수 있는 구조가 아니었다. 애초에 각 게시물의 url 링크도 따로 받아올 수가 없었다... 그래서 고민을 하다가 결국 selenium을 사용하게 됐다.
    XPATH를 활용해서 각 게시글을 클릭하게 하고, 그 후에 본문 내용과 댓글 내용을 저장하는 식으로 했었는데, 중간중간에 에러가 정말 많이 떴다. 아무래도 selenium을 활용하면 전체적으로 자동화가 되다보니, 다른 것보다도 스크롤 위치등에 따라서 element를 못 찾는 경우가 대다수였다. 이미지를 저장할 때도 이미지가 로딩이 덜 돼서 로딩중 이미지가 저장이 될때도 있었고... scroll_to_element를 활용하면 해결이 될 줄 알았는데 그래도 오류가 떠서 삽질을 정말 많이했다. 결론적으로 해결한 방법은 다음과 같았다.
    기존에는 스크롤을 끝까지 다 내린 후에 처음으로 돌아가서 하나씩 차례대로 게시글을 읽어오는 식으로 했는데, 정확한 이유는 몰라도 element를 찾지 못하는 오류가 정말 잦게 떴다. 특히 이미지가 있는 글을 읽고 나면, 페이지의 대부분 공간을 그 글이 차지하게 돼서 그 다음 게시글들을 찾지 못하는 경우가 잦았다. 그래서 글을 읽어올 때마다 스크롤의 위치와 스크롤의 height크기를 비교해서 일정값 이하의 차이가 나면 그때 스크롤을 내려주는 식으로, 그러니까 그때 그때 스크롤을 내려주는 식으로 방식을 변경했다. 그렇게 하고나니 element를 찾지 못하는 에러는 거의 뜨지 않았는데, 이미지가 로딩이 덜 된 경우가 있었다. 이 경우야 wait를 걸어주면 되는 문제이기 때문에 wait를 적절하게 걸어주는 것으로 해결했다.
    이 외에도 사이트의 html 구조가 조금 복잡해서, 이미지가 존재하는지 여부 등의 파악 때문에 삽질을 좀 하기도 했었다.
    아무튼 그렇게 해서 크롤링은 마무리를 했다.

  2. 프론트 구현
    디자인의 경우 기존 사이트를 참고해서 만들어달라고 하셔서, 그냥 그대로 만들면 됐는데, next 자체는 react와 별 차이가 없어서 어렵지는 않아보였다. db와 연동해서 데이터를 받아오는 로직은 getServerSideProps를 활용해서 구현했고, 사실 이 과정에서도 JSON 파싱 때문에 잠깐 삽질을 하긴 했지만 결과적으로는 잘 해결이 됐다. 이제 남은건 ui를 구현하는 것이었는데, 문제는 내가 프론트 작업을 한지가 너무 오래됐다보니(거의 1년쯤 된 것 같다...) 유일하게 할 줄 알았던 react조차도 잘 기억이 안 났고, 하나하나 다시 되짚어가면서 하기엔 일정이 매우 촉박했다... 그래서 그나마 기억나는 html css로 하드코딩을 할 수밖에 없었다...(당연히 리팩터링은 해야할것같다...) 외부 component들을 쓸 수는 있겠지만, 기존 사이트의 디자인이 복잡하지가 않아서 정말 다행스럽게도 html css 하드코딩으로도 해결이 되기는 했다.
    사실 너무 급하게 구현하다보니 이게 맞나 싶어서 주변에 물어봤는데, getServerSideProps를 활용하는 것보다는 swr을 한 번 활용해보라는 조언을 받아서, 나중에는 swr을 활용하는 방식으로 수정을 해볼까 싶다.

  3. 배포
    어쨌든 UI단은 구현을 2-3일 정도에 거쳐서 완성을 하고, vercel을 활용해서 배포를 했는데 time out에러가 떴다...? 물론 로컬에서 돌리면서도 사이트 작동이 느린 것 같다는 생각이 좀 들기는 했지만 우선은 다른 작업부터 하느라 바빴는데, time out 에러가 뜨니까 멘붕이 왔다. 그래서 찾아보니 vercel의 경우에는 최대 요청 대기 시간이 10초로 지정되어있다는 것이다. 좀 느린 거 같긴 했는데 이정도로 느린가...? 하지만 이제와서 다른 배포 플랫폼을 찾기엔 정말 시간이 없었다.. 그래서 어떻게든 대기시간을 낮추기 위해서 다음 방법들을 써봤다.
    1)img -> Image(next/Image)로 변경. 그런데 현재 이미지는 구글 드라이브 url을 활용해서 불러오는 경우가 많았는데 Image의 href에 외부 url을 넣어주니 오류가 났다..? (지금 찾아보니 경로를 config파일에 지정해주면 외부 url도 쓸 수 있다고 한다!) 그래서 메인 로고로 쓰는 이미지만 Image로 변경해줬다.
    2)db data fetch 개수 조절: 원래 요청 한 번에 10개씩 데이터를 받아오도록 했는데, 5개 정도로 개수를 줄였다.
    이렇게 하고나서 다시 배포를 하니 놀랍게도 time out 에러가 안 떴다. 아무래도 img->Image보다는 db feetching개수를 줄인 것이 문제 해결에 도움이 된 것 같다.

이러한 과정을 거쳐서 프로젝트를 1차적으로 마무리를 했다. 의뢰자분이 특별한 수정 사항은 없다고 하셔서 사용자들에게 오픈을 했고, 지금 현재 기준으론 간헐적으로 mongoDB에서 connection almost limit 알림이 오고 있기는 하다... 그래도 아직은 limit까지는 안 다다랐으니 좀 더 지켜볼 예정이다. (이번 프로젝트로 atlas 무료계정이 생각보다 connection 제공수가 적다는 걸 알게 됐다...)

profile
개발자, 학생

0개의 댓글