,
NCBI(National Center for Biotechnology Information)是美國國立生物技術(shù)信息中心,它提供了龐大的生物醫(yī)學信息資源和強大可靠的檢索工具,被生物醫(yī)學研究人員廣泛使用。
NCBI網(wǎng)站(http://www.ncbi.nlm.nih.gov/)將所有數(shù)據(jù)庫的檢索和使用集成在一個界面上,并為開發(fā)人員提供了幾個開放的API編程接口,便于在他們的應用程序中獲取和操作NCBI的數(shù)據(jù)。E-utilities(Entrez Programming Utilities)是NCBI Entrez檢索系統(tǒng)的開放API編程接口,可以訪問所有的Entrez數(shù)據(jù)庫,包括PubMed、PMC、Gene、 Nuccore and Protein等。
利用NCBI數(shù)據(jù)進行文本挖掘和信息分析是目前醫(yī)學信息研究領(lǐng)域的一個熱點,而獲取文本數(shù)據(jù)是這些研究的基礎(chǔ)性工作。有介紹NCBI開放編程接口的文獻[1-2],也有介紹如何開發(fā)基于NCBI開放編程接口各種具體應用的文獻[3-10]。但是,有的文獻沒有詳細的接口調(diào)用的實例,而有接口調(diào)用實例的文獻由于“從2015年7月1日后不再提供E-utilities SOAP Web Service 服務[11]”已經(jīng)不再適用了?,F(xiàn)有的文獻管理軟件如Endnote、NoteExpress等雖然可以提供題錄下載,但是卻并不包括對于后續(xù)文本挖掘和信息分析至關(guān)重要引用數(shù)據(jù)、PMID、Mesh等字段。
本文詳細描述了利用標準的URL接口實現(xiàn)檢索和批量自動下載PubMed中的文獻題錄信息的具體過程。該方法可方便獲取NCBI論文數(shù)據(jù)并存入SQL數(shù)據(jù)庫,為后續(xù)深度開發(fā)文本挖掘和信息分析等功能構(gòu)建了數(shù)據(jù)基礎(chǔ)。
根據(jù)用戶輸入的檢索式,自動從PubMed數(shù)據(jù)庫中檢索出所有相關(guān)的文獻信息,將其下載后,再從中提取出需要的題錄信息,最后存入本地SQL數(shù)據(jù)庫。用于存放題錄信息的數(shù)據(jù)庫主要字段見表1。
表1 PubMed 主要字段類型
E-utilities由9個服務器程序組成,借助E-utilities,可以設(shè)置一套標準參數(shù)進行搜索、鏈接和下載數(shù)據(jù)(表2)[12-14]。本實例在微軟的Microsoft Visual Studio 2010平臺上,采用C#語言進行開發(fā)。操作系統(tǒng)選用Windows Server 2008 Enterprise Edition Service Pack 2 (64bit ),Web服務器選用IIS 7.0,數(shù)據(jù)庫選用Microsoft SQL Server 2008 R2。E-utilities程序開發(fā)接口主要選用ESearch,EFetch,發(fā)送請求和接收數(shù)據(jù)選用System.Net.WebClient組件,解析XML數(shù)據(jù)選用System.Xml組件。
表2 E-utilities API接口及其功能
下載題錄信息實現(xiàn)流程見圖1。
要把用戶輸入的檢索詞規(guī)范化,以便使它符合E-utilities程序開發(fā)接口的要求。例如,要把用戶輸入的簡單檢索式“l(fā)iver cancer AND AFP”,轉(zhuǎn)換成“l(fā)iver+cancer+AND+AFP”格式。
下載數(shù)據(jù)時,先用EFetch的批量下載方式批量下載。如果有失敗的部分,再通過EFetch的單個PMID值下載方式逐條下載。
實現(xiàn)代碼如下:
public static bool FetchDataToDB(string query, int searchLogID)
{
//通過ESearch獲取參數(shù)“WebEnv”,“QueryKey”,“Count”的值
Dictionary
if (parameters == null)
{
return false;
}
int count = int.Parse(parameters[“Count”]);
List
//編譯EFetch的URL列表
urlList = GetBatchPMIDUrls(query, count,searchLogID, parameters);
//下載題錄數(shù)據(jù)并存入本地數(shù)據(jù)庫
if (DownloadDataToDBRepeatedly(urlList, searchLogID) == false)
{
return false;
}
//如果有部分下載失敗,則通過單個失敗的PMID的URL重新下載。
if(DBManager.IsFailurePMID(count,searchLogID))
{
//編譯失敗部分的單個PMID的EFetch的URL列表
urlList = GetFailedPMIDUrls(query,count,searchLogID);
//下載題錄數(shù)據(jù)并存入本地數(shù)據(jù)庫
if (DownloadDataToDBRepeatedly(urlList, searchLogID) == false)
{
return false;
}
}
return true;
}
圖1 下載題錄信息流程
3.2.1 EFetch批量下載方式
第一步,通過ESearch獲取參數(shù)“WebEnv”“QueryKey”“Count”的值。
首先,編譯ESearch的URL。例如,根據(jù)檢索詞“l(fā)iver+cancer+AND+AFP”,形成URL:http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=liver+cancer+AND+AFP&usehistory=y
其次,根據(jù)ESearch的URL,引用System.Net.WebClient組件下載xml數(shù)據(jù)。實現(xiàn)下載功能的具體代碼如下:
using System.Net;
using System.Text;
private static string DownloadDataFromSite(string url)
{
string xmlPage =null;
try
{
WebClient MyWebClient = new WebClient();
MyWebClient.Credentials = CredentialCache.DefaultCredentials;
//從網(wǎng)上下載數(shù)據(jù)
Byte[]pageData = MyWebClient.DownloadData(url);
xmlPage = Encoding.UTF8.GetString(pageData);
}
catch (WebException webEx)
{
LogManager.InsertError(webEx);
}
return xmlPage;
}
最后,引用System.Xml組件解析并提取xml數(shù)據(jù)中的參數(shù)“WebEnv”,“QueryKey”,“Count”的值。
第二步,通過EFetch 的批量下載方式獲取文獻題錄信息。圖2是代碼實現(xiàn)的詳細流程,首先,根據(jù)參數(shù)“WebEnv”,“QueryKey”,“Count”的值,編譯EFetch的URL列表。其中,retmax參數(shù)需要根據(jù)實際的運行情況并經(jīng)過多次測試結(jié)果而設(shè)定。單個EFetch的URL的格式如下:
http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&rettype=abstract&retmode=xml&WebEnv=NCID_1_7740069_130.14.22.215_9001_1454423068_1167148892_0MetA0_S_MegaStore_F_1&query_key=1&retstart=0&retmax=500
其次,根據(jù)EFetch的URL列表,利用System.Net.WebClient組件下載xml數(shù)據(jù)。
再次,利用System.Xml組件解析并提取xml數(shù)據(jù)中題錄信息。
最后,把提取的題錄信息存入本地數(shù)據(jù)庫。
部分實現(xiàn)代碼如下:
Private static bool DownloadDataToDBRepeatedly(List
{
//有時候某些URL下載不成功,需要多次重復下載,這里根據(jù)實際情況定了10次
int circleNum = 0;
do
{
urlList = DownloadDataToDB(urlList, searchLogID);
if (urlList == null)
{
return false;
}
circleNum++;
} while (urlList.Count >= 1 && circleNum <= 10);
if (circleNum > 10 && urlList.Count > 0) //如果 urlList.Count==0,表示成功的下載并存入本地數(shù)據(jù)庫。
{
foreach (string url in urlList)
{
PubmedLogger.Log(url + "/r" + "After download it" + circleNum + "times, it is failure! ", LogCategory.Failure);
}
return false;
}
return true;
}
private static List
{
List
bool isSuccessful;
List
foreach (string url in urlList)
{
//從網(wǎng)站下載數(shù)據(jù)
string xmlPage = DownloadDataFromSite(url);
if (xmlPage == null)
{
FailedUrlList.Add(url);
PubmedLogger.Log(url + "/r" + "There is not the downloaded data. ", LogCategory.Warning); continue;
}
//從xml格式的數(shù)據(jù)里提取所需的題錄信息
articleList = ExtractDataFromXmlPage(xmlPage, searchLogID, url);
if (articleList == null) { FailedUrlList.Add(url); continue; }
//把提取的題錄信息存入本地數(shù)據(jù)庫
isSuccessful = PutDataToDB(articleList);
if (isSuccessful == false){ return null;}
}
return FailedUrlList;
}
圖 2 EFetch下載題錄信息詳細流程
3.2.2 EFetch單個PMID值單條下載方式
如果EFetch批量下載方式下載過程中有失敗的部分,則通過EFetch單個PMID值單條下載方式逐條下載題錄信息并存入本地數(shù)據(jù)庫。
第一步,需要通過ESearch下載xml數(shù)據(jù)并提取所有相關(guān)的PMID值,再跟數(shù)據(jù)庫中成功的部分比較,得到前面批量下載過程中所有失敗的PMID值。需要注意的是需下載所有的PMID值,ESearch的URL中需要設(shè)置“RetMax”參數(shù)值。ESearch的URL格式如下:http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=liver+cancer+AND+AFP&usehistory=y&RetMax=4206
第二步,通過EFetch單個PMID值單條下載方式,逐條下載題錄信息并存入本地數(shù)據(jù)庫。下載和保存的實現(xiàn)代碼與EFetch批量下載方式中的第二步一樣,區(qū)別在于EFetch單個PMID值單條下載方式的URL的格式不一樣。
http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&rettype=abstract&retmode=xml&id=26815502
測試主要是比對手工檢索結(jié)果頁面顯示的總的記錄項數(shù)目和本地數(shù)據(jù)庫中的記錄項數(shù)目是否相等,以及比對手工下載的結(jié)果文件中的部分內(nèi)容和本地數(shù)據(jù)庫中由程序代碼下載的內(nèi)容是否相同。由于PubMed數(shù)據(jù)每天更新,所以測試時要保證手工檢索和下載結(jié)果文件的時間與通過程序代碼下載的時間不能相隔太久。在不同時間段,用不同檢索詞,進行了多次的測試,得到的結(jié)果都是相同的。
本文利用NCBI的E-utilities中的ESearch和EFetch兩個標準的URL接口,實現(xiàn)了對PubMed數(shù)據(jù)庫的檢索和批量自動下載檢索結(jié)果中的文獻題錄信息。給出的實現(xiàn)流程和關(guān)鍵代碼為進一步文本挖掘和信息分析提供數(shù)據(jù)基礎(chǔ)。