[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