[프로젝트 회고] - English Memorization Book For Developer (Memorize)

Jaychy·2021년 2월 18일
1

프로젝트 Memorize

목록 보기
1/1
post-thumbnail

본 글은 글쓴이의 개인적인 생각이 담겨있을 수 있습니다.

회고를 쓰는 게 처음이라 내용이 중구난방일 수도 있겠다 싶긴 하지만
회고를 작성하는 것이 나중에 내가 이 프로젝트를 되돌아봤을 때
어떤 생각으로 이런 프로젝트를 기획했고 어떤 생각으로 코드를 작성했을지 알 수 있을 것 같아서 이렇게 작성해본다.

먼저 프로젝트에 대한 간략한 소개를 해보자면,
Memorize 라는 프로젝트로
스프링 부트 공식문서를 크롤링하여 번역 및 분석의 과정을 거쳐 가장 많이 나온 영어 단어를 이용하여
개발자용 영어 암기에 도움이 될 수 있는 프로그램을 만드는 것이 목표인 프로젝트였다.
자세한 설명(그닥 자세하진 않음)과 코드는 아래 깃허브에서 관리한다.

[Github] https://github.com/Lee-Jin-Hyeok/memorize

본 프로젝트는 [크롤링] - [번역] - [저장] 으로 크게 세 가지로 구분된다.
API로 단어를 보내주기도 하나, 큰 의미는 없으므로 제외했다.

🔧 스프링 부트 공식문서 크롤링하기

🎁 크롤링 대상 정하기

크롤링을 한다고 해서 무작정하면 될 줄 알았는데
먼저, 스프링 부트 공식문서가 아주 많았다.
생각해보면 스프링 부트로 개발하면서 본 공식문서만 해도 수십 가지가 넘는데
내가 보지도 못한 문서도 합하면 얼마나 많겠냐는 생각을 했다.
그래서 스프링 부트 공식 사이트에 들어가 가장 간단하게 스프링 부트에 대해서
설명해주는 공식문서를 크롤링하기로 했다.

📦 robots.txt

크롤링 라이브러리는 Jsoup을 이용하였다.
그런데 생각해보니 내가 간과하고 있었던 것이 있었다.
크롤링은 사이트에 대규모의 트래픽을 유도할 수 있기 때문에
사이트는 robots.txt를 이용해 크롤링의 가능 여부를 알려주고 있다.
다급하게 스프링 부트 공식문서의 robots.txt를 살펴보았는데 다행이게도 쿨하게 허용해주는 모양이었다.

User-agent: *
crawl-delay: 1

User-agent: *
Disallow: /autorepo/

📪 크롤링의 기준

사실 이전에도 이 프로젝트를 진행하려고 한적이 있다.
하지만 그 당시에 팀 프로젝트를 많이 진행하고 있었고 내 의지가 부족해 프로젝트를 제대로 마무리하지 못했었다.
그리고 그때 겪었던 문제가 사이트의 구조에 굉장히 복잡하다는 것이었다.
처음에는 지금 크롤링하려는 사이트가 아니라 Java SE 8 API 문서를 크롤링하려고 했었는데
이 사이트에는 iframe안에 iframe이 있고 안에 또 있고 이런식으로 더럽게? 되어 있어서 크롤링하기 막막했었다.

하지만 이번 사이트는 구조가 간단하기에 text 또는 a 태그 그리고 p 태그를 이용해 크롤링하려고 했다.
a 태그에는 공식문서의 특성상 패키지 네임, .jar 파일 이름, 클래스 이름 등이 유냔히 많이 포함되어 있어서 제외하기로 했고,
text와 p 태그를 비교해본 결과 text가 p 태그를 포함하고 있고 차집합을 만들었을 때
text에 쓸모없는 단어가 많다는 것을 미루어보아 text 대신 p 태그를 선택하기로 했다.

📔 단어 추출

그리고 문장이 아닌 단어만을 추출해야하기 때문에 규칙을 정해야만 했다.
나는 이 규칙을 정규표현식으로 해결하기로 마음먹었기에 다음과 같은 정규표현식이 나왔다.

INCLUDE_SPECIAL_CHARACTER(Regex("[~!@#$%^&*]*"))
ONLY_ENGLISH(Regex("^[a-zA-Z]*"))
MORE_THAN_ONE_UPPERCASE_CHARACTER(Regex(".*[A-Z].*[A-Z].*"))
AT_LEAST_THREE_CHARACTER(Regex(".{3,}"))

지금 보니까 '해야하는 것'과 '하지말아야 하는 것'이 섞여 있어서 복잡해보일 수 있을 것 같다.
위에서부터 살펴보면,

  • Include Special Character - 특수문자를 포함하지 말아야 한다.
    지금 생각해보니까 두 번째 제한안에 포함되는 내용이다.
  • Only Enlgish - 영어로만 이루어져야 한다.
  • More Than One Uppercase Character - 대문자를 두 개 이상 포함하지 말아야 한다.
    대문자가 두 개 이상이면 보통 클래스 이름일 가능성이 높다.
  • At Least Three Character - 3글자 이상이어야 한다.
    a, is an 등의 너무 많이 나오는 것에 대해서 제외하였다.

물론 이것만으로는 and, the 와 같은 영어를 제외할 수는 없겠지만 충분히 필요 없는 단어를 제거했다고 생각한다.

🔨 영어 번역하기

😡 번역 API 찾기

크롤링을 통해 영어 단어들을 얻었으니 영어 단어들을 번역해야 한다.
처음에는 Naver Papago API를 이용하여 번역하려고 했으나
번역 API에서 500에러가 발생하는 문제로 인해 더이상 Naver Papago API를 이용할 수가 없었다.

그래서 한국어 기초 사전와 같은 사이트도 들어가봤으나 로그인이 힘들었고,
힘들게 로그인에 성공해도 원하던 API가 아니라서 다른 것을 찾아야 했다.
Google Translation API를 이용해보려고도 했으나 마침 카드를 집에 두고 오는 바람에 사용할 수가 없었다.

그래서 마침내 찾게된 번역 API가 Kakao Translation API였다.
내가 원하던 API도 맞고 Postman으로 요청을 날려본 결과 바로 응답하는 것으로 보아 내 프로젝트에 사용하기에 적합했다.

😢 번역 API 적용하기

번역 API를 적용하는 것은 간단했다. Retrofit 라이브러리를 이용하여 요청을 보내서 가져오는 방식으로 간단하게 해결했다.

하지만 충격적인 문제가 발생했다. 한 네 다섯번 정도 번역해보니 요청에서 에러가 발생하는 것이었다.
알고보니 하루에 번역 API를 사용할 수 있는 제한이 있었던 것이었다.

하지만 이 시점에서는 이미 데이터베이스에 저장하는 과정까지 마쳤기에 다행이었다.
다음부턴 설명을 자세히 읽어야겠다고 다짐했다.

🤬 너무 느려 (Coroutine)

번역 API를 사용하기 위해서 Retrofit을 이용해 요청을 보내는 것을 한두 번하는 것이 아니라
영어 단어가 수 천 개 수만 개가 넘어가는 만큼 수천 번 수만 번 요청을 보내야 했다.
수만 번 요청을 보내니 굉장히 느려지는 것을 체감할 수 있었다.
시간을 정확히 재보지는 않았지만 수만 개의 단어를 번역하는데에는 매우 오랜 시간이 걸렸다.

그래서 이를 코루틴을 이용해서 해결하려고 했다.
Webflux나 JavaFx를 이용할 수도 있었지만 이들의 형식은 좀 구리기에
마침 코틀린을 쓰는 겸해서 코루틴을 사용해보았다.

그런데 코루틴을 사용해보면서 느낀 게 이게 진짜 비동기가 되는 것일까 라고 생각하게 될 정도로
깔끔한 코드여서 놀랐다.

Webflux나 JavaFx를 이용한 코드는 builder 패턴을 이용한다거나 @Async 어노테이션이 붙어있다거나 하는 등
비동기 티? 가 났었는데 코루틴은 그런 것 없이 깔끔한 코드를 작성할 수 있었다.
그리고 확실히 속도도 빨라졌다.

🛠 데이터베이스에 저장하기

😇 Kotlin Exposed 공부하기

처음에는 당연히 JPA를 이용하여 저장하면 되겠다라는 생각으로 했지만
막상 데이터베이스에 저장하려고 하니 Spring Boot 환경이 아니라 일반 코틀린 메인 환경이었기에
Spring Data JPA를 사용할 수 없었다.
물론 JPA를 사용할 수는 있었으나 Spring Data JPA가 아니라면 그리 큰 이득을 볼 수 없었기에
다른 프레임워크를 찾아나서야 했다.

그래서 오픈 소스 프레임워크인 Kotlin Exposed 를 이용하기로 했고
결과는 성공적? 이었다.
물론 Kotlin Exposed가 썩 편하지는 않았지만 사용할만은 한 것 같다.

마무리

이렇게 코틀린으로 작성하는 첫 개인 프로젝트는 막을 내렸다.
끝내고 나니까 많은 기술들을 사용해본 것 같아서 보람찼고,
이러한 유용하다고 생각할만한 아이디어를 다시 만들어낼 수 있을까라는 생각을 하게 되었다.
그리고 무엇보다 혼자서 코드를 작성하면서 어떻게 하면 더 예쁘게 작성할 수 있을까를 생각하니 재밌었다.

profile
아름다운 코드를 꿈꾸는 백엔드 주니어 개발자입니다.

0개의 댓글