정보
- 업무명 : 소프트웨어 개발
- 작성자 : 박진만
- 작성일 : 2019-09-07
- 설 명 : 요리 사이트의 유용한 정보 (ex : 요리이름, 재료, 조리방법, 이미지 주소)를 파싱하여 수집 프로그램
- 수정이력 :
내용
[특징]
- R 프로그램의 httr package를 이용하여, 타겟이 되는 사이트에 접근하여 웹 페이지의 html을 가져온 후 이를 가공 및 변환하여, 자료를 수집하는 프로그램

[기능]
- 타겟이 되는 주소 접근 및 html 불러오기
- 필요한 자료 가공 및 추출
- 추출된 정보를 저장 (해당 코드에서는 보안을 위해 생략)
[활용 자료]
- 대상 홈페이지의 주소 (초기 입력자료)
[자료 처리 방안 및 활용 분석 기법]
- 없음
[사용법]
- 대상 홈페이지의 주소 및 i 값 (레시피 번호)를 입력 또는 원하는 범위에서의 loop 문을 통해 레시피 정보를 가져올 수 있다.
- 중간에 404 에러가 뜨는 경우 루프문을 통과해 다음 레시피 번호로 가게 설정되어 있다.
[사용 OS]
- Windows 10
[사용 언어]
- R 3.5.3
소스 코드
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#========================================================================================================================================== | |
# Routine : R Project Web Crawl Program ver 1.2 | |
# crawl site : http://www.10000recipe.com/index.html | |
# Purpose : To crawl specific information on the website specified above. | |
# Author : Jin-Man Park (Academy. of KIC Campus) | |
# Revisions : V1.0 October 31, 2018 First release (Techer. Y.-K. Park) | |
#========================================================================================================================================== | |
#================================================================ | |
# 0. library load... | |
#================================================================ | |
library(rmarkdown) | |
library(dplyr) | |
library(dynlm) | |
library(repr) | |
library(gstat) | |
library(stringr) | |
library(xlsx) | |
library(XML) | |
library(httr) | |
library(curl) | |
aaa <- paste0("http://www.10000recipe.com/recipe/",i) | |
sapply(aaa, url.exists) | |
qqqq<-url(aaa) | |
i = 6828812 #test | |
A_table = as.character.Date(data.frame("cook_number" = c("zzz"), "cook_name" = c("zzz"), "cook_explain" = c("zzz"), | |
"cook_mainimg"= c("zzz"), "cook_people"=c("zzz"), "cook_level" = c("zzz"), | |
"cook_time" = c("zzz"))) | |
B_table = as.character.Date(data.frame("cook_number" = c("zzz"),"metal"= c("zzz"))) | |
C_table = as.character.Date(data.frame("cook_number" = c("zzz"), "seq_number" = c("zzz"), "seq_text" = c("zzz"), | |
"seq_img" = c("zzz"))) | |
cookNumber = 0 | |
i | |
for (i in c(6828809:6899018)) { ## url number :: 6828809 - 6899018 | |
cookNumber = cookNumber + 1 | |
print(i) | |
print((cookNumber)/(6899018-6828809)) | |
#================================================================ | |
# sequence 1 : url 주소 부여 및 html 소스 가져오기. | |
#================================================================ | |
url <- paste0("http://www.10000recipe.com/recipe/",i) | |
xxx <- tryCatch( | |
{ | |
check <- htmlParse(rawToChar(GET(url)$content)) #html source | |
}, | |
error = function(e) e | |
) | |
if(length(xxx) == 2) next | |
if(length(xxx) == 1) { | |
source <- htmlParse(rawToChar(GET(url)$content)) | |
} | |
#================================================================ | |
# sequence 2 : 요리 이름 및 기본적 정보 | |
# (ex : 이름,간단설명,사람수,조리시간, | |
# 난이도,타이틀 이미지 주소정보) 가져오기. | |
#================================================================ | |
cookName <- xpathSApply(source, "//div[@class='view2_summary']/h3", xmlValue) | |
#cookName #cookname | |
simpleInfo <- xpathSApply(source, "//div[@class='view2_summary_in']", xmlValue) | |
simpleInfo <- gsub("[\r\n]","", simpleInfo) | |
simpleInfo <- gsub("[ ]{2,}|[ ]+$", "", simpleInfo) | |
#simpleInfo #summary text | |
inbun <- xpathSApply(source, "//div[@class='view2_summary_info']/span[1]", xmlValue) | |
time <- xpathSApply(source, "//div[@class='view2_summary_info']/span[2]", xmlValue) | |
nando <- xpathSApply(source, "//div[@class='view2_summary_info']/span[3]", xmlValue) | |
TitleImage <- xpathSApply(source, "//div[@class='centeredcrop']/img", xmlAttrs) | |
TitleImage[2] # image src | |
if(length(cookName) == 0) { | |
simpleInfo <- "NAN" | |
} | |
if(length(simpleInfo) == 0) { | |
simpleInfo <- "NAN" | |
} | |
if(length(inbun) == 0) { | |
inbun <- "NAN" | |
} | |
if(length(time) == 0) { | |
time <- "NAN" | |
} | |
if(length(nando) == 0) { | |
nando <- "NAN" | |
} | |
A_table = rbind(A_table, c(cookNumber, cookName, simpleInfo, | |
TitleImage[2], inbun, nando, time)) | |
#================================================================ | |
# sequence 3 : 배열의 형태로 재료 가져오기. (je3) | |
#================================================================ | |
je <- xpathSApply(source, "//div[@class='ready_ingre3']/ul/li", xmlValue) | |
je1 <- gsub("[ ]{2,}|[ ]+$", "|", je) #2개 이상의 공백 제거 | |
je2 <- gsub("[\r\n]"," ", je1) | |
je3 <- gsub("[ ]{2,}|[ ]+$", "", je2) #2개 이상의 공백 제거 | |
je3 | |
length(je3) | |
#배열 자르기 | |
for (j in c(1:length(je3))) { | |
# print(je3[j]) | |
B_table = rbind(B_table, c(cookNumber, je3[j])) | |
} # end j | |
#================================================================================ | |
# sequence 4 : 배열의 형태로 조리순서 및 조리 이미지(존재유무 불확실)가져오기. | |
#================================================================================ | |
j = 0 | |
#레시피의 길이를 알 수 없으므로 무한루프에 빠뜨린 후 처리한다. | |
while(TRUE) { | |
j = j + 1 | |
dum1 = paste0("//div[@class='view_step_cont media step",j,"']") | |
cook_seq = xpathSApply(source, dum1, xmlValue) | |
cook_seq = gsub("[\r\n]","", cook_seq) # get seq | |
dum2 = paste0("//div[@id='stepimg",j,"']/img") | |
cook_img = xpathSApply(source, dum2, xmlAttrs) # get img | |
# 이미지가 없을 경우 임의의 파일 이름 만들기. | |
if(length(cook_img) == 0) { | |
cook_img = "noimage.jpg" | |
} | |
if(length(cook_seq) == 0) { | |
break | |
} else { | |
# cook_seq, cook_img 쓰기 작업 | |
C_table = rbind(C_table, c(cookNumber,j,cook_seq,cook_img)) | |
} | |
} # end while | |
} # end url number | |
결과
- 요리 제목 및 난이도


- 요리 재료 목록


- 조리법 및 이미지


참고문헌
[논문]
- 없음
[보고서]
- 없음
[URL]
- 없음
블로그에 대한 궁금하신 점을 문의하시면 자세히 답변드리겠습니다.
E. sangho.lee.1990@gmail.com & saimang0804@gmail.com
'프로그래밍 언어 > R' 카테고리의 다른 글
[R] NetCDF 형식인 NPP/CERES SSF 기상위성 자료를 이용하여 아스키 (ASCII) 형식으로 처리 (0) | 2019.12.28 |
---|---|
[R] 다수의 날짜정보를 컬럼으로 가진 DataFrame 에서의 컬럼 제어 방법 (0) | 2019.12.21 |
[R] 동아시아 대기질 이미지 영상을 통해 크롤링 및 애니메이션 구현 (0) | 2019.12.08 |
[R] ggplot2를 이용한 Log 스케일로 산점도 가시화 (0) | 2019.12.06 |
[R] 한반도 연 평균기온 계산 및 Plotting (0) | 2019.11.03 |