RCurl没有检索网站的完整源文本 - 缺少链接?

时间:2011-10-25 14:04:33

标签: r web-crawler web-scraping rcurl

我想使用RCurl作为礼貌的网络浏览器从网站下载数据。 显然我需要用于科学研究的数据。虽然我有权通过我的大学访问网站内容,但网站的使用条款禁止使用网络浏览器。

我试图直接向网站管理员询问数据,但他们只是以非常模糊的方式回复。好吧无论如何,似乎他们不会简单地将基础数据库发送给我。

我现在要做的是要求他们正式获得一次性许可,使用基于RCurl的R代码从他们的网站下载特定的纯文本内容,其中包括每个请求执行后的三秒延迟

我想从工作中下载数据的网站的地址如下: http://plants.jstor.org/specimen/ 网站的ID

我尝试用RCurl编程,但我无法完成它。 一些事情使事情变得复杂:

  1. 如果允许 cookies ,我们只能访问该网站(我使用cookiefile参数在RCurl中工作)。

  2. 当通过点击普通浏览器中的不同链接实际访问网站时,下一步按钮仅出现在源代码中。 在源代码中,Next按钮使用包含

    的表达式进行编码
    <a href="/.../***ID of next site***">Next &gt; &gt; </a>
    

    当一个人试图直接访问该网站时(之前没有在同一个浏览器中点击它),它将无法工作,带链接的行根本就不在源代码中。

  3. 网站的ID是字母和数字的组合(例如“goe0003746”或“cord00002203”),所以我不能简单地在R中编写一个for循环尝试每个数字从1到1,000,000。

  4. 所以我的程序应该模仿通过下一个按钮点击所有网站的人,每次都保存文本内容。

    每次保存网站内容后,应该等待三秒,然后再点击下一步按钮(它必须是礼貌的抓取工具)。我也使用Sys.sleep函数在R中工作。

    我还想过使用自动程序,但似乎有很多这样的程序,我不知道使用哪一个。

    我也不是程序编写者(除了R之外),所以我非常感谢不包含Python,C ++,PHP等编程的解决方案。

    任何想法都将不胜感激!非常感谢您提出意见和建议!!

2 个答案:

答案 0 :(得分:2)

尝试不同的策略。

 ##########################
 ####
 ####            Scrape http://plants.jstor.org/specimen/
 ####        Idea:: Gather links from http://plants.jstor.org/search?t=2076
 ####            Then follow links:
 ####
 #########################

 library(RCurl)
 library(XML)

 ### get search page::

 cookie = 'cookiefile.txt'
 curl  =  getCurlHandle ( cookiefile = cookie , 
     useragent =  "Mozilla/5.0 (Windows; U; Windows NT 5.1; en - US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6",
     header = F,
     verbose = TRUE,
     netrc = TRUE,
     maxredirs = as.integer(20),
     followlocation = TRUE)

 querry.jstor <- getURL('http://plants.jstor.org/search?t=2076', curl = curl)

 ## remove white spaces:
 querry.jstor2 <- gsub('\r','', gsub('\t','', gsub('\n','', querry.jstor)))

 ### get links from search page
  getLinks = function() {
        links = character()
        list(a = function(node, ...) {
                    links <<- c(links, xmlGetAttr(node, "href"))
                    node
                 },
             links = function()links)
      }

 ## retrieve links
  querry.jstor.xml.parsed <- htmlTreeParse(querry.jstor2, useInt=T, handlers = h1)

 ## cleanup links to keep only the one we want. 
  querry.jstor.links = NULL
  querry.jstor.links <- c(querry.jstor.links, querry.jstor.xml.parsed$links()[-grep('http', querry.jstor.xml.parsed$links())]) ## remove all links starting with http
  querry.jstor.links <- querry.jstor.links[-grep('search', querry.jstor.links)] ## remove all search links
  querry.jstor.links <- querry.jstor.links[-grep('#', querry.jstor.links)] ## remove all # links
  querry.jstor.links <- querry.jstor.links[-grep('javascript', querry.jstor.links)] ## remove all javascript links
  querry.jstor.links <- querry.jstor.links[-grep('action', querry.jstor.links)] ## remove all action links
  querry.jstor.links <- querry.jstor.links[-grep('page', querry.jstor.links)] ## remove all page links

 ## number of results
  jstor.article <- getNodeSet(htmlTreeParse(querry.jstor2, useInt=T), "//article")
  NumOfRes <- strsplit(gsub(',', '', gsub(' ', '' ,xmlValue(jstor.article[[1]][[1]]))), split='')[[1]]
  NumOfRes <- as.numeric(paste(NumOfRes[1:min(grep('R', NumOfRes))-1], collapse = ''))

  for(i in 2:ceiling(NumOfRes/20)){
    querry.jstor <- getURL('http://plants.jstor.org/search?t=2076&p=',i, curl = curl)
    ## remove white spaces:
    querry.jstor2 <- gsub('\r','', gsub('\t','', gsub('\n','', querry.jstor)))
    querry.jstor.xml.parsed <- htmlTreeParse(querry.jstor2, useInt=T, handlers = h1)
    querry.jstor.links <- c(querry.jstor.links, querry.jstor.xml.parsed$links()[-grep('http', querry.jstor.xml.parsed$links())]) ## remove all links starting with http
    querry.jstor.links <- querry.jstor.links[-grep('search', querry.jstor.links)] ## remove all search links
    querry.jstor.links <- querry.jstor.links[-grep('#', querry.jstor.links)] ## remove all # links
    querry.jstor.links <- querry.jstor.links[-grep('javascript', querry.jstor.links)] ## remove all javascript links
    querry.jstor.links <- querry.jstor.links[-grep('action', querry.jstor.links)] ## remove all action links
    querry.jstor.links <- querry.jstor.links[-grep('page', querry.jstor.links)] ## remove all page links

    Sys.sleep(abs(rnorm(1, mean=3.0, sd=0.5))) 
  }

  ## make directory for saving data: 
  dir.create('./jstorQuery/')

  ## Now we have all the links, so we can retrieve all the info
  for(j in 1:length(querry.jstor.links)){
    if(nchar(querry.jstor.links[j]) != 1){
       querry.jstor <- getURL('http://plants.jstor.org',querry.jstor.links[j], curl = curl)
       ## remove white spaces:
       querry.jstor2 <- gsub('\r','', gsub('\t','', gsub('\n','', querry.jstor)))

       ## contruct name:
       filename = querry.jstor.links[j][grep( '/', querry.jstor.links[j])+1 : nchar( querry.jstor.links[j])]

       ## save in directory: 
       write(querry.jstor2, file = paste('./jstorQuery/', filename, '.html', sep = '' ))

       Sys.sleep(abs(rnorm(1, mean=3.0, sd=0.5))) 
    }
  }

答案 1 :(得分:1)

我可能遗漏了你被挂断的那一滴,但听起来你几乎就在那里。

您似乎可以请求第1页上的Cookie。然后解析搜索下一个站点ID的内容,然后通过使用下一个站点ID构建URL来请求该页面。然后刮掉你想要的任何数据。

听起来你的代码几乎完成了所有这些。解析第1页的问题是获取下一步的ID吗?如果是这样,你应该制定一个可重复的例子,我怀疑你会得到一个非常快速的答案来解决你的语法问题。

如果您无法查看该网站的功能,我建议您使用适用于Firefox的Tamper Data插件。它会让你看到每次点击鼠标时发出的请求。我发现它对这类事物非常有用。