항해99 3기

[WIL] 항해99 3기 1주차

na_o 2021. 9. 20. 05:54
728x90

[2021.09.13 ~ 2021.09.17]

드디어 첫 프로젝트가 끝이 났다

지금까지 JAVA를 공부해서 Spring으로 프로젝트를 해왔었는데

flask로 프로젝트를 한 건 처음이다

첫 날에 계획했던 화면과 나름 비슷하게 구현이 되었다

https://velog.io/@donggun130/hanghae993%EA%B8%B0-15%EC%A1%B0

 

hanghae99(3기)-15조

1.제목 : 연수구 가치봉사 설명 : 현재 모집중인 인천 연수구내 봉사활동에 대해서 리스트업 시켜주고 마이페이지에 나의 봉사활동을 관리 할 수 있게 해주는 서비스 입니다.2\.https://github.com/Ldong

velog.io

 


[프로젝트 이름 및 사용 기술]

이름은 '연수구 가치봉사' 이다!

팀원이 인천광역시 연수구에 살고 있기도 하고

연수구에서 할 수 있는 봉사활동이 그렇게 많지 않아서 크롤링하기 적당해보였다

1~3기 통해서 봉사를 주제로 진행한 프로젝트가 없어서 이걸로 선택했다

사용한 기술은 Python3.8, flask, bs4, requests, pymongo, pyJWT 1.7.1, charset-nomalizer 2.0.4 이다

 

 

 


[프로젝트 설명]

1. 로그인 페이지

회원가입을 통해 계정을 새로 만들고, 로그인을 한다

 

 

 

2. 목록 조회 페이지

인천 연수구에서 할 수 있는 봉사활동 목록을 보여준다

하트를 눌러 좋아요를 표시할 수 있고, 취소도 할 수 있다

좋아요를 표시하면 마이페이지에서 확인 가능하다

 

 

 

3. 상세 페이지

봉사활동의 제목을 눌러 상세내용을 확인한다

 

 

 

4. 마이페이지

마이페이지에서 좋아요를 누른 봉사활동 정보가 출력된다

하트를 눌러 좋아요 취소를 하면 봉사예정 부분에서 사라진다

완료하기 버튼을 눌러 봉사 완료 부분으로 이동한다

현재까지 봉사를 완료한 총 시간을 확인할 수 있다

 

 

 

소스코드: https://github.com/Ldonggun/hanghae99-3-15

 

GitHub - Ldonggun/hanghae99-3-15: 항해99 15조 1주차 미니프로젝트

항해99 15조 1주차 미니프로젝트. Contribute to Ldonggun/hanghae99-3-15 development by creating an account on GitHub.

github.com

 

5. 구현한 기능

기능 Method URL request response
로그인 페이지 이동 GET /    
목록 조회 페이지 이동 GET /mainpage 토큰["id"] 봉사활동 정보 리스트
목록 조회 페이지
좋아요 누르기
POST /mainpage/like {"volunteer_no": volunteer_no,
"subject": subject,
"recruit_period": recruit_period,
"hour": hour,
"href": href}
메시지
"좋아요를 눌렀습니다!"
목록 조회 페이지
좋아요 취소
POST /mainpage/cancel {"volunteer_no": volunteer_no} 메시지
"좋아요를
취소했습니다!"
마이페이지 이동 GET /mypage 토큰["id"] 봉사활동 정보 리스트,
총 봉사시간,
마감일로부터 남은 날
마이페이지 좋아요 취소 POST /mypage/delete {"volunteer_no": volunteer_no} 메시지
"봉사활동 삭제됨!"
수행한 봉사활동 완료 POST /mypage/done {"volunteer_no": volunteer_no} 메시지
"봉사활동 완료됨!"
회원가입 POST /sign_up/save {"username_give": username,
"password_give": password}
{'result': 'success'}
아이디 중복확인 POST /sign_up/check_dup {"username_give": username} {'result': 'success', 
'exists': exists}
로그인 POST /sign_in {"username_give": username,
"password_give": password}
{'result': 'success', 
'msg': '연결됨.'}

[어려웠던 점]

1. 1365 페이지가 크롤링이 안 된다

1365의 봉사활동 조회 페이지에서 지역을 선택하는 부분이 있는데

인천광역시 -> 연수구 로 선택을 한 상태에서 URL을 가져와 크롤링을 했다

