2017-05-08 58 views
0

我正在寻找一些有效的解决方案,以从the Vermont Secretaty of State中刮取清理的xpath数千次迭代。这是冠军,我试图刮中的XPath:大数据(〜90k)XPath刮

'//*[@id="content_wrapper"]/div[2]/div/h1' 

我挣扎在寻找清洁高效的方式来运行一个循环,经过约90000页环,抓住标题,并将其存储在向量中。最终目标是导出包含页面值和标题xpath的小数据框。我将使用这个数据框来为数据库中的未来搜索建立索引。

这是我到目前为止有:

library(XML) 
library(rvest) 

election_value <- 1:90000 
title <- NA 

for (i in 1:90000) { 
    url <- sprintf("http://vtelectionarchive.sec.state.vt.us/elections/view/%s", election_value[i]) 
    if (is.null(tryCatch({read_html(url) %>% html_nodes(xpath='//*[@id="content_wrapper"]/div[2]/div/h1') %>% html_text()}, error=function(e){}))) { 
    title[i] <- NA } else { 
     title[i] <- read_html(url) %>% html_nodes(xpath='//*[@id="content_wrapper"]/div[2]/div/h1')} 
} 
vermont_titles <- data.frame(election_value, title) 
write.csv(vermont_titles, 'vermont_titles.csv') 

不幸的是,该脚本无法正常工作,因为html_nodes()函数返回括号中的字符串,而不仅仅是文字。任何解决方案,将不胜感激,因为这个脚本一直困扰我一个星期左右。

+0

请检查您发布的网址,“http://vtelectionarchive.sec.state.vt.us/elections/查看/%s“,产生一个'400错误的请求'。我认为,正确的网址是http://vtelectionarchive.sec.state.vt.us/elections/search/year_from:1789/year_to:2016 – Ashish

+0

'%s'正在替代它所在的数字b/c一个'sprintf()'调用。目前还不清楚OP在尝试做什么。 – hrbrmstr

回答

2

这里是一个工作解决方案。查看评论了解更多详细信息:

library(rvest) 

#url<-"http://vtelectionarchive.sec.state.vt.us/elections/view/68156" 
election_value <- 68150:68199 

#predefine title vector 
title <- vector("character", length=length(election_value)) 

for (i in 1:50) { 
    url <- sprintf("http://vtelectionarchive.sec.state.vt.us/elections/view/%s", election_value[i]) 
    #read page and test if null 
    page<-tryCatch({read_html(url)}, error=function(e){}) 
    if (is.null(page)) 
    { 
     title[i] <- NA } 
    else { 
    #parse the page and extract the title as text 
    node<-page %>% html_nodes(xpath='//*[@id="content_wrapper"]/div[2]/div/h1') 
    title[i] <- node %>% html_text() 
    } 
} 
vermont_titles <- data.frame(election_value, title) 
write.csv(vermont_titles, 'vermont_titles.csv') 

有两点要注意:阅读的页面中,而不是一次最多两次,解析页面只有1次将提高性能。另外,预先定义标题作为矢量是另一个性能提升。

1

另一种解决方案可能是:

require(tidyverse) 
require(rvest) 
election_value <- c(3,68150:68153) 
base_url <- "http://vtelectionarchive.sec.state.vt.us/elections/view/" 
urls <- paste0(base_url, election_value) 

map(urls, possibly(read_html, NA_character_)) %>% 
    map_if(negate(is.na), html_nodes, xpath = '//*[@id="content_wrapper"]/div[2]/div/h1') %>% 
    map_if(negate(is.na), html_text) %>% 
    as.character %>% 
    tibble(election_value, title = .) 

返回:

# A tibble: 5 × 2 
    election_value             title 
      <dbl>             <chr> 
1    3             NA 
2   68150 2014 Probate Judge General Election Rutland County 
3   68151 2014 Probate Judge General Election Orleans County 
4   68152 2014 Probate Judge General Election Grand Isle County 
5   68153 2014 Probate Judge General Election Lamoille County