Como posso usar os pacotes R (rcurl/xml?!) Para raspar esta página da web?

StackOverflow https://stackoverflow.com/questions/2443127

  •  19-09-2019
  •  | 
  •  

Pergunta

Eu tenho um (um tanto complexo) desafio de raspagem na web que desejo realizar e adoraria alguma direção (a qualquer nível que você quiser compartilhar) aqui:

Eu gostaria de passar por todas as "páginas de espécies" presentes neste link:

http://gtrnadb.ucsc.edu/

Então, para cada um deles, eu irei:

  1. O link da página da espécie (por exemplo: http://gtrnadb.ucsc.edu/aero_pern/)
  2. E depois para o link de página "Estruturas secundárias" (por exemplo: http://gtrnadb.ucsc.edu/aero_pern/aero_pern-structs.html)

Dentro desse link, desejo descartar os dados na página para ter uma longa lista contendo esses dados (por exemplo):

chr.trna3 (1-77)    Length: 77 bp
Type: Ala   Anticodon: CGC at 35-37 (35-37) Score: 93.45
Seq: GGGCCGGTAGCTCAGCCtGGAAGAGCGCCGCCCTCGCACGGCGGAGGcCCCGGGTTCAAATCCCGGCCGGTCCACCA
Str: >>>>>>>..>>>>.........<<<<.>>>>>.......<<<<<.....>>>>>.......<<<<<<<<<<<<....

Onde cada linha terá sua própria lista (dentro da lista para cada "tRNA" dentro da lista para cada animal)

Lembro -me de encontrar os pacotes RCURL e XML (em R) que podem permitir essa tarefa. Mas não sei como usá -los. Então, o que eu adoraria ter é: 1. Algumas sugestões sobre como criar esse código. 2. e recomendação de como aprender o conhecimento necessário para executar essa tarefa.

Obrigado por qualquer ajuda,

Tal

Foi útil?

Solução

Tal,

Você poderia usar r e o XML Pacote para fazer isso, mas (caramba) isso é um HTML mal formado que você está tentando analisar. De fato, na maioria dos casos, você gostaria de usar o readHTMLTable() função, que é coberto neste tópico anterior.

Dado este feio html, no entanto, teremos que usar o RCurl Pacote para puxar o HTML bruto e criar algumas funções personalizadas para analisá -lo. Este problema tem dois componentes:

  1. Obtenha todos os URLs do genoma da página da web base (http://gtrnadb.ucsc.edu/) usando o getURLContent() função no RCurlpacote e alguma magia regex :-)
  2. Em seguida, pegue a lista de URLs e raspe os dados que você está procurando e depois coloque -os em um data.frame.

Então, aqui vai ...

library(RCurl)

### 1) First task is to get all of the web links we will need ##
base_url<-"http://gtrnadb.ucsc.edu/"
base_html<-getURLContent(base_url)[[1]]
links<-strsplit(base_html,"a href=")[[1]]

get_data_url<-function(s) {
    u_split1<-strsplit(s,"/")[[1]][1]
    u_split2<-strsplit(u_split1,'\\"')[[1]][2]
    ifelse(grep("[[:upper:]]",u_split2)==1 & length(strsplit(u_split2,"#")[[1]])<2,return(u_split2),return(NA))
}

# Extract only those element that are relevant
genomes<-unlist(lapply(links,get_data_url))
genomes<-genomes[which(is.na(genomes)==FALSE)]

### 2) Now, scrape the genome data from all of those URLS ###

# This requires two complementary functions that are designed specifically
# for the UCSC website. The first parses the data from a -structs.html page
# and the second collects that data in to a multi-dimensional list
parse_genomes<-function(g) {
    g_split1<-strsplit(g,"\n")[[1]]
    g_split1<-g_split1[2:5]
    # Pull all of the data and stick it in a list
    g_split2<-strsplit(g_split1[1],"\t")[[1]]
    ID<-g_split2[1]                             # Sequence ID
    LEN<-strsplit(g_split2[2],": ")[[1]][2]     # Length
    g_split3<-strsplit(g_split1[2],"\t")[[1]]
    TYPE<-strsplit(g_split3[1],": ")[[1]][2]    # Type
    AC<-strsplit(g_split3[2],": ")[[1]][2]      # Anticodon
    SEQ<-strsplit(g_split1[3],": ")[[1]][2]     # ID
    STR<-strsplit(g_split1[4],": ")[[1]][2]     # String
    return(c(ID,LEN,TYPE,AC,SEQ,STR))
}

# This will be a high dimensional list with all of the data, you can then manipulate as you like
get_structs<-function(u) {
    struct_url<-paste(base_url,u,"/",u,"-structs.html",sep="")
    raw_data<-getURLContent(struct_url)
    s_split1<-strsplit(raw_data,"<PRE>")[[1]]
    all_data<-s_split1[seq(3,length(s_split1))]
    data_list<-lapply(all_data,parse_genomes)
    for (d in 1:length(data_list)) {data_list[[d]]<-append(data_list[[d]],u)}
    return(data_list)
}

# Collect data, manipulate, and create data frame (with slight cleaning)
genomes_list<-lapply(genomes[1:2],get_structs) # Limit to the first two genomes (Bdist & Spurp), a full scrape will take a LONG time
genomes_rows<-unlist(genomes_list,recursive=FALSE) # The recursive=FALSE saves a lot of work, now we can just do a straigh forward manipulation
genome_data<-t(sapply(genomes_rows,rbind))
colnames(genome_data)<-c("ID","LEN","TYPE","AC","SEQ","STR","NAME")
genome_data<-as.data.frame(genome_data)
genome_data<-subset(genome_data,ID!="</PRE>")   # Some malformed web pages produce bad rows, but we can remove them

head(genome_data)

O quadro de dados resultante contém sete colunas relacionadas a cada entrada do genoma: ID, comprimento, tipo, sequência, string e nome. A coluna de nome contém o genoma da base, que foi o meu melhor palpite para a organização de dados. Aqui é o que parece:

head(genome_data)
                                   ID   LEN TYPE                           AC                                                                       SEQ
1     Scaffold17302.trna1 (1426-1498) 73 bp  Ala     AGC at 34-36 (1459-1461) AGGGAGCTAGCTCAGATGGTAGAGCGCTCGCTTAGCATGCGAGAGGtACCGGGATCGATGCCCGGGTTTTCCA
2   Scaffold20851.trna5 (43038-43110) 73 bp  Ala   AGC at 34-36 (43071-43073) AGGGAGCTAGCTCAGATGGTAGAGCGCTCGCTTAGCATGCGAGAGGtACCGGGATCGATGCCCGGGTTCTCCA
3   Scaffold20851.trna8 (45975-46047) 73 bp  Ala   AGC at 34-36 (46008-46010) TGGGAGCTAGCTCAGATGGTAGAGCGCTCGCTTAGCATGCGAGAGGtACCGGGATCGATGCCCGGGTTCTCCA
4     Scaffold17302.trna2 (2514-2586) 73 bp  Ala     AGC at 34-36 (2547-2549) GGGGAGCTAGCTCAGATGGTAGAGCGCTCGCTTAGCATGCGAGAGGtACAGGGATCGATGCCCGGGTTCTCCA
5 Scaffold51754.trna5 (253637-253565) 73 bp  Ala AGC at 34-36 (253604-253602) CGGGGGCTAGCTCAGATGGTAGAGCGCTCGCTTAGCATGCGAGAGGtACCGGGATCGATGCCCGGGTCCTCCA
6     Scaffold17302.trna4 (6027-6099) 73 bp  Ala     AGC at 34-36 (6060-6062) GGGGAGCTAGCTCAGATGGTAGAGCGCTCGCTTAGCATGCGAGAGGtACCGGGATCGATGCCCGAGTTCTCCA
                                                                        STR  NAME
1 .>>>>>>..>>>>........<<<<.>>>>>.......<<<<<.....>>>>>.......<<<<<<<<<<<.. Spurp
2 .>>>>>>..>>>>........<<<<.>>>>>.......<<<<<.....>>>>>.......<<<<<<<<<<<.. Spurp
3 .>>>>>>..>>>>........<<<<.>>>>>.......<<<<<.....>>>>>.......<<<<<<<<<<<.. Spurp
4 >>>>>>>..>>>>........<<<<.>>>>>.......<<<<<.....>.>>>.......<<<.<<<<<<<<. Spurp
5 .>>>>>>..>>>>........<<<<.>>>>>.......<<<<<.....>>>>>.......<<<<<<<<<<<.. Spurp
6 >>>>>>>..>>>>........<<<<.>>>>>.......<<<<<......>>>>.......<<<<.<<<<<<<. Spurp

Espero que isso ajude e obrigado pela divertida pequena tarde de domingo R Desafio!

Outras dicas

Acabei de tentar usar mozenda (http://www.mozenda.com). Depois de cerca de 10 minutos e eu tinha um agente que poderia raspar os dados conforme você descreve. Você poderá obter todos esses dados usando o teste gratuito. A codificação é divertida, se você tiver tempo, mas parece que você já pode ter uma solução codificada para você. Bom trabalho desenhou.

Problema interessante e concordo que R é legal, mas de alguma forma acho R um pouco pesado a esse respeito. Parece que prefiro obter os dados em formulário intermediário de texto simples para poder verificar se os dados estão corretos em cada etapa ... se os dados estiverem prontos em sua forma final ou para fazer upload de seus dados em algum útil.

A mais simples, na minha opinião http://gtrnadb.ucsc.edu/ site (usando wget) e pegue os arquivos nomeados /-Structs.html, sed ou awk os dados que você gostaria e formate -os para ler em R.

Tenho certeza de que haveria muitas outras maneiras também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top