Dev

Crawling 성능 40배 올리기, 160분에서 4분대로 -요구사항 충족-

친환경사과 2023. 4. 4. 21:41

 

👕 크롤링 애플리케이션은 JBLY 프로젝트 요구 사항인 "파이썬 환경에서 최소 세 개 이상의 쇼핑몰을 모아볼 수 있다."를 수행하는 애플리케이션입니다. 시리즈 포스팅은 성능 개선 과정에서 겪은 문제점과 해결하는 과정을 담고 있습니다.


✒️ 첫 번째 요구사항 충족 글은 성능이 개선되기 전 요구 사항 달성 과정을 포스팅합니다. (160분 소요)

✒️ 두 번째 도구 선택의 중요성 글은 Selenium Tool 걷어내는 과정에서 성능 개선 방법에 대해 포스팅합니다. (30분대로 성능 개선)

✒️ 세 번째 병렬 처리 글은 병렬 처리를 통해 성능을 높일 수 있는 방법에 대해 포스팅합니다.(4분대로 성능 개선)


 

🍎 Crawling

  • 지정한 임의의 세 개의 쇼핑몰을 모아볼 수 있는 기능을 구현하기 위해선 어떤 방법으로 해결해야 할까요?
  • 세 개의 쇼핑몰을 매 페이지마다 들려가며 상품 정보들을 가져와야 한다면 시간이 많이 걸릴뿐더러 사람이 하는 작업이라 Human Error가 발생할 확률이 높습니다. 따라서, 이를 자동화하는 방법을 찾아야 합니다.
  • Crawling을 통해 웹 사이트, 하이퍼 링크, 데이터와 같은 정보 자원을 자동화된 방법으로 수집, 분류 저장하는 것을 가져올 수 있습니다.
  • Crawling 시 robots.txt를 통해 해당 Web의 정책을 확인해야 합니다.

 

🍏 방법을 찾았습니다. 파이썬 환경에서 Crawling을 수행하면 됩니다. 특정 웹 사이트의 정보를 가져오기 위해서 어떤 도구를 사용할 수 있을까요?

  • 도구를 찾는데 선택한 방법은 웹에 Crawling Tool을 검색해 그중 자료가 많은 도구를 선택했습니다. 이런 선택을 한 이유는 처음 해보는 Crawling 개발이기 때문에 참고할 자료가 많다면 그만큼 시간을 단축시킬 수 있다고 판단했기 때문입니다.
  • Crawling Tool 중 사용 빈도가 높은 두 개를 골라 프로젝트를 진행했습니다. 두 Tool은 Beautiful Soup, Selenium입니다.

 

🍎 Beautiful Soup

  • Beautiful Soup은 HTML과 XML 문서들의 구문을 분석하기 위한 Python Package입니다. Beautifus Soup에 입력된 HTML Source를 던져주면 Beautiful Soup은 HTML DOM을 그립니다.
  • Beautifus Soup이 제공하는 함수를 통해 그린 DOM에서 원하는 데이터를 긁어올 수 있습니다. Python에서 사용하려면 Beautiful Soup을 직접 다운로드해 사용해야 합니다.

Beautiful Soup 사용 예시
찾고자 하는 부분의 결과 데이터

  • 위의 예시에서 볼 수 있듯이 원하는 사이트에 Requests Module을 통해 요청을 보낸 후 가져온 response를 BeautifulSoup Module을 사용해 파싱 하길 원하는 부분의 데이터를 가져올 수 있습니다.
  • 프로젝트에선 사용될 상품 하나의 Data Schema는 [상품_id, 상품_이름, 상품_이미지, 상품_가격, 상품_타입, 상품_상세_정보, 가게_이름]으로 구성되어 진행됩니다.

필요한 상품 정보 파싱 과정 코드

 

⚠️ 문제가 두 가지 발생했습니다.

 

1️⃣ 웹 사이트마다 다르지만 일부 웹 사이트에 요청을 보낼 때, 403 Forbidden 이 발생합니다.

 

🍏 요청에 대한 응답값이 403일 때 해결 방법 

  • google.com site에 요청을 보내 응답을 가져온 것처럼 Crawling target site를 requests module에 넣어 응답을 받아왔지만 올바른 값을 가져오지 못했습니다. 대신 403 Forbidden Error Message를 쇼핑몰 site server로부터 받아왔습니다.
  • HTTP 403 Forbidden 클라이언트 오류 상태 응답 코드는 서버에 요청이 전달되었지만, 권한 때문에 거절되었다는 것을 의미합니다. 이 상태는 401과 비슷하지만, 로그인 로직(틀린 비밀번호로 로그인 행위)처럼 반응하여 재인증(re-authenticating)을 하더라도 지속적으로 접속을 거절합니다.
  • 403 오류 상태는 400 Bad Request처럼 "요청이 잘못되었다"라는 의미가 아니라 "요청 syntax가 잘못되어서 이해를 못 하겠다"라는 의미를 담고 있습니다. 요청을 판단하는 주체는 서버입니다. (= The server understood the request, but is refusing to fulfill it.)
  • 요청 시 서버에게 이해할 수 있는 syntax를 갖는 요청을 보내면 문제를 해결할 수 있습니다. 웹 개발자 도구에서 사이트 접근할 사이트 Request Header를 보면 요청 시 필요한 값들을 알 수 있습니다. crawling 대상 사이트들은 요청 시 Header에 referer와 user-agent 값을 넣음으로 올바른 syntax 조건을 만족시켰습니다.

웹 개발자 도구에서 Request Header로 서버에 요청된 값들
요청 시, Header 값을 추가해 403 Error 해결

 

2️⃣ Schema에 존재하는 상품_상세_정보를 가져오기 위해선 하나의 깊이(페이지)를 더 들어가야 합니다. 또한 다음 페이지로 이동하기 위해선 동적 처리(클릭이라는 동적인 움직임으로 상세 페이지에 접근)를 해야 하는데 문제는 Beautiful Soup은 동적 페이지 처리 기능을 제공하지 않습니다.

 

🍏 웹 사이트에서 동적 처리를 제공해 주는 Tool을 찾아야 했습니다. 해결책으로 Selenium이란 도구를 발견했습니다. 이를 통해 웹 페이지를 사용자 요구에 맞게 처리할 수 있습니다. (동적 처리를 위해 사용했지만 다음 글에서 Selenium을 제거합니다.)

 

🍎 Selenium

  • JBLY 프로젝트에선 Selenium을 사용해 동적 처리를 진행했습니다.
  • Selenium은 웹 애플리케이션을 자동화하고 테스트하는 데 사용되는 프레임워크입니다. 웹 페이지의 텍스트, 버튼, 링크, 이미지, 폼 등을 자동으로 조작할 수 있습니다. 이처럼 다양한 방법으로 웹 페이지를 조작할 수 있으며, 확장성이 높아 다양한 작업을 수행할 수 있습니다.
  • Selenium을 사용할 때, Web Driver(Web Engine)을 코드를 통해 생성해 사용하는 방법과 직접 Web Engined을 애플리케이션 구동 위치와 같은 위치에 둬 호출을 통해 사용하는 방법이 있습니다. JBLY 프로젝트의 경우, 후자의 방법을 선택했습니다. 이유는 Window 환경에서 코드를 통해 Web Engine을 생성하는 부분에 에러가 발생했기 때문입니다.
  • 예제 코드를 보고 싶다면 여기를 클릭해 주세요!

✅ BeautifulSoup과 Selenium을 통해 세 개의 사이트를 크롤링하는 것을 완료할 수 있었습니다. 

  • 하지만, 문제가 있습니다. 세 사이트를 모두 Crawling 할 경우 160분이라는 시간이 소요됩니다.
  • 실제 서비스를 진행한다고 했을 때 하루에 처리할 수 있는 사이트의 수는 많다면 30 개밖에 되지 않습니다. 1000개의 사이트 모아보기를 사용자에게 제공하는 서비스라고 한다면 한 달을 쉬지 않고 애플리케이션을 구동시켜도 모든 사이트들의 아이템을 등록시킬 수 없습니다.
  • 도중 사이트에서 변경 사항이 생긴다면(상품 가격 수정, 상품 재고 없음) 해당 결과를 사용자가 알기까지 Worst Case로 한 달 이상이 걸릴 수 있다는 것을 의미합니다. 즉, 실제 사이트에서 판매되는 제품과 JBLY에서 보여주는 제품의 데이터 정합성이 일치하지 않음을 이야기합니다. 이는 JBLY Application 품질을 낮춥니다.
  • 지금 개발한 대로 1000개의 모아보기 서비스를 운영한다면 1년에 들어가는 유지 비용은 다음과 같습니다.(해당 비용은 대략적인 계산결과입니다.)
    • Naver Cloud Server 사용 시(최소 사양) 비용 계산을 해보자면 (245원 * 24) * (30일) * (12 개월) = 2,116,800이 서버 동작에 들어갑니다.

사용하는 컴퓨터와 비슷한 성능의 Cloud Server 환경

  • 추가적으로 DB 사용할 때 추가적으로 비용이 들어갑니다.(DB 튜닝 포스팅에서 다룹니다.) 프로젝트 한 달간 세 사이트만 Crawling을 진행했을 때 발생한 비용은 100,000이었습니다. 하루에 10번의 사이클이 돌아가니 100,000 * 10 = 1,000,000이고 1년을 계산하면 12,000,000이라는 금액이 발생합니다.
  • 따라서, 반드시 애플리케이션 실행 시간을 줄여야 합니다.

 

🔜 다음 포스팅에선 병목이 많이 발생하는 부분을 찾아보고 개선해 160분에서 30분대로 줄이는 과정을 포스팅하겠습니다.! 긴 글 읽어주셔서 감사합니다.


📚 참고 사이트

HTML 상태 코드의 의미를 자세하게 볼 수 있습니다.

HTML Spec을 확인할 수 있습니다.

Web Parser인 BeautifulSoup의 사용법을 배울 수 있습니다.

Web 동적 처리를 제공하는 Selenium의 사용법을 배울 수 있습니다.


🍎 현재까지 완료된 코드를 보고싶다면 링크된 브랜치에서 확인할 수 있습니다.

 

GitHub - f-lab-edu/JBLY: 크롤링을 이용한 쇼핑몰 모아보기 서비스

크롤링을 이용한 쇼핑몰 모아보기 서비스. Contribute to f-lab-edu/JBLY development by creating an account on GitHub.

github.com