근데 전 지역을 조회한 상태에서 크롤링을 해오는 것이였다

계속 생각해보니까 쿼리스트링이 생각났다

쿼리스트링으로 인천광역시, 연수구, 현재 페이지 에 대한 데이터를 같이 보냈더니 해결되었다

 

 

 

2. 인천광역시 연수구에 대한 봉사활동들을 조회했는데 페이지가 여러개다

총 페이지 개수를 계산하려면 인천광역시 연수구에 있는 봉사활동 총 개수가 필요했다

1365 페이지에서 먼저 총 개수를 크롤링해온 뒤 한 페이지에서 확인할 수 있는 봉사활동 개수(10개)로 나누어

총 페이지 개수를 계산했다

정확히는 올림 함수를 썼다

page_count = math.ceil(page_count / 10)

그래서! 총 페이지 개수를 구한 뒤 for문을 사용했다

쿼리스트링의 cPage의 값을 페이지 개수대로 반복문으로 바꿔가며 그 페이지를 크롤링했다

 

 

 

3. 1365 페이지에 있는 데이터들을 가져오는 방법

이건 한번 해봤기 때문에 다행히도 크게 어렵지 않았다

크롬의 개발자도구의 'copy selector' 기능을 이용해 크롤링 대상 태그의 선택자를 가져왔다

크롤링 대상의 태그를 전체 다 가져와 태그를 걸러내 데이터만 뽑아내고, 필요한 형태로 가공했다

 

 

 

4. 크롤링 속도가 너무 느리다

심각하게 너무 느렸다..누가 웹 페이지를 1분 이상 기다리겠는가..ㅠㅠ

무조건 개선해야했다

멘토님과의 1:1 상담이 있었는데, 그 때 '크롤링 성능 개선'이라고 검색해보라고 알려주셨다

구글링을 해서 아래의 페이지를 찾았다

https://geniyong.github.io/2019/11/06/Python-Crawler-%EC%84%B1%EB%8A%A5-%EA%B0%9C%EC%84%A0.html

 

Python - Crawler 성능 개선 - 지니용 개발 블로그

개요   적게는 수 만개에서 많게는 수 백만 개의 웹 사이트에 각각 접속하여 데이터를 가져오는 크롤러를 개발하면서 크롤러의 본질적인 문제들을 만나고 해결하는 과정을 반복했다. 크롤러의

geniyong.github.io

멀티쓰레드를 이용하는 것이다

해야 할 일을 n명이 나눠가져서 하는 원리이다

그래서 1분 넘게 걸리는 것을 17초 정도로 줄였다

내 방 컴퓨터가 인터넷 상태가 좋지 않아 느린 편이다

인터넷 상태가 좋다면 이것보다 더 빠를 것이다

 

 

 

5. 마이페이지에서 목록 조회 페이지로 이동했을 때, 데이터가 중복되어 화면에 보인다

코드를 아무리 이래저래 바꿔봐도 원인을 못 찾았다

그래서 봉사활동 정보들이 담겨있는 리스트에서 중복된 데이터는 삭제했다

https://inma.tistory.com/95

 

[Python] List에서 dictionary 중복 제거

리스트에서 딕셔너리 중복 제거 파이썬 리스트에서 특정 속성  기준으로 중복되는 딕셔너리를 제거할 때 사용되는 Example 입니다. 다음과 같은 accounts  계정 목록이 있다고 가정해봅시다. accoun

inma.tistory.com

하지만 프로젝트를 완성하고 다시 생각해보니 크롤링할 때마다 데이터를 담고있는 리스트를

초기화해줘야했었다

초기화를 안한 상태로 계속 크롤링을 하니 중복되는 데이터가 있는 게 당연하지..

왜 그 당시에는 생각 못했을까..

 

 

 

6. 마이페이지에서 계정마다 좋아요 누른 봉사활동 목록을 보여주는 것을 다르게 해야 한다

기본적인 기능을 다 구현하고 보니, 큰 비중을 차지하는 기능을 넣지 않았던 것이다

그래서 로그인을 할 때 브라우저에 토큰을 저장하는데, 그 토큰에서 아이디값을 가져오는 게 필요했다

나는 JWT를 전혀 몰랐다. 공부를 해보니까

