需要帮助优化大型网络抓取任务中的循环
Need help optimizing for loop in large webscraping task
我正在开发一个单独的项目,该项目首先使用 rvest 包生成股票数据以进行网络抓取并将其存储在数据表中。
该循环从网站中提取部分股票代码并将其存储在数据框中。我的代码 非常 过时(我认为),部分原因是网站的组织方式。该网站按字母顺序排列页面上的符号,每页上的代码数量不同(每个字母一页)——是的,我必须计算每页有多少。我最终完成的工作但 运行 非常缓慢:
#GET AMEX tickers
alphabet <- c('A','B','C','D','E','F','G','H','I','J','K',
'L','M','N','O','P','Q','R','S','T','U','V',
'W','X','Y','Z')
#start at 2
lengths <- c(65,96,89,125,161,154,86,62,173,83,26,43,62,51,
37,126,25,81,149,52,77,74,34,50,8,11)
amexurls <- paste0("http://findata.co.nz/markets/AMEX/symbols/",toupper(alphabet),".htm",
sep = "")
iterator <- 0
for(j in 1:26){
url <- amexurls[j]
for(k in 2:lengths[j]){
html <- read_html(as.character(url))
iterator
test <- html_nodes(html,as.character(paste0("tr:nth-child(",k,") a")))
test <- toString(test)
test <- gsub("<[^>]+>", "", test)
amexsymbols[k-2+iterator] <- test
}
iterator <- iterator + lengths[j] + 1
}
上面的 for 循环需要一个多小时才能完成 运行。我觉得可能主要是因为上网的电话比较多
我正在努力更好地理解向量化和其他技巧,以最大限度地提高 R 的效率,尤其是在像这样的大项目中。
我拥有的东西 tried/seen:
-我已经从循环体中提取了尽可能多的内容(特别是 paste0 行
-从数据帧切换到数据表
-在更老的 post 中,用户@Gregor(再次感谢)向我展示了我可以利用 paste0 作为矢量化函数,因此 amexurls 没有不要使用 for 循环来存储 - 但不幸的是,这不是代码的缓慢部分
这只是一个更大的网络抓取代码的片段。如果我可以优化这个块,我可以将它应用到其余部分。对我的代码或 tips/tricks 的任何改进将不胜感激。谢谢你的时间。
由于防火墙限制,我现在无法对此进行测试。但我建议尝试使用 rvest
中的 html_table()
函数来收集数据。这比在每一页上手动指定股票数量并单独遍历每一行要动态得多。
library(rvest)
amexurls <- paste0("http://findata.co.nz/markets/AMEX/symbols/", LETTERS,".htm")
ldf <- list()
iterator <- 0
for(url in amexurls){
iterator <- iterator + 1
html <- read_html(url)
ldf[[iterator]] <- html_table(html_nodes(html, "table")[[2]])
}
df <- do.call(rbind, ldf)
我正在开发一个单独的项目,该项目首先使用 rvest 包生成股票数据以进行网络抓取并将其存储在数据表中。
该循环从网站中提取部分股票代码并将其存储在数据框中。我的代码 非常 过时(我认为),部分原因是网站的组织方式。该网站按字母顺序排列页面上的符号,每页上的代码数量不同(每个字母一页)——是的,我必须计算每页有多少。我最终完成的工作但 运行 非常缓慢:
#GET AMEX tickers
alphabet <- c('A','B','C','D','E','F','G','H','I','J','K',
'L','M','N','O','P','Q','R','S','T','U','V',
'W','X','Y','Z')
#start at 2
lengths <- c(65,96,89,125,161,154,86,62,173,83,26,43,62,51,
37,126,25,81,149,52,77,74,34,50,8,11)
amexurls <- paste0("http://findata.co.nz/markets/AMEX/symbols/",toupper(alphabet),".htm",
sep = "")
iterator <- 0
for(j in 1:26){
url <- amexurls[j]
for(k in 2:lengths[j]){
html <- read_html(as.character(url))
iterator
test <- html_nodes(html,as.character(paste0("tr:nth-child(",k,") a")))
test <- toString(test)
test <- gsub("<[^>]+>", "", test)
amexsymbols[k-2+iterator] <- test
}
iterator <- iterator + lengths[j] + 1
}
上面的 for 循环需要一个多小时才能完成 运行。我觉得可能主要是因为上网的电话比较多
我正在努力更好地理解向量化和其他技巧,以最大限度地提高 R 的效率,尤其是在像这样的大项目中。
我拥有的东西 tried/seen:
-我已经从循环体中提取了尽可能多的内容(特别是 paste0 行
-从数据帧切换到数据表
-在更老的 post 中,用户@Gregor(再次感谢)向我展示了我可以利用 paste0 作为矢量化函数,因此 amexurls 没有不要使用 for 循环来存储 - 但不幸的是,这不是代码的缓慢部分
这只是一个更大的网络抓取代码的片段。如果我可以优化这个块,我可以将它应用到其余部分。对我的代码或 tips/tricks 的任何改进将不胜感激。谢谢你的时间。
由于防火墙限制,我现在无法对此进行测试。但我建议尝试使用 rvest
中的 html_table()
函数来收集数据。这比在每一页上手动指定股票数量并单独遍历每一行要动态得多。
library(rvest)
amexurls <- paste0("http://findata.co.nz/markets/AMEX/symbols/", LETTERS,".htm")
ldf <- list()
iterator <- 0
for(url in amexurls){
iterator <- iterator + 1
html <- read_html(url)
ldf[[iterator]] <- html_table(html_nodes(html, "table")[[2]])
}
df <- do.call(rbind, ldf)