1

我有一个 URL 列表(足够大),我想检查它们的 HTML 代码是否有效。如果不是,我想知道错误和警告的数量,比如这个页面的结果:http: //validator.w3.org/

因此,希望通过 RI 将我的 URL 提交到该网页,然后解析结果以获取我需要的信息。还有另一种方法吗?

我找到了 RCurl 包,但我不确定如何去做。我会很感激任何帮助。

提前致谢。

编辑:

我尝试了下面的代码,这似乎可以完成这项工作,尽管由于某些未知原因我仍然无法处理一些 URL,我收到错误并且代码停止(因此我失去了一切)。

HTMLValid=foreach(i=1:nrow(allData), .combine='rbind') %dopar% {
  library(RCurl)
  library(XML)
  url=paste("http://validator.w3.org/check?uri=",
            as.character(allData$url[i]),
            "&charset=%28detect+automatically%29&doctype=Inline&group=0#preparse_warnings",
            sep="")
  w = getURL(url,httpheader = c('User-Agent' = "Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0"))


  doc <- htmlTreeParse(w, getDTD = F)
  r=xmlRoot(doc)
  text=r[["body"]][[2]][[4]][[1]][[1]][[2]][[1]]
  errors=strsplit(toString.XMLNode(text),' ')[[1]][1]
  warnings=strsplit(toString.XMLNode(text),' ')[[1]][3]

  c(as.numeric(errors),as.numeric(warnings))
}

当页面在特定时间范围内没有响应时,我可能会收到错误消息。我该如何克服呢?有没有办法更快地完成程序?

4

1 回答 1

0

对您的代码的一些评论。

你可能不应该在你的 for 循环中加载你的库。我不确定这会导致崩溃,但你应该只加载你的库一次。

更重要的是,不要将您的网络抓取并行化。这有三个原因:1)我认为您的处理能力不会成为这里的瓶颈,因此您可能不会通过并行化获得任何性能。2)错误可能来自您对网站的过于频繁的请求,它“把你扔出去”。3)您没有收集结果,因此您会丢失所有先前获得的结果。

一个简单的解决方法:使用普通的 for 循环,最好在内部设置一些计时器,以确保您每秒不会发出太多请求。在循环的每个步骤中将结果保存到列表中(增加列表的大小)。

如果它最终仍然出现错误,至少您将存储以前的结果并且您会知道它在哪个点崩溃(因此您可以手动重新处理该单个示例,看看出了什么问题)。

另一种可能性是将循环内部包含在 tryCatch 中,以便跳过引发错误的情况并继续继续。

这是您重新编写的代码。我还没有运行它。

library(RCurl)
library(XML)
results <- list()
for (i=1:nrow(allData)) {

  Sys.sleep(1)

  try({
  url=paste("http://validator.w3.org/check?uri=",
            as.character(allData$url[i]),
            "&charset=%28detect+automatically%29&doctype=Inline&group=0#preparse_warnings",
           sep="")
  w = getURL(url,httpheader = c('User-Agent' = "Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0"))

  doc <- htmlTreeParse(w, getDTD = F)
  r=xmlRoot(doc)
  text=r[["body"]][[2]][[4]][[1]][[1]][[2]][[1]]
  errors=strsplit(toString.XMLNode(text),' ')[[1]][1]
  warnings=strsplit(toString.XMLNode(text),' ')[[1]][3]
  results[[i]] <- c(as.numeric(errors),as.numeric(warnings))
  })
}

Results <- do.call("rbind", results)
于 2016-06-21T15:52:29.440 回答