2010-03-14 24 views
10

Tengo un desafío de raspado web (algo complejo) que deseo lograr y me gustaría alguna dirección (al nivel que quieras compartir) aquí va:¿Cómo puedo usar R (paquetes Rcurl/XML?!) Para raspar esta página web.

Me gustaría revisar todas las "páginas de especies" "presente en este enlace:

http://gtrnadb.ucsc.edu/

Así que para cada uno de ellos voy a ir a:

  1. El vínculo especies (por ejemplo: http://gtrnadb.ucsc.edu/Aero_pern/)
  2. y luego al vínculo "estructuras secundarias" (por ejemplo: http://gtrnadb.ucsc.edu/Aero_pern/Aero_pern-structs.html)

Dentro de ese enlace deseo para el desguace de los datos en la página de modo que voy a tener una larga lista que contiene estos datos (por ejemplo,):

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

donde cada línea tendrá su propia lista (dentro de la lista para cada "ARNt" dentro de la lista para cada animal)

recuerdo llegar a través de los paquetes Rcurl y XML (en I) eso puede permitir tal tarea. Pero no sé cómo usarlos. Entonces, lo que me gustaría tener es: 1. Alguna sugerencia sobre cómo construir dicho código. 2. Y la recomendación de cómo aprender el conocimiento necesario para realizar dicha tarea.

Gracias por cualquier ayuda,

Tal

+1

@Tal, una pregunta, si se me permite: ¿es esto legal? Y si es así, ¿no sería más fácil simplemente pedirle a UCSC un acceso regular a su base de datos? –

+2

Hola Tal, intenta dejarlos una línea de todos modos. Puede encontrarlos bastante complacientes. Es posible que ni siquiera se den cuenta de que la gente quiere usar los datos de la forma en que lo desea. Tal vez estarán interesados ​​en proporcionarlo como quieras? – user246211

Respuesta

17

Tal,

Usted podría utilizar R y el paquete XML para hacer esto, pero (maldito) que es algo de HTML mal formado que está tratando de analizar. De hecho, en la mayoría de los casos, querrá utilizar la función readHTMLTable(), which is covered in this previous thread.

Dado este feo HTML, sin embargo, tendremos que usar el paquete RCurl para extraer el HTML sin procesar y crear algunas funciones personalizadas para analizarlo.Este problema tiene dos componentes:

  1. Obtener todas las URL de la página web del genoma de base (http://gtrnadb.ucsc.edu/) utilizando la función getURLContent() en el paquete RCurl y un poco de magia de expresiones regulares :-)
  2. luego tomar esa lista de direcciones URL y raspe los datos que está buscando y luego péguelos en data.frame.

Por lo tanto, aquí va ...

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) 

La trama de datos resultante contiene siete columnas relacionadas con cada entrada genoma: ID, longitud, tipo, secuencia, secuencia, y el nombre. La columna de nombre contiene el genoma base, que fue mi mejor estimación para la organización de datos. Aquí es lo 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 esto ayude, y gracias por el pequeño desafío de domingo por la tarde R!

+0

Ahh, gracias Tal. No había hecho una búsqueda lo suficientemente exhaustiva de las posibles entradas. ¡Me alegra que pudieras hacerlo funcionar! – DrewConway

+0

La ayuda para readHTMLtable proporciona un método para tablas PRE. Algo como: u = "http://gtrnadb.ucsc.edu/Ppaci1/Ppaci1-structs.html"; h = htmlParse (u); p = getNodeSet (h, "// pre"); con = textConnection (xmlValue (p [[2]])); readLines (con, n = 4) [- 1] Podría ayudar. –

0

problema interesante y coinciden en que R es fresco, pero de alguna manera me parece R para ser un poco engorroso en este sentido. Parece que prefiero obtener los datos en formato de texto plano intermedio primero para poder verificar que los datos son correctos en cada paso ... Si los datos están listos en su forma final o para cargar sus datos en alguna parte RCurl es muy útil.

más simple en mi opinión sería (en Linux/Unix/Mac/o en cygwin) acaba de reflejar toda la http://gtrnadb.ucsc.edu/ sitio (usando wget) y tomar los archivos con el nombre / -structs.html, sed o awk el datos que le gustaría y formatee para leer en R.

Estoy seguro de que también habría muchas otras maneras.

1

Acabo de probarlo usando Mozenda (http://www.mozenda.com). Después de aproximadamente 10 minutos y tuve un agente que podría raspar los datos como usted describe. Es posible que pueda obtener todos estos datos solo con su versión de prueba gratuita. La codificación es divertida, si tiene tiempo, pero parece que ya tiene una solución codificada para usted. Buen trabajo, Drew.

Cuestiones relacionadas