R語言批量爬取NCBI基因注釋數(shù)據(jù)

網(wǎng)絡(luò)爬蟲(web crawler),也叫網(wǎng)絡(luò)蜘蛛(spider),是一種用來自動瀏覽萬維網(wǎng)的網(wǎng)絡(luò)機器人。其目的一般為編纂網(wǎng)絡(luò)索引毡惜。各大搜索引擎都可以被看做爬蟲,根據(jù)爬取的內(nèi)容更新自身的網(wǎng)站內(nèi)容或其對其他網(wǎng)站的索引斯撮。一般如果想批量從網(wǎng)頁獲取數(shù)據(jù)经伙,有download或者API(之前推送過使用API提取TCGA數(shù)據(jù))頁面最好,沒有的話可以考慮使用爬蟲爬取。

??本期使用R語言批量爬取NCBI基因注釋信息帕膜,主要用到了XML包的getNodeSet函數(shù)枣氧。需要使用者有一定html+css基礎(chǔ),以及理解并能使用XML路徑語言(xpath)垮刹。


使用R爬取NCBI人類基因信息流程如下:

??首先準備目標基因文件达吞,我們以下面這幾個基因(gene symbol的形式)為例進行爬取其在NCBI(gene)中的信息,基因列表文件可以從這里下載(https://pan.baidu.com/s/1c2jbvby)。

gene list文件

載入要用到的包并讀入基因列表:

library(RCurl)
library(stringr)
library(XML)
library(clusterProfiler)

rm(list=ls())
# 讀入基因列表:
genes <- read.table("test_genes.txt",header = T,stringsAsFactors = F)

從下圖可以發(fā)現(xiàn)NCBI對于基因頁面的索引方式都是 https://www.ncbi.nlm.nih.gov/gene/Entrze ID 的方式荒典。

NCBI中基因頁面

所以我們需要將gene symbos轉(zhuǎn)為entrze ID酪劫,這里使用clusterProfiler包的bitr函數(shù)進行轉(zhuǎn)換:

# 將gene symbol轉(zhuǎn)為entrze ID:
genes <- bitr(genes$SYMBOL, fromType="SYMBOL", toType="ENTREZID", OrgDb="org.Hs.eg.db")

然后獲得每個基因在NCBI中的索引鏈接:

# 網(wǎng)址數(shù)據(jù)框:
genes$NCBI_url <- paste("https://www.ncbi.nlm.nih.gov/gene/",genes$ENTREZID,sep="")
head(genes)
每個基因symbol、entrze ID和NCBI url

??使用XML包的getNodeSet()函數(shù)需要兩個參數(shù)寺董,一個是根據(jù)URL獲得的網(wǎng)頁XML document對象覆糟,另一個是要定位的節(jié)點(xpath格式)。不了解xpath的可以點擊頁面左下角閱讀全文查看其基本語法。不過我們可以在不了解語法的情況下獲得要定位節(jié)點的xpath。只需要在chrome瀏覽器里打開NCBI的gene信息頁面矗愧,我們以基因DBNDD1為例,然后再按一下F12就可以調(diào)出chrome瀏覽器自帶的開發(fā)者工具:

在chrome瀏覽器中選擇節(jié)點的xpath

??比如說我們要爬取基因的Official Full name信息麦箍,我們只需要在調(diào)出來的開發(fā)者工具欄右上角點幾下那個小箭頭,然后在點下Official Full name然后在右上方的源代碼顯示Official Full name的位置點擊右鍵魄藕,選擇CopyCopy XPath背率。

獲得要爬取節(jié)點的xpath信息

我們可以得到這樣的xpath字段:

# Official Full name的xpath://*[@id="summaryDl"]/dd[2]/text()

??使用同樣的方法,我們可以獲得基因的HGNC ID嫩与,Gene typeSummary等任何部分的xpath。

# HGNC ID的xpath://*[@id="summaryDl"]/dd[3]/a
# Gene type的xpath://*[@id="summaryDl"]/dd[5]/text()
# Summary的xpath://*[@id="summaryDl"]/dd[10]/text()

到這里準備工作就結(jié)束了划滋,接下來構(gòu)建并調(diào)用函數(shù)來爬取每個基因這4個字段的信息:

# 根據(jù)xpath獲取節(jié)點內(nèi)容:
getNodesTxt <- function(html_txt1,xpath_p){
  els1 = getNodeSet(html_txt1, xpath_p)
  # 獲得Node的內(nèi)容同窘,并且去除空字符:
  els1_txt <- sapply(els1,xmlValue)[!(sapply(els1,xmlValue)=="")]
  # 去除\n:
  str_replace_all(els1_txt,"(\\n )+","")
}

# 處理節(jié)點格式,為character且長度為0的賦值為NA:
dealNodeTxt <- function(NodeTxt){
  ifelse(is.character(NodeTxt)==T && length(NodeTxt)!=0 , NodeTxt , NA)
}

使用一個for循環(huán)獲得每個基因的信息并存儲到數(shù)據(jù)框:


for(i in 1:nrow(genes)){
  # 獲得網(wǎng)址:
  doc <- getURL(genes[i,"NCBI_url"])
  cat("成功獲得網(wǎng)頁想邦!\t")
  # 獲得網(wǎng)頁內(nèi)容
  html_txt1 = htmlParse(doc, asText = TRUE)
  
  # 獲得Full Name:
  genes[i,"FullName"] <- dealNodeTxt(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[2]/text()'))
  cat("寫入基因\t")
  # 獲得HGNC ID:
  genes[i,"HGNC_ID"] <- str_replace_all(dealNodeTxt(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[3]/a')),"HGNC|:","")
  cat("寫入HGNC_ID\t")
  # 獲得Gene type:
  genes[i,"GeneType"] <- dealNodeTxt(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[5]/text()'))
  cat("寫入GeneType\t")
  # 獲得summary:
  genes[i,"Summary"] <- ifelse(length(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[10]/text()'))!=0,getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[10]/text()'),NA)
  cat("寫入Summary\n")
  
  print(paste("完成第",i,"個了丧没!"))

}

爬取結(jié)果如下:

爬取結(jié)果

??上面的節(jié)點的xpath中的標簽是按照順序在chrome生成的鹰椒,這樣就存在一個問題锡移,如果某個基因沒有某個屬性,則這個屬性后續(xù)的所有節(jié)點的xpath都將發(fā)生改變漆际。如下圖所示的兩個基因淆珊,一個有別名,一個沒有別名奸汇,則這兩個基因的Summaryxpath就是不同的施符,而我們是按照有別名基因的xpath爬取的,所以爬取到?jīng)]有別名的基因時的summary就會出錯茫蛹。

不同基因同一屬性的xpath可能不同

??為了能夠精確爬取到想要的數(shù)據(jù)操刀,這里就需要使用到xpath函數(shù)獲得準確的節(jié)點定位。下面直接附上代碼:

# xpath精確定位:
for(i in 1:nrow(genes)){
  # 獲得網(wǎng)址:
  doc <- getURL(genes[i,"NCBI_url"])
  cat("成功獲得網(wǎng)頁婴洼!\t")
  # 獲得網(wǎng)頁內(nèi)容
  html_txt1 = htmlParse(doc, asText = TRUE)
  
  # 獲得Full Name:
  genes[i,"FullName"] <- str_split(dealNodeTxt(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[preceding-sibling::dt[contains(text(),"Symbol") and position()=1 ] ]')),"provided")[[1]][1]
  cat("寫入基因\t")
  # 獲得HGNC ID:
  genes[i,"HGNC_ID"] <- str_replace_all(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[preceding-sibling::dt[text()="Primary source" and position()=1 ] ]')," |HGNC|:","")
  cat("寫入HGNC_ID\t")
  # 獲得Gene type:
  genes[i,"GeneType"] <- dealNodeTxt(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[preceding-sibling::dt[text()="Gene type" and position()=1 ] ]'))
  cat("寫入GeneType\t")
  # 獲得summary:
  genes[i,"Summary"] <- dealNodeTxt(getNodesTxt(html_txt1,'//*[@id="summaryDl"]/dd[preceding-sibling::dt[text()="Summary" and position()=1 ] ]'))
  cat("寫入Summary\n")
  
  print(paste("完成第",i,"個了骨坑!"))
}

精確爬取結(jié)果如下,驗證都是正確的柬采。


精確爬取結(jié)果

??爬取結(jié)果的準確性依賴于節(jié)點定位是否準確欢唾,定位既可以通過xpath,也可以通過CSS粉捻,rvest包提供里這兩種定位方式礁遣。并且rvest包使用magrittr包的%*%操作符,增強了代碼的可讀性肩刃。


更多原創(chuàng)精彩視頻敬請關(guān)注生信雜談:

閱讀原文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末祟霍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盈包,更是在濱河造成了極大的恐慌沸呐,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呢燥,死亡現(xiàn)場離奇詭異崭添,居然都是意外死亡,警方通過查閱死者的電腦和手機叛氨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門呼渣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人寞埠,你說我怎么就攤上這事屁置。” “怎么了畸裳?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵缰犁,是天一觀的道長。 經(jīng)常有香客問我,道長帅容,這世上最難降的妖魔是什么颇象? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮并徘,結(jié)果婚禮上遣钳,老公的妹妹穿的比我還像新娘。我一直安慰自己麦乞,他們只是感情好蕴茴,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著姐直,像睡著了一般倦淀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上声畏,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天撞叽,我揣著相機與錄音,去河邊找鬼插龄。 笑死愿棋,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的均牢。 我是一名探鬼主播糠雨,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼徘跪!你這毒婦竟也來了甘邀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤垮庐,失蹤者是張志新(化名)和其女友劉穎鹃答,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體突硝,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年置济,在試婚紗的時候發(fā)現(xiàn)自己被綠了解恰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡浙于,死狀恐怖护盈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情羞酗,我是刑警寧澤腐宋,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響胸竞,放射性物質(zhì)發(fā)生泄漏欺嗤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一卫枝、第九天 我趴在偏房一處隱蔽的房頂上張望煎饼。 院中可真熱鬧,春花似錦校赤、人聲如沸吆玖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沾乘。三九已至,卻和暖如春浑测,著一層夾襖步出監(jiān)牢的瞬間翅阵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工尽爆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怎顾,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓漱贱,卻偏偏與公主長得像槐雾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子幅狮,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容