Как я могу использовать R (пакеты Rcurl / XML ?!) для очистки этой веб-страницы?

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

  •  19-09-2019
  •  | 
  •  

Вопрос

У меня есть (несколько сложная) задача по очистке веб-страниц, которую я хочу выполнить, и мне хотелось бы получить какое-то направление (на любом уровне, которым вы захотите поделиться).:

Я хотел бы просмотреть все "страницы видов", представленные по этой ссылке:

http://gtrnadb.ucsc.edu/

Итак, по каждому из них я перейду к:

  1. Ссылка на страницу вида (например: http://gtrnadb.ucsc.edu/Aero_pern/)
  2. А затем перейдите по ссылке на страницу "Вторичные структуры" (например: http://gtrnadb.ucsc.edu/Aero_pern/Aero_pern-structs.html)

Внутри этой ссылки я хочу удалить данные на странице, чтобы у меня был длинный список, содержащий эти данные (например):

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

Где каждая строка будет иметь свой собственный список (внутри списка для каждой "трнк" внутри списка для каждого животного)

Я помню, что натыкался на пакеты Rcurl и XML (на R), которые могут разрешить такую задачу.Но я не знаю, как ими пользоваться.Так что чего бы мне хотелось, так это:1.Несколько предложений о том, как создать такой код.2.И рекомендации о том, как усвоить знания, необходимые для выполнения такой задачи.

Спасибо за любую помощь,

Tal

Это было полезно?

Решение

Tal,

Вы могли бы использовать R и XML пакет для этого, но (черт возьми) это какой-то плохо сформированный HTML, который вы пытаетесь разобрать.На самом деле, в большинстве случаев вы хотели бы использовать readHTMLTable() функция, который описан в этой предыдущей теме.

Однако, учитывая этот уродливый HTML-код, нам придется использовать RCurl пакет для извлечения необработанного HTML-кода и создания некоторых пользовательских функций для его синтаксического анализа.Эта проблема состоит из двух компонентов:

  1. Получите все URL-адреса генома с базовой веб-страницы (http://gtrnadb.ucsc.edu/) используя getURLContent() функционировать в RCurlпакет и немного магии регулярных выражений :-)
  2. Затем возьмите этот список URL-адресов и очистите данные, которые вы ищете, а затем вставьте их в data.frame.

Итак, поехали...

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)

Результирующий фрейм данных содержит семь столбцов, относящихся к каждой записи генома:Идентификатор, длина, тип, последовательность, строка и имя.Столбец name содержит базовый геном, который был моим лучшим предположением для организации данных.Вот как это выглядит:

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

Я надеюсь, что это поможет, и спасибо за веселый небольшой воскресный дневной R-челлендж!

Другие советы

Просто попробовал это с помощью Mozenda (http://www.mozenda.com).Примерно через 10 минут у меня появился агент, который смог собрать данные, как вы описали.Возможно, вы сможете получить все эти данные, просто воспользовавшись их бесплатной пробной версией.Кодирование - это весело, если у вас есть время, но, похоже, у вас уже есть решение, разработанное специально для вас.Отличная работа, Дрю.

Интересная проблема, и я согласен, что R - это круто, но почему-то я нахожу R немного громоздким в этом отношении.Кажется, я предпочитаю сначала получать данные в промежуточной текстовой форме, чтобы иметь возможность проверять правильность данных на каждом шаге...Если данные готовы в окончательном виде или для загрузки ваших данных куда-либо, RCurl очень полезен.

Проще всего, на мой взгляд, было бы (в linux / unix / mac / или в cygwin) просто отразить весь http://gtrnadb.ucsc.edu/ сайт (используя wget) и берем файлы с именами /-structs.html, sed или awk нужные данные и отформатируйте их для чтения в R.

Я уверен, что было бы много и других способов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top