[R-br] Ajuda com função para web-scraping no R

Augusto Ribas ribas.aca em gmail.com
Domingo Junho 24 18:01:27 BRT 2012


Ola pessoal.
Estou com problemas com uma função aqui de web-scraping.
Meu problema é o seguinte. Especies estão sempre mudando de nome.
Novos generos surgem, outros somem, e assim vai.
Mas tem um indexador de nome de especies que é uma mão na roda. O
http://www.catalogueoflife.org/
Blz, é so colocar o nome nele que sai se o nome novo se mudou, o mesmo
se nao mudou, enfim qual o nome aceito hoje em dia.
Ai eu tentei fazer uma função pra fazer isso.
Basicamente eu fiz ele fazer um search, criando o link, dai eu pego o
primeiro resultado, entro na pagina do primeiro resultado, ai dentro
da pagina do primeiro resultado eu pego o nome aceito e o autor.
Eu tava tentando copiar essa função de algum tempo atras aqui da lista
pra usar na minha necessidade
http://r-br.2285057.n4.nabble.com/R-br-OT-Distancias-entre-municipios-td3964600.html
So que a entrada era pra ser o nome da especie, dai a saida era pra
ser uma lista com o nome da especie e o autor.
Ai o meu problem é o seguinte.

Ps. a função ta no final da msg, pra nao bagunçar aqui.

Qd eu uso ele sozinho sai blz
>-sp.check(dados$Hospedeiro[1])
$sp.aceito
[1] "Aetobatus narinari"

$autor
[1] "Euphrasen, 1790"

Mas as vezes sai assim
> sp.check(dados$Hospedeiro[1])
$sp.aceito
] "Aetobatus narinari"

$autor
[1] "Euphrasen, 1790"

Não sei pq some o "[1" que deveria ter ali

Mas ai qd eu uso pra pra saber so o nome da especie por exemplo
> sp.check(dados$Hospedeiro[1])$sp.aceito
tus narinari"

> sp.check(dados$Hospedeiro[1])$sp.aceito
 narinari"

Ele não funciona direito, come metade do nome ali, come umas letras sei la
A minha ideia final é o seguinte, eu tenho um dafa.frame tipo assim:

#####################################################################
> dput(exemplo)
structure(list(Hospedeiro = c("Aetobatis narinari", "Arothron hispidus",
"Astyanax aenaeus", "Astyanax fasciatus", "Astyanax fasciatus"
), Parasita = c("Acanthobothrium nicoyaense", "Bianium simonei",
"Wallinia chavariiae", "Anacanthocotyle anacanthocotyle",
"Gyrodactylus costaricensis"
), Grupo.H = c("peixes", "peixes", "peixes", "peixes", "peixes"
), Grupo.P = c("C", "D", "D", "M", "M")), .Names = c("Hospedeiro",
"Parasita", "Grupo.H", "Grupo.P"), row.names = c(NA, 5L), class = "data.frame")
########################################################################

Eu gostaria de criar outra coluna, com o nome da especie aceito
atualmente, usando tipo um loop com essa função que estou tentando
fazer.
E uma coluna com o autor que descreveu a especie tb para a coluna hospedeiros.
Se alguem puder dar uma olhadinha o que estou fazendo errado.
Eu quero chegar a isso:

          Hospedeiro       sp aceita           outras colunas
1 Aetobatis narinari    Fulana detal      ----
2  Arothron hispidus    Ciclana detal     -----
3   Astyanax aenaeus  Beltrana detal    ------
4 Astyanax fasciatus    Mesmo nome    -----
5 Astyanax fasciatus


Segue aqui passo a passo o que eu fiz e tudo na forma de função também.

#######################################
#Passo a passo
########################################

#Entrada do nome da especie
especie<-c("Bufo marinus")

#Separando o nome da especie
gen<-strsplit(especie,"\\ ")[[1]][1]
esp<-strsplit(especie,"\\ ")[[1]][2]
gen
esp

