我有一个(有点复杂的)网络抓取挑战,我希望完成它,并且希望得到一些方向(无论您想分享什么级别),这里是:

我想浏览此链接中存在的所有“物种页面”:

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: >>>>>>>..>>>>.........<<<<.>>>>>.......<<<<<.....>>>>>.......<<<<<<<<<<<<....

每行都有自己的列表(在每个动物列表中的每个“trna”的列表中)

我记得遇到过 Rcurl 和 XML(R 中的)包可以完成这样的任务。但我不知道如何使用它们。所以我想要的是:1.关于如何构建这样的代码的一些建议。2.以及如何学习执行此类任务所需知识的建议。

谢谢你的帮助,

塔尔

有帮助吗?

解决方案

塔尔,

你可以使用 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)

生成的数据框包含与每个基因组条目相关的七列:ID、长度、类型、序列、字符串和名称。名称列包含基本基因组,这是我对数据组织的最佳猜测。这是它的样子:

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