본문 바로가기

Project & Module/Crawler

[WebMagic] Analyze

1. Spider
1. addUrl
1. addRequest(url)
1. scheduler.push(request, this) (** 2.1 이동 **)
2. thread
1. checkIfRunning
1. 실행중인지 체크
2. 입력 파라미터 threadNum 값 세팅
3. run
1. checkRunningStat
1. state 체크 (STAT_RUNNING 이면 예외 처리)
2. initComponent
1. downloader 세팅
2. pipelines 세팅
3. downloader 스레드 세팅
4. threadPool 세팅
5. startRequest 세팅
3. while loop (조건 interrupted 상태가 아닌지, 실행중인지)
1. Queue 에서 Request 하나 poll 해옴.
2. request 여부에 따라 로직 분기 처리
1. request == null
1. threadPool 상태 및 exitWhenComplete 상태 체크해서 Crawler 종료 상태면 break
2. waitNewUrl()
1. 명시적인 lock 걸고 await 끝난 후 락풀기. 
1. 왜 그런가 하면 무수히 많은 스레드들이 들어올 수 있기 때문
2. request != null
1. ThreadPool.execute ( ** 3.1 이동 **)
1. processRequest
1. downloader.download(request, this) ( ** 4.1 이동 **)
2. 조건 분기 - 
1. page.isDownloadSuccess = true
1. onDownloadSuccess ( ** 1.4 ** 이동)
2. page.isDownloadSuccess = false
1. onDownloaderFail ( ** 1.6 ** 이동)
2. onSuccess(request)
1. for (spiderListener) spiderListener.onSuccess 호출
3. catch 절
1. onError(request)
1. for (spiderListener) spiderListener.onError 호출
4. finally
1. pageCount.increment
2. signalNewUrl
1. lock 걸고 waiting 하고 있는거 깨운 뒤 unlock 함
4. while loop 나오면 stat.set(STAT_STOPPED)
5. close()


4. onDownloadSuccess
1. page statusCode 조건 체크
1. 조건이 true 이면
1. pageProcessor.process(page)
1. 이 부분에 내가 가져오고 싶은 내용을 캐치하면 된다.
2. extractAndAddRequests(page, spawnUrl) ( ** 1.5 ** 이동)
3. getResultItem.skip 이 아니라면
1. for (pipelines) 돌려서 pipeline.process(page.getResultItems)
1. 이 부분에서 데이터 handling 처리
2. 조건이 false 이면
1. page status code error 로그 찍고 끝냄.
2. sleep(site.getSleepTime())
3. return ;
5. extractAndAddRequests
1. for 문 돌리기. targetRequest
1. addRequest(request)
6. onDownloaderFail
1. site.getCycleRetryTimes()조건 분기
1. site.getCycleRetryTimes() == 0 이면
1. sleep(site.getSleepTime())
2. site.getCycleRetryTimes() != 0 이면
1. doCycleRetry(request) ( ** 1.7 이동 **)
7. doCycleRetry
1. 조건에 맞으면 addRequest 함. 그러면 다시 retry 되겠지. 


2. Scheduler
1. push
1. queue 에 request 담음.
3. ThreadPool
1. execute
1. 현재 스레드가 실행되고 있는 개수와 스레드 최대 실행 개수를 비교하여 실행할지 여부 결정
1. Lock 잡고 수행
2. 수행해도 된다면, threadAlive 개수 하나 늘림.
3. ExecutorService.execute 
1. 이 안에서 runnable.run 한 후 끝나면 Lock 걸고 threadAlive 개수 줄임. 그런 후 Lock 풀고

4. HttpClientDownloader
1. download
1. getHttpClient
2. getProxy (default = null)
3. make httpClientRequestContext
4. httpClient.execute()
1. 얘를 통해 httpResponse 를 받음.
5. handleResponse ( ** 4.2 이동 **)
6. onSuccess
1. 아무것도 안함.
7. return page
2. handleResponse
1. 받아온 content 를 byte 로 변환
2. contentType 가져옴.
3. page 생성
4. request 가 바이너리 내용이 아니면
1. page.setBytes(bytes)
2. page.setCharset
3. page.setRawText(new String(bytes, charset)
5. page.setUrl
6. page.setRequest
7. page.setStatusCode
8. page.setDownloadSuccess(true)
9. responseHeader 가 존재하면 setHeaders
10. return page


'Project & Module > Crawler' 카테고리의 다른 글

[Crawler] 구현 시 주의사항  (0) 2017.01.17
[Crawler] Robots.txt 설명  (0) 2017.01.17