JWT는 JSON Web Token의 줄임말로, JSON 객체를 사용해 정보를 안정성 있게 전달하는 웹표준이고,

사용자가 로그인하면 서버에서 회원임을 인증하는 토큰을 넘겨줌으로써

이후 회원만 접근할 수 있는 서비스 영역에서 신분을 확인하는 데 쓰일 수 있다고 한다.

https://tansfil.tistory.com/58?category=255594 

 

쉽게 알아보는 서버 인증 1편(세션/쿠키 , JWT)

앱 개발을 처음 배우게 됐을 때, 각종 화면을 디자인해보면서 프론트엔드 개발에 큰 흥미가 생겼습니다. 한때 프론트엔드 개발자를 꿈꾸기도 했었죠(현실은 ...) 그러나 서버와 통신을 처음 배

tansfil.tistory.com

위의 글은 http 요청에서부터 cookie/session ~ JWT 내용까지 있어 자세해서 좋다

JWT에 대한 내용만 있는건 https://velopert.com/2389

 

[JWT] JSON Web Token 소개 및 구조 | VELOPERT.LOG

지난 포스트에서는 토큰 기반 인증 시스템의 기본적인 개념에 대하여 알아보았습니다. 이 포스트를 읽기 전에, 토큰 기반 인증 시스템에 대해서 잘 모르시는 분들은 지난 포스트를 꼭 읽어주세

velopert.com

JWT는 "." 구분자로 헤더(header), 내용(payload), 서명(signature) 세 부분으로 되어있다

그 중 payload에 아이디와 암호화된 비밀번호를 저장해서

목록 조회 페이지로 이동할 때 payload에서 아이디값을 가져왔다

좋아요를 눌러 DB에 봉사활동 정보를 저장할 때 좋아요를 누른 계정 아이디도 같이 저장했다

마이페이지에서 좋아요를 누른 봉사활동들을 DB에서 조회할 때

현재 로그인한 계정이 좋아요를 누른 것을 조회해오도록 했다

 

 

7. 1365 페이지에서 모집 마감한 봉사활동을 마이페이지에서 안 떠야 한다

이 부분은 메인페이지에서 크롤링해온 데이터를 가져와

DB에 저장되어있는 데이터와 비교를 했다

크롤링해온 봉사활동 목록에서

DB에 저장되어있는 봉사활동이 없으면 DB에서 삭제했다

마감된 봉사활동은 크롤링해온 목록에 없을거기 때문에

이런 로직으로 만들었다

마감일이 정해져 있어도 이미 모집되었기 때문에 게시물을 올린 사람이 게시물을 내릴 수도 있다

이 경우를 생각해서 위의 로직으로 짰다


[배운 것]

협업하는 과정을 경험했다

특히 Github에 대해 익숙해지기 위해 다같이 공부했다

Flask라는 프레임워크를 배웠다

Django를 잠깐 써본 적이 있는데, 나한테는 Flask가 더 쉬웠다

뭔가 Spring 프레임워크랑 비슷한 느낌이라 좀 더 익숙하게 사용했던 것 같다

그리고 MongoDB라는 것을 처음 사용해 봤다

이제 보니까 MongoDB는 NoSQL이였다

NoSQL은 JSON 형태로 데이터가 저장되는 것 같았다

Oracle과 MySQL과 다른 형태였다


[아쉬웠던 것]

Github를 조금이라도 잘 다뤘더라면 시간을 좀 더 효율적으로 사용했지 않았을까 싶다

그리고 프로젝트에 DB를 제대로 사용하지 못했던 것 같다

마이페이지에서만 사용되고, 메인페이지에서는 크롤링해온 데이터로 보여주기 때문에

데이터베이스가 거의 쓰이지 않았다


[소감]

처음 만난 사람들과 바로 프로젝트를 시작해야되니 너무 어색했다

숨 막힐 정도로 어색했는데 그래도 어찌어찌 진행되었다

우리 조는 git을 제대로 써 본 사람이 없어서

코드를 카톡으로 주고받으면서 프로젝트를 했다

프로젝트를 어느정도 마무리 한 다음에는 다같이 git에 대해 공부했다

github에서 clone하는 것 부터 commit, push하는 것 까지 공부하고 각자 돌아가면서 이 과정을 직접 해봤다

같이 공부해나가니까 머리에 더 잘 들어왔다

참 좋은 경험이였다