URL 리스트 취합

웹 스크래핑은 타겟이 되는 인터넷 페이지의 url을 확인하는 것으로 시작한다. 한두 개의 웹페이지라면 모르겠지만 스크래핑 대상물이 여러 페이지에 흩어져 있다면 인터넷 주소를 취합하는 간단한 작업도 초보자에겐 큰 장애물이 된다. 그러나 문법이 조금 익숙한 사용자라면 반복문을 사용하여 좀 더 간편하게 필요한 url 리스트를 구성할 수 있다. 통상의 웹페이지 주소는 main URl에 인덱스가 붙는 형식으로 구성되어 있기 때문이다. 예컨데 이렇게 말이다.

main <- "www.main_url.co.kr/search="
search <- c("apple", "orange", "pineapple")
index <- "&indexpage="

url_list <- NULL

for (i in 1:3){
  for (j in 1:3) {
    url <- paste0(main, search[i], index, j)
    url_list <- append(url_list, url)
  }
}

url_list
## [1] "www.main_url.co.kr/search=apple&indexpage=1"    
## [2] "www.main_url.co.kr/search=apple&indexpage=2"    
## [3] "www.main_url.co.kr/search=apple&indexpage=3"    
## [4] "www.main_url.co.kr/search=orange&indexpage=1"   
## [5] "www.main_url.co.kr/search=orange&indexpage=2"   
## [6] "www.main_url.co.kr/search=orange&indexpage=3"   
## [7] "www.main_url.co.kr/search=pineapple&indexpage=1"
## [8] "www.main_url.co.kr/search=pineapple&indexpage=2"
## [9] "www.main_url.co.kr/search=pineapple&indexpage=3"

climate watch data의 페이지 구성

그러나 이번에 스크래핑한 www.climatewatchdata.org는 웹페이지가 매우 독특한 구성으로 되어있어 위의 경우처럼 간단한 반복문으로는 url을 취합하기 어려웠다. 그림처럼 개별 섹션(Sectoral Mitication Targets) 및 섹터(Energy | Renewable Energy) 별로 해당되는 목록을 취합하기 위해서는 섹터 및 섹션별 url을 따로 만들어야 했는데 다음과 같은 복잡한 과정을 거쳐야 했기 때문이다.

  1. 먼저 url https://www.climatewatchdata.org/ndcs/country/IND/sectoral-information로 들어가 총 5개의 섹션 리스트를 가져온다.
  2. 각각의 섹션리스트를 모두 소문자로 변경하여 각 섹션별 주소를 구성한다. (ex: https://www.climatewatchdata.org/ndcs/country/IND/sectoral-information?section=sectoral_mitigation_targets)
  3. 각 섹션별로 모든 섹터 리스트(ex, Energy | Renewable Energy, Energy | Renewable Energy:Biofuels….)를 가져온다.
  4. 모든 섹터 리스트를 기호 “|” 를 기준으로 쪼갠 다음 “|” 뒤에 위치하고 있는 문자를 소문자로 변경한다.
  5. 위 4에서 만든 섹션을 가지고 각 섹션별 전체 주소리스트를 구성한다.

위의 5단계를 거쳐 최종적으로 만들어진 https://www.climatewatchdata.org/ndcs/country/IND/sectoral-information?section=sectoral_mitigation_targets&sector=renewable_energy의 주소는 sectoral_mitication 섹션의 renewable_energy섹터의 목록을 스크래핑하는 기본 url이 된다.

이상의 5가지 단계를 실행하기 위해 다음의 코드를 작성하였다.

########### Section 취합 #############
### 1. 대문 page 이동
remDr$navigate("https://www.climatewatchdata.org/ndcs/country/IND/sectoral-information?section=none&sector=none") 
## 대문 page source 읽기
html_page <- remDr$getPageSource()[[1]]

### 2. section 주소  : section_link 주소
section <- read_html(html_page) %>% html_nodes("div.accordion-styles__title__2PD3i") %>% html_text() 
section_adr <- str_replace_all(str_to_lower(section), " ", "_") ##대문자 to 소문자, 공백을 "_"로 대체


########### 주소 취합 #############
main <- "https://www.climatewatchdata.org/ndcs/country/IND/sectoral-information?section="
section_sector <- NULL
link_list <- NULL

for (i in 1:length(section_adr)) {
  
  section_link <- paste0(main, section_adr[i], "&sector=none")
  
  ### 3. sector 주소  : sector_link 주소
  remDr$navigate(section_link)
  Sys.sleep(3) # 3초 딜레이
  
  section_page <- remDr$getPageSource()[[1]]
  sector <- read_html(section_page) %>% html_nodes("div.ndcs-country-accordion-styles__subAccordion__1zDx7") %>% html_nodes("div.accordion-styles__title__2PD3i") %>% html_text() 
  
  link_list <- cbind(i, section[i], section_adr[i], sector)
  section_sector <- rbind(section_sector, link_list)
}

section_sector <- data.frame(section_sector)
names(section_sector) <- c("index", "section", "section_adr", "sector")
section_sector$sector_adr <- str_to_lower(section_sector$sector)
section_sector$sector_adr <- str_split_fixed(section_sector$sector_adr, "[|]", 2)[,2]
section_sector$sector_adr <- str_trim(section_sector$sector_adr)
section_sector$sector_adr <- str_replace_all(section_sector$sector_adr, "[-:/ ]", "_")
section_sector$sector_adr <- str_replace_all(section_sector$sector_adr, "__", "_")

### 주소 만들기
link_pool <- NULL
for (i in 1:dim(section_sector)[1]) {
  link <- paste0(main, section_sector$section_adr[i], "&sector=", section_sector$sector_adr[i])
  link_pool <- append(link_pool, link)
}

section_sector <- cbind(section_sector, link_pool)

참고로 해당 웹페이지가 java로 구성되었는지 rvest로는 html 태그를 확인할 수 없었다. 차선책으로 Rselenium을 사용하였으며 끊김없는 안정적인 스크래핑을 위해 중간중간 Sys.sleep(3)의 코드를 추가하였다.

이 외에 데이터를 취합하는 내용을 포함한 전체 코드는 Github에 올려두었다.

comments powered by Disqus
Next
Previous