2013-08-20 35 views
1

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

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

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

在此先感谢。

编辑:

我尝试下面的代码,这似乎有种做的工作,虽然我还不能处理一些未知的原因,我得到一个错误,代码停止(因此我失去了一些网址一切)。

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

如果页面在特定的时间范围内没有响应,可能会出现错误。我该如何克服这一点?有没有办法更快地完成该过程?

+0

您可以尝试'library(XML)'中的'xmlSchemaValidate'。 – Thomas

+0

您可以指定foreach'.errorhandling ='remove''选项来过滤错误并仅返回成功的任务结果。通过这种方式,您可以在几项任务失败时避免失去一切。 –

+0

@SteveWeston通过这种方式,我将无法识别出我没有得到结果的案例。或者,也许我可以在结果中附加迭代器! 托马斯我会试试看!谢谢!! – Stergios

回答

0

对你的代码的一些评论。

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

更重要的是,不要平行你的网页抓取。有三个原因: 1)我没有看到你的处理能力将成为瓶颈,所以你可能不会通过并行获得任何性能。 2)错误可能来自您对网站提出过于频繁的请求,并“将您抛出”。 3)你没有收集结果,因为他们来了,所以你失去了以前获得的所有结果。

一个简单的解决方法:使用正常的循环,最好在里面有一些定时器,以确保你每秒不会发出太多的请求。在循环的每一步将结果保存到列表中(增加列表的大小)。

如果它最终仍然出现错误,至少你会保存以前的结果,你会知道它在哪一点崩溃(所以你可以手工重做这个例子,看看出了什么问题)。

另一种可能性是将你的循环的内部封装在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)