搜索网页中的链接,关注它们,并返回R中没有链接的页面

时间:2013-10-15 14:43:07

标签: html r hyperlink web-crawler

我正在撰写对rNOMADS package的更新,以便将所有模型都包含在NOMADS网站上。为此,我必须在每个模型的html目录树中搜索。我不知道这棵树有多深,或者它含有多少分枝。因此,我正在编写一个简单的Web爬虫,以递归方式搜索首页的链接,跟踪每个链接,并返回没有链接的页面的URL。这样的页面是模型数据的下载页面。必须搜索的网址Here is an example

我想获取此页下方所有网页的地址。 我试过这段代码:

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))
        }
    }
}

但是,我还没有想出一个返回所有“死胡同”页面列表的好方法。 相反,此代码只返回一个模型页面,而不是它们的整个列表。 我可以声明一个全局变量并将URL保存到该变量,但我想知道是否有更好的方法来解决这个问题。我该如何构建这个函数来给我一个每一页的列表?

1 个答案:

答案 0 :(得分:1)

你的错误在递归中:

## 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)或者甚至可以在你进行时取消列出,但这可能会减慢你的速度。可能值得对它进行基准测试。