【问题标题】:Webcrawl with R使用 R 进行网络爬虫
【发布时间】:2012-08-18 19:26:57
【问题描述】:

我有一个问题需要帮助。我需要创建一段可以加载到 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 个请求,然后在触发下一个 100 个请求之前暂停 x 秒...

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

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


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

能帮我更多吗?

【问题讨论】:

  • 我建议将其分成两个问题。至于你的第一个,你为什么不放一个条件来检查你的迭代器是否是 100 的倍数,即if i%%100 == 0 then Sys.sleep(yourTimeHere)...
  • 我同意这两个问题(我是新手,会尝试调整)。可以看到有人提议改变我的问题。我会尝试解决你提出的问题,我会尽快发布解决方案。我的基本问题是具有 VBA 编程的基本技能,但刚开始使用 R。所以我不知道不同的循环是如何工作的,以及如何为我制作一个“计数器”,就像我在 VBA 中很容易做到的那样。跨度>
  • 基本结构或多或少是相同的,尽管我会在 R 中自动递增...为了测试这一点,请执行 for (i in 1:10) {print(i)}

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


【解决方案1】:

跟进我的 cmets - 这是一个基本概念,可在循环的中途放入 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 页面或从中获得更有用的东西,我会问一个新的/不同的问题,我可能不会在这方面提供太多帮助。

希望这会有所帮助, -追逐

【讨论】:

  • 啊,是的,正是我需要的帮助。我现在得去睡觉了,但明天我会写代码。非常感谢您的帮助。真的很感激。 (我花了大约 20 个小时从“必须有一些软件可以为我做到这一点”到“嗯,看来我得自己编写代码了,这也很有趣)
  • @KasperChristensen - 如果这个答案“回答”了您的问题,那么它旁边会有一个空白的“复选标记”,您可以单击它来表示它。 “向上”和“向下”箭头也可以用来表示“这个答案是否有用”。这两种行为都会为回答的人带来“声誉”……这是“堆栈溢出的货币”。 FAQ 比我解释得更好,所以我会检查一下。祝你好运!
  • 看来我必须进入这个论坛,因为它比我想象的更有条理,这很好。非常感谢直到现在。今晚我会尽量让代码正常工作,一定会给你一些声望分。
  • 看来我还需要你的帮助。我写了这段代码,但它仍然没有给我正在寻找的数据......似乎“Sys.sleep”在错误的地方,因为它似乎仍然一次触发所有请求?
  • @KasperChristensen - 更新了我的答案,希望这更接近您正在寻找的内容。
【解决方案2】:

最终解决方案:

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

【讨论】:

  • 只是为了总结如何构建一个爬虫/爬虫,它可以下载指定 URL 的向量并将它们中的每一个保存到特定的文本文件中。我最终不需要 Sys.sleep 函数,因为这个函数“足够慢”。然而,这给了我一个问题,因为它实际上有点慢,但它能够通过一些手动工作来解决我的问题。特别感谢 Chase,他一路帮助我。我意识到最终的解决方案并不在 Chase 附近,但我从他的帖子中学到了很多。卡斯帕
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多