网络爬虫与R

时间:2012-08-18 19:26:58

标签: r if-statement for-loop web-crawler

我有一个问题,我想要一些帮助。我需要创建一个可以加载到csv文件中的R代码。 csv文件包含一个名为“Link”的列,对于每个i(Row),都有一个链接,代码需要从该链接下载链接的内容并将其放在单独的csv文件中。到目前为止,我已经管理好查找并修改了下面显示的代码段。 (感谢Christopher Gandrud及其合着者)

library(foreign)
library(RCurl)

addresses <- read.csv(">>PATH TO CSV FILE<<")

for (i in addresses) full.text <- getURL(i)

text <- data.frame(full.text)

outpath <-">>PATH TO SPECIFIED FOLDER<<"

x <- 1:nrow(text)

for(i in x) {
  write(as.character(text[i,1]), file = paste(outpath,"/",i,".txt",sep=""))
}

实际上代码工作正常,但问题是我的服务器超载了请求,所以在从100-150链接下载了正确的内容之后,这些文件只是空的。我知道这是一个问题,因为我已经多次测试链接数量减少了。实际上如果我当时只下载100个链接就没问题了。超过100它开始成为一个问题。尽管如此,我需要在这段代码中实现一些东西,以便它成为这项特定任务的良好爬虫。

我已将问题分成两部分,因为解决问题应该暂时解决问题。

  1. 我想每100次下载使用Sys.Sleep函数。因此,代码会触发前100个链接的100个请求,然后暂停x秒,然后再触发下100个请求...

  2. 对我的数据集/ csv文件中的所有行/链接完成此操作后,我需要检查每个csv文件中的两个条件。它们不能为空,它们不能包含服务器在某些特殊情况下给出的某些错误消息。如果这两个条件中的一个是真的那么它需要将文件名(链接号)保存到我可以从那里使用的向量中。

  3. 哇这个问题突然变得很长。我意识到这是一个很大的问题,我问了很多。这是我的硕士论文,它不是真正关于R编程,但我需要从许多我可以访问的网站下载内容。接下来我要分析内容,这就是我的论文的内容。欢迎任何建议/意见。


     library(foreign)  
     library(RCurl)  
    
     addresses <- read.csv("~/Dropbox/Speciale/Mining/Input/Extract post - Dear Lego n(250).csv")  
    
     for (i in addresses) {  
    +   if(i == 50) {  
    +     print("Why wont this work?")  
    +     Sys.sleep(10)  
    +     print(i)  
    +   }  
    +   else {  
    +     print(i)  
    +   }  
    + }  
    

    “然后在加载的链接上列出一个完整的列表。没有”为什么不工作“在i == 50”后跟

    警告信息

    In if (i == 100) {:
     the condition has length > 1 and only the first element will be used  
    full.text <- getURL(i)  
    text <- data.frame(full.text)  
    outpath <-"~/Dropbox/Speciale/Mining/Output"  
    x <- 1:nrow(text)  
    for(i in x) {  
    write(as.character(text[i,1]), file = paste(outpath,"/",i,".txt",sep=""))}  
    

    能够帮助我更多吗?

2 个答案:

答案 0 :(得分:0)

跟进我的评论 - 这是一个基本概念,在你的循环中间放入一个Sys.sleep。

for (i in 1:10) { 
  if(i == 5) {
      print("halfwayhome")
      Sys.sleep(5)
      print(i)
  }
  else { 
      print(i)
  }
}

结果:

[1] 1
[1] 2
[1] 3
[1] 4
[1] "halfwayhome"
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10

所以我没有任何RCurl或解析HTML页面的经验,所以我方便地避免了你的那部分任务。但是,我能够成功生成地址列表,使用readLines()下载它们,然后将它们写回。我在每个人之后加了一个Sys.sleep()电话,事情好像很有效。

links <- c("http://news.lugnet.com/dear-lego/?n=1",
           "http://news.lugnet.com/dear-lego/?n=2",
           "http://news.lugnet.com/dear-lego/?n=3",
           "http://news.lugnet.com/dear-lego/?n=4",
           "http://news.lugnet.com/dear-lego/?n=5",
           "http://news.lugnet.com/dear-lego/?n=6",
           "http://news.lugnet.com/dear-lego/?n=7",
           "http://news.lugnet.com/dear-lego/?n=8",
           "http://news.lugnet.com/dear-lego/?n=9",
           "http://news.lugnet.com/dear-lego/?n=10"
           )

for (j in 1:length(links)){
  dat <- readLines(links[j])
  write.table(dat, paste0("outfile",j,"txt"))
  Sys.sleep(5)
  cat("Finished file", j)
}

如果您需要解析这些HTML页面或从中获取更多有用的内容,我会问一个新的/不同的问题,我可能在这方面没有太多帮助。

希望这有帮助, -Chase

答案 1 :(得分:0)

最终解决方案:

> library(RCurl)  
> library(foreach)  
> library(foreign)

> z <- nrow(links)  
> outpath <-"SPECIFIC PATH"

> foreach(i=1:z) %do% {    
+  text <- getURL(links[i,])    
+  write(as.character(text), file = paste(outpath,"/",i,".txt",sep=""))}