2014-12-20 2 views
1

불행히도 매우 불안정한 반응 시간에 반응하지 않는 웹 사이트에서 데이터를 긁어 내려고했습니다. 첫 번째 아이디어는 물론 수천 개의 URL 목록을 반복하고 목록을 채워 다운로드 한 결과를 저장하는 것입니다.루프의 순서를 동적으로 변경합니다.

그러나 문제는 서버가 무작위로 매우 느리게 응답하여 시간 초과 오류가 발생한다는 것입니다. 이것만으로도 tryCatch() 함수를 사용하고 다음 반복으로 이동할 수 있으므로 문제가되지 않습니다. 그래서 나는 각 실행에서 일부 파일이 누락되었습니다. 목록에있는 각 URL이 존재하며 모든 데이터가 필요하다는 것을 알고 있습니다.

그래서 내 아이디어는 getURL() 요청 출력 및 오류가 있는지 평가하기 위해 tryCatch()을 사용했을 것입니다. 그렇다면 루프는 다음 반복으로 점프하고 루프가 실행되는 URL 목록의 끝에 잘못된 URL이 추가됩니다. 이 작품은 내가 결국 목록에있는 모든 URL을 다운로드 할 수있을 것 "것"경우

dwl = list() 

for (i in seq_along(urs)) { 

temp = tryCatch(getURL(url=urs[[i]]),error=function(e){e}) 

if(inherits(temp,"OPERATION_TIMEDOUT")){ #check for timeout error 
urs[[length(urs)+1]] = urs[[i]] #if there is one the erroneous url is appended at the end of the sequence 
next} else { 
dwl[[i]] = temp #if there is no error the data is saved in the list 
} 
} 

: 내 직관적 인 솔루션은 다음과 같이 보일 것입니다. 그러나 next 함수에 대한 도움말 페이지에서 "for 루프의 seq는 루프 시작 부분에서 평가되므로 나중에 변경하면 루프"에 영향을 미치지 않으므로 작동하지 않습니다. 이 목표를 달성 할 수있는 트릭이나 일시적인 해결책이 있습니까? 모든 의견에 감사드립니다!

답변

2

나는 (주석에서 설명) 이런 짓을 할 것이다 :

## RES is a global list that contain the final result 
## Always try to pre-allocate your results 
RES <- vector("list",length(urs)) 
## Safe getURL returns NA if error, the NA is useful to filter results 
get_url <- function(x) tryCatch(getURL(x),error=function(e)NA) 
## the parser! 
parse_doc <- function(x){## some code to parse the doc}) 


## loop while we still have some not scraped urls 
while(length(urs)>0){ 
    ## get the doc for all urls 
    l_doc <- lapply(urs,get_url) 
    ## parse each document and put the result in RES 
    RES[!is.na(l_doc)] <<- lapply(l_doc [!is.na(l_doc)],parse_doc) 
    ## update urs 
    urs <<- urs[is.na(l_doc)] 
} 
+0

를 봐 대단히 감사합니다! 훌륭한 솔루션! – chameau13

관련 문제