3

RCurl を丁寧な Web クローラーとして使用して、Web サイトからデータをダウンロードしたいと考えています。明らかに、科学研究のためのデータが必要です。私は大学経由でウェブサイトのコンテンツにアクセスする権利を持っていますが、ウェブサイトの利用規約により、ウェブクローラーの使用が禁止されています。

サイトの管理者にデータを直接尋ねようとしましたが、非常に漠然とした回答しかありませんでした。とにかく、基礎となるデータベースを単純に私に送ってくれないようです。

私が今やりたいことは、各リクエストが実行されてから 3 秒の遅延を含む RCurl に基づく R コードを使用して、サイトから特定のテキストのみのコンテンツをダウンロードするための 1 回限りの許可を取得するように公式に依頼することです。

仕事からデータをダウンロードしたいサイトのアドレス: http://plants.jstor.org/specimen/サイトの ID

RCurl でプログラムしようとしましたが、実行できません。いくつかのことが複雑になります。

  1. Cookieが許可されている場合にのみ Web サイトにアクセスできます(Cookiefile 引数を使用して RCurl で動作するようになりました)。

  2. [次へ] ボタンは、通常のブラウザでさまざまなリンクをクリックして実際にサイトにアクセスした場合にのみ、ソース コードに表示されます。ソース コードでは、[次へ] ボタンは次のような式でエンコードされています。

    <a href="/.../***ID of next site***">Next &gt; &gt; </a>
    

    サイトに直接アクセスしようとすると (以前に同じブラウザーでクリックしたことがなくても)、リンクのある行がソース コードに含まれていないため、機能しません。

  3. サイトの ID は文字と数字の組み合わせ(「goe0003746」や「cord00002203」など) であるため、1 から 1,000,000 までのすべての数字を試行する for ループを R で単純に記述することはできません。

したがって、私のプログラムは、テキスト コンテンツを保存するたびに [次へ] ボタンを使用してすべてのサイトをクリックする人を模倣することになっています。

サイトのコンテンツを保存するたびに、[次へ] ボタンをクリックする前に3 秒待つ必要があります (丁寧なクローラーである必要があります)。Sys.sleep 関数を使用して、R でも動作するようになりました。

自動化されたプログラムを使うことも考えましたが、そのようなプログラムがたくさんあるようで、どれを使用すればよいかわかりません。

また、私は (少しの R を除いて) プログラムを書く人ではないので、Python、C++、PHP などでのプログラミングを含まないソリューションを本当に感謝しています。

どんな考えでも大歓迎です!コメントや提案を事前にありがとうございました!!

4

2 に答える 2

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))) 
    }
  }
于 2011-12-02T13:07:47.880 に答える
1

私はあなたがハングアップしている部分を正確に見逃しているかもしれませんが、あなたはほとんどそこにいるように聞こえます.

Cookie をオンにしてページ 1 をリクエストできるようです。次に、コンテンツを解析して次のサイト ID を検索し、次のサイト ID を使用して URL を作成してそのページをリクエストします。次に、必要なデータをスクレイピングします。

このほとんどすべてを行うコードがあるようです。問題は、ページ 1 を解析して次のステップの ID を取得することですか? もしそうなら、再現可能な例を定式化する必要があります。そうすれば、構文の問題に対する非常に迅速な答えが得られると思います。

サイトが何をしているかを確認できない場合は、Firefox のTamper Dataプラグインを使用することをお勧めします。マウスをクリックするたびに、どのようなリクエストが行われているかを確認できます。この種のことには本当に便利だと思います。

于 2011-10-25T15:04:55.010 に答える