#Criando o link
link<-paste("http://www.catalogueoflife.org/col/search/all/key/",gen,"+",esp,"/match/1",sep="")
link <- iconv(link, 'latin1', 'UTF-8')
Encoding(link) <- 'bytes'
link

#lendo a pagina
pagina <- readLines(url(link))

#Achando onde esta o primeiro resultado da lista, Acredito que essa linha
#é o começo da tabelinha de resultado sempre, não sei o que mais da pra usar
#pra achar o primeiro resultado :(
n.linhas<-which(pagina%in%"        <td class=\"field_header_black\">")

#aqui pra testa depois na função se nao achou nada, menor que 1 ele
nao achou nada no site
length(n.linhas)

#pegando o primeiro resultado
pag.sp<-strsplit(pagina[n.linhas[1]+1],'\\"')[[1]][2]

#gerando o link do primeiro resultado
link2 <- paste( "http://www.catalogueoflife.org",pag.sp,sep="")
link2 <- iconv(link2, 'latin1', 'UTF-8')
Encoding(link2) <- 'bytes'
link2

#baixando a pagina do primeiro resultado
pagina2 <- readLines(url(link2))

#achando a linha onde esta o nome da especie aceito
linha2<-grep('(accepted name)',pagina2)
sp.final<-pagina2[linha2]

#pegando o nome da especie
corte1<-strsplit(sp.final,'<i>')[[1]][2]
sp.aceito<-strsplit(corte1,'</i>')[[1]][1]

#pegando o autor
corte2<-strsplit(sp.final,'\\(')[[1]][2]
autor<-strsplit(corte2,')')[[1]][1]

#Resultados de interesse
sp.aceito
autor

#######################################
#Agora uma função pra faze isso
########################################
#função sp.check

sp.check<-function(especie) {

especie<-as.character(especie)

gen<-strsplit(especie,"\\ ")[[1]][1]
esp<-strsplit(especie,"\\ ")[[1]][2]

link<-paste("http://www.catalogueoflife.org/col/search/all/key/",gen,"+",esp,"/match/1",sep="")
link <- iconv(link, 'latin1', 'UTF-8')
Encoding(link) <- 'bytes'

pagina <- readLines(url(link))

n.linhas<-which(pagina%in%"        <td class=\"field_header_black\">")

if(length(n.linhas)>0) {

pag.sp<-strsplit(pagina[n.linhas[1]+1],'\\"')[[1]][2]

link2 <- paste( "http://www.catalogueoflife.org",pag.sp,sep="")
link2 <- iconv(link2, 'latin1', 'UTF-8')
Encoding(link2) <- 'bytes'
link2

pagina2 <- readLines(url(link2))

linha2<-grep('(accepted name)',pagina2)
sp.final<-pagina2[linha2]

corte1<-strsplit(sp.final,'<i>')[[1]][2]
sp.aceito<-strsplit(corte1,'</i>')[[1]][1]

corte2<-strsplit(sp.final,'\\(')[[1]][2]
autor<-strsplit(corte2,')')[[1]][1]
}else {
sp.aceito<-c("Não encontrado")
autor<-c("Não encontrado")
}
return(list(sp.aceito=sp.aceito,autor=autor))
}

PS1: O as.character la no começo é que normalmente eu leio os
dataframe com read.csv2 ai converte pra fator a coluna, ai quis fazer
ele transforma ali pra nao da pau.
PS2: Eu tb  coloque um if pra dar um jeito qd ele não achar resultado,
a principio tava funcionando.
PS3: Tem como suprimir esse erro:
 In readLines(url(link2)) :
 linha final incompleta encontrada em
'http://www.catalogueoflife.org/col/details/species/id/7159709/synonym/7161980'
PS4: Tem como o loop não parar qd a internet não funciona. tipo qd da
aqueles erros 505 e a pagina nao abre.

Agradeço a atenção e peço desculpas pela mensagem muito longa.




-- 
Grato
Augusto C. A. Ribas

Site Pessoal: http://augustoribas.heliohost.org
Lattes: http://lattes.cnpq.br/7355685961127056


Mais detalhes sobre a lista de discussão R-br