簡體   English   中英

如何使用R(Rcurl / XML包?!)來抓取這個網頁?

[英]How can I use R (Rcurl/XML packages ?!) to scrape this webpage?

我有一個(有點復雜的)網絡抓取挑戰,我希望完成,並希望在某個方向(你想分享的任何級別)這里:

我想通過此鏈接中的所有“物種頁面”:

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. 使用RCurl包中的getURLContent()函數和一些正則表達式魔法從基本網頁( http://gtrnadb.ucsc.edu/ )獲取所有基因組URL :-)
  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分鍾后,我有一個代理人可以像你描述的那樣抓取數據。 您可以使用他們的免費試用版獲得所有這些數據。 編碼很有趣,如果你有時間,但看起來你可能已經為你編寫了一個解決方案。 干得好Drew。

有趣的問題,並同意R很酷,但不知何故,我發現R在這方面有點麻煩。 我似乎更喜歡首先以中間純文本格式獲取數據,以便能夠在每個步驟中驗證數據是否正確...如果數據已准備好以其最終形式或用於上傳您的數據某處RCurl非常有用。

我認為最簡單的是(在linux / unix / mac /或cygwin上)只鏡像整個http://gtrnadb.ucsc.edu/網站(使用wget)並獲取名為/ -structs.html,sed的文件或者awk您想要的數據並格式化以便讀入R.

我相信還有很多其他方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM