服务热线
178 0020 3020
#任务1 install.packages("RMySQL") library(RMySQL) #创建SQL数据库连接 con <- dbConnect(MySQL(),host="localhost",dbname="rdb",user="root",password="") #localhost代表本机,dbname就是上面创建的rdb,用户名一般是root,password为空 #向数据库引擎提交并同步执行SQL查询;使php写入mysql的编码为utf-8,可以防止phpmyadmin中查看mysql的中文数据出现乱码 dbSendQuery(con,'SET NAMES utf8') #创建数据库连接删除函数,每个任务之前最好先清理所有的连接,调用此函数就可以 killDbConnections <- function () { all_cons <- dbListConnections(MySQL()) #默认的删除链接函数 print(all_cons) for(con in all_cons) + dbDisconnect(con) #对删除链接次数计数并打印 print(paste(length(all_cons), " connections killed.")) }
#任务2 killDbConnections() library(RMySQL) con <- dbConnect(MySQL(),host="localhost",dbname="rdb",user="root",password="") dbSendQuery(con,'SET NAMES utf8') library(httr) totalNum=563 #上一次得到的总数 pageSize=10 #每页数目,获取摘要的时候设置数目过大容易引起网络阻塞 #获得总页数 totalPage=ceiling(totalNum/pageSize) #按题目要求得到总页数 currentPage=1 #当前页数 term='(cell[TA]) AND 2017[DP]' usehistory='Y'#是否使用历史搜索 querykey='' webenv='' postSearchUrl='https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi' while(currentPage<=totalPage){ retstart=(currentPage-1)*pageSize r <- POST(postSearchUrl, body = list(db='pubmed', term=term, retmode='json', retstart=retstart, retmax=pageSize, usehistory=usehistory, rettype='uilist' ) ) stop_for_status(r) #clear http status data=content(r, "parsed", "application/json") esearchresult=data$esearchresult querykey=esearchresult$querykey webenv=esearchresult$webenv idlist =esearchresult$idlist #idlist为搜索结果中pmid的合集,代码用于拼接出Rmysql需要的数据 n = length(idlist) pmid=c() i = 1 while(i<=n){ pmid=c(pmid, as.character(idlist[i][1])) i = i+1 } article=data.frame('pmid'=pmid)#写入article数据表内,不能加append=TRUE dbWriteTable(con,"article",article,append=TRUE) currentPage = currentPage + 1 #当currentPage>totalPage,退出循环 } dbDisconnect(con)#关闭连接,丢弃所有正在等待的工作,并释放资源
#任务3 library(RMySQL) library(xml2) library(httr) killDbConnections() con <- dbConnect(MySQL(),host="localhost",dbname="rdb",user="root",password="") dbSendQuery(con,'SET NAMES utf8') rs <- dbSendQuery(con, "SELECT * FROM article WHERE isdone=0") while (!dbHasCompleted(rs)) { chunk <- dbFetch(rs, 10) pmidStr="" i=1 n=nrow(chunk) #获得总行数 while (i<=n){ pmidStr = paste(pmidStr,chunk[i,3],sep=",") #循环将各个pmid之间用逗号连接起来 i = i + 1 } pmidStr=substr(pmidStr,2,100000) #去掉pmid第一个逗号,从第2位起,到100000位,即到末尾 #下面就是第一次作业里面获取title和abstract postFetchUrl='https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi' r2 <- POST(postFetchUrl, body = list( db='pubmed', id=pmidStr, retmode='xml' ) ) stop_for_status(r2) #clear http status data2=content(r2, "parsed", "application/xml") article=xml_children(data2) #xml_length(article)为里面文章的数量 count=length(article) cnt=1 while(cnt<=count){ title=xml_text(xml_find_first(article[cnt],".//ArticleTitle")) #找到第一个ArticleTitle节点 abstract=xml_text(xml_find_first(article[cnt],".//AbstractText")) pmid=xml_text(xml_find_first(article[cnt],".//PMID")) #更新数据库,首先去掉title和abstract里面的单引号,单引号会导致mysql更新出现问题 title = gsub("'","",title) abstract = gsub("'","",abstract)#得到新的title和abstract(没有单引号) #构建mysql更新语句,R语言的字符串拼接不太好,不能使用"+",也不能使用点"." sql=paste("UPDATE article SET title='",title,"',abstract='",abstract,"',isdone=1"," where pmid='",pmid,"'",sep="")#设置isdone字段用于标记已经处理完的 #执行,并新开通一个mysql连接 con2 <- dbConnect(MySQL(),host="localhost",dbname="rdb",user="root",password="") dbSendQuery(con2,'SET NAMES utf8') dbSendQuery(con2,sql) dbDisconnect(con2) cnt = cnt + 1#延迟1秒运行,因为pubmed接口说明如果1秒内并发超过3次将会被封禁IP Sys.sleep(1) } }
惭愧,几乎全是照搬,通过帮助和搜索才勉强弄懂函数意思,循环语句更是完全不会写。任务3开始用源代码运行,总是不完全,后来用了群里R2-30的建议才全部获得,即把tittle和abstract的类型变为BLOB后(操作-修改),运行任务3的命令,然后再改回来(改完后我忘记abstract之前是啥了,text是可以的)。
但是,不知道为什么程序依旧报错
基础不牢,地动山摇啊
附件