我正在更新我的 rNOMADS package包括 NOMADS 网站上的所有模型。为此,我必须为每个模型搜索 html 目录树。我事先不知道这棵树有多深,也不知道它有多少枝条。因此,我正在编写一个简单的网络爬虫来递归搜索首页链接,跟踪每个链接,并返回没有更多链接的页面的 URL。这样的页面就是模型数据的下载页面。 Here is an example必须搜索的 URL。
我想得到这个下面所有网页的地址。 我尝试过这段代码:
library(XML)
url <- "http://nomads.ncep.noaa.gov/cgi-bin/filter_cmcens.pl"
WebCrawler <- function(url) {
doc <- htmlParse(url)
links <- xpathSApply(doc, "//a/@href")
free(doc)
if(is.null(links)) { #If there are no links, this is the page we want, return it!
return(url)
} else {
for(link in links) { #Call recursively on each link found
print(link)
return(WebCrawler(link))
}
}
}
但是,我还没有找到返回所有“死胡同”页面列表的好方法。 相反,这段代码只会返回一个模型页面,而不是它们的整个列表。 我可以声明一个全局变量并将 URLS 保存到该变量,但我想知道是否有更好的方法来解决这个问题。我应该如何构建这个函数来为我提供一个包含每个页面的列表?
最佳答案
你的错误在于递归:
## THIS IS INCORRECT
for(link in links) { #Call recursively on each link found
print(link)
return(WebCrawler(link)) <~~~ Specifically this line
}
这里没有递归属性,您只是沿着一个分支深入挖掘。
*
/ \
\
\
\
\
*
您不想返回 WebCrawler(link)
的值。
相反,您想捕获那个值,然后返回值的集合。
ret <- vector("list", length=length(links))
for(link in links) { #Call recursively on each link found
print(link)
ret[[link]] <- WebCrawler(link) <~~~ Specifically this line
}
return(ret) # or return(unlist(ret))
更新:
可能值得考虑一下您对最终输出的期望是什么?你会得到一个深度嵌套的列表。如果您只想要结束节点,您可以 unlist(.. recursive=TRUE, use.names=FALSE)
或者您甚至可以在进行过程中取消列出,但这可能会减慢您的速度。可能值得对其进行基准测试以确保。
关于html - 在网页中搜索链接,关注它们,并在 R 中返回没有链接的页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19384125/