본문 바로가기
프로그래밍/JAVA

38 JAVA/크롤링: 요리 레시피 조회 프로그램 제작

by 윤지(●'◡'●) 2021. 7. 12.
반응형

 


크롤링을 하는것은 자유이지만,
타인의 콘텐츠를 무단으로 사용하여 상업적인 용도로 사용하는 것은 불법입니다!
글을 시작하기전, 저는 상업적 목적이 아닌 프로젝트용(공부용)으로 크롤링을 한 것임을 밝힙니다.

계기

 

학원에서 정식 웹 프로젝트를 하기전, 자바를 통해 간단한 미니 프로젝트를 하게 되었다.

우리 조에서 정한 주제는 만개의 레시피와 같은 기능을 가지고 있는 요리 레시피 프로그램 이였다.

 

 

 

설명

분류 설명
프로젝트명 원조의 레시피
기능 ▪ 만개의 레시피 크롤링을 통한 레시피 검색 및 조회
▪ 레시피보관함(검색을 통해 원하는 레시피 저장, 유저가 직접 작성하여 레시피저장)
▪ 게시판(유저소통 게시판, 레시피 소통게시판)
▪ 마이페이지(레시피 보관함 조회, 내 정보 수정, 내 작성글 조회)
특징 회원과 비회원을 나누어, 비회원 기능 제한을 통해 회원가입을 하도록 유도했다.

 

위의 설명 중, 보라색으로 표시된 부분이 내가 맡은 파트이다.

 

 

제작을 하며, 겪은 고충

 

1. 크롤링할 사이트 고르기

 

처음, 사이트를 고르는 과정에서 많은 고민을 했었다.

 

사이트명 설명
네이버 레시피 ▪ 유저가 작성하는 것이 아닌 지식백과라 그런지 폼이 거의 일정하고, 광고 문구가 없다.
▪ id와 class가 잘 나눠져 있지않아서 크롤링하는데 어려움이 있다.
만개의 레시피 ▪ 유저가 작성하는 것이라 폼이 일정하지 않고, 레시피 내부에 유튜브 구독 등 광고문구가 포함되어 있다.
▪ 네이버 레시피에 비해 id와 class가 잘 나눠져 있어서 크롤링 하기 좋다.

 

네이버 레시피가 유저가 조회할 때 깔끔할 것 같아서 네이버 레시피로 진행하려 했으나,

위에서 말한 문제점 때문에(결국은 나의 실력 문제지만...(;´д`)ゞ 열심히하자..!) 만개의 레시피로 선택하였다.

 

 

2. 일정하지 않은 폼

위의 사진처럼 재료의 ul의 갯수가 일정하지 않아서 긁어오려할 때 계속해서 에러가 났었다.

근데 이건 내가...바보였다 ㅎㅎ 그냥 재료가 적혀있는 div의 모든 li를 긁어오면 되는거였는데

ul > li 로 긁어오려하니 ul의 갯수가 그때그때 달라져 에러가 나는것이라 간단 해결 !

 

 

3. 제일 고생한, 계량법 가져오기

 

 

위의 사진을 보면 알겠지만, 재료 하고 뒤에 공백이 길~~~~~~~게 있고 그 후에 계량법이 적혀 있어서

재료를 가져오면 "오이                                                     1/4개"로 가져와졌다.

물론 콘솔창에 출력이야 이쁘게 하려면 할 수 있었지만, DB에 담아야 했기에 저 모양상태로는 절대 넣을 수 없었다.

 

 

[해결 하기까지의 과정]

 

trim() 메소드를 사용해봤지만, 앞 뒤 공백을 제거하는 메소드 이기 때문에 소용이 없었고

replace() 메소드 또한 사용해보았지만 실패하였다.

오기가 생겨서 주말 내내 구글 검색도 해보고 내가 아는 메소드를 전부 사용해 봤지만 실패하였고

학원 선생님과의 기나긴 고민 끝에 해결법을 알아냈다! (그저 빛 ㅠㅠ)

 

일단, length()를 이용하여 길이를 확인해보니 저 긴 공백을 한칸으로 처리하는점을 알아냈다

이를 알아보고 나니 , substring()을 이용하여 전체 길이(재료명 + 계량법) 에서 span태그로 묶여있는 계량법의 길이만큼을 제거하면 재료명만을 떼낼 수 있고, span태그의 text만 떼오면 계량법을 떼올 수 있었다.

그리고 이 둘을 합치면 저 기다란 공백이 사라진 온전한 재료(재료명 + 계량법)을 얻을 수 있었다.

 

[예시]

 

오이                                                     1/4개 의 length() : 6
span태그의 text(=1/4개) length()  : 3
step1.substring(0, 재료의전체길이 - 재료명의길이 - 1) : 오이 
span 태그의 text : 1/4개
둘을 합치면 !!! "오이 1/4"

[코드]

String liText = ""; // 재료명을 담을 변수
WebElement stuffArea = driver.findElement(By.id("divConfirmedMaterialArea"));
// id가 divConfirmedMaterialArea 인 요소 찾아 stuffArea에 담기
List<WebElement> stuffList = stuffArea.findElements(By.tagName("li"));
// stuffArea에서 tag가 li인 요소들을 찾아 stuffList에 담기

for (int i = 0; i < stuffList.size(); i++) { //0부터 stuffList의 사이즈까지 반복
  WebElement spanTag = stuffList.get(i).findElement(By.tagName("span"));
  // stuffList의 i번째에서 tagName이 span인 요소 spanTag에 담기 (계량법)
  String spanText = spanTag.getText();
  // spanTag의 text를 가져와 spanText에 담기(계량법)
  String step1 = stuffList.get(i).getText();
  //stuffList의 i번째에서 text가져와 step1 에 담기(긴 공백이 포함된 재료명 + 계량법)
  // 계량법이 안적혀 있는 경우가 있어서 조건문으로 나누었다
  if (spanText.length() > 0) { // 만약 spanText(계량법)의 길이가 0보다 크다면
  					// 즉, 계량법이 있는 경우를 말한다
  liText = step1.substring(0, step1.length() - spanText.length() - 1);
  // step1의 0번째 부터, "긴 공백이 포함된 재료명 + 계량법의 길이 - 계량법의 길이 - 1" 까지만을
  // 변수 liText에 담는다.(공백의 제거된 재료명)
} else {
  // 계량법이 없는 경우
  stuff += step1 + " "; // 공백을 제거한 재료명만을 결과값을 저장할 stuff에 담는다.
  }
  // 모든 재료를 한 줄로 넣기 위에 for문을 돌며 처리된 값을 stuff에 이어 넣는다. 
  stuff += liText + spanText + " ";
}

 

 

결과

 

 

 

 


열심히 공부하고 있지만, 오류 사항이 존재 할 수 있습니다.

수정 사항이 존재 할 경우 알려주시면 감사하겠습니다 <(__)>

반응형

'프로그래밍 > JAVA' 카테고리의 다른 글

JAVA 필수 단축키  (0) 2021.05.27
37 멀티쓰레드를 이용한 문제 풀이  (0) 2021.05.04
36 동기화(synchronized)  (0) 2021.05.04
35 Thread  (0) 2021.05.04

